diff --git a/.gn b/.gn
index a9187a74..853c59a 100644
--- a/.gn
+++ b/.gn
@@ -116,6 +116,7 @@
   "//clank/native/framework/BUILD.gn",
 
   "//components/domain_reliability/BUILD.gn",
+  "//components/scheduler/scheduler.gni",
   "//components/webui_generator/generator/wug.gni",
   "//content/browser/browser.gni",
   "//content/child/child.gni",
diff --git a/AUTHORS b/AUTHORS
index 85609f3..6bfd1724 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,7 @@
 Adenilson Cavalcanti <a.cavalcanti@samsung.com>
 Aditya Bhargava <heuristicist@gmail.com>
 Ajay Berwal <ajay.berwal@samsung.com>
+Ajay Berwal <a.berwal@samsung.com>
 Ajith Kumar V <ajith.v@samsung.com>
 Aku Kotkavuo <a.kotkavuo@partner.samsung.com>
 Alex Gabriel <minilogo@gmail.com>
@@ -127,7 +128,7 @@
 Debashish Samantaray <d.samantaray@samsung.com>
 Deepak Dilip Borade <deepak.db@samsung.com>
 Deepak Mittal <deepak.m1@samsung.com>
-Deepak Singla <deepak.sa@samsung.com>
+Deepak Singla <deepak.s@samsung.com>
 Derek Halman <d.halman@gmail.com>
 Devlin Cronin <rdevlin.cronin@gmail.com>
 Diego Ferreiro Val <elfogris@gmail.com>
@@ -574,6 +575,7 @@
 Kenneth Strickland <ken.strickland@gmail.com>
 Olli Syrjälä <olli.syrjala@intel.com>
 Vishal Bhatnagar <vishal.b@samsung.com>
+Yunsik Jang <yunsik.jang@lge.com>
 
 BlackBerry Limited <*@blackberry.com>
 Code Aurora Forum <*@codeaurora.org>
diff --git a/BUILD.gn b/BUILD.gn
index 10ac76f8..ba6b223a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -697,8 +697,6 @@
   group("linux_default_tests") {
     testonly = true
     deps = [
-      # components_browsertests  TODO(GYP)
-
       "//base:base_unittests",  # PASSES (*) 2/25/2015
       "//cc:cc_unittests",  # PASSES 2/25/2015
       "//chrome/test:browser_tests",
@@ -706,6 +704,7 @@
       "//chrome/test:sync_integration_tests",  # Crashes for brettw in GN and GYP.
       "//chrome/test:unit_tests",  # PASSES 2/25/2015
       "//chrome/test/chromedriver:chromedriver_unittests",  # PASSES 2/25/2015
+      "//components:components_browsertests",  # PASSES 4/17/2015
       "//components:components_unittests",  # PASSES 2/27/2015
       "//content/test:content_browsertests",
       "//content/test:content_unittests",  # PASSES 2/25/2015
@@ -737,6 +736,7 @@
       "//third_party/mojo/src/mojo/edk/test:mojo_public_bindings_unittests",  # PASSES 2/25/2015
       "//third_party/mojo/src/mojo/edk/test:mojo_public_environment_unittests",  # PASSES 2/25/2015
       "//third_party/mojo/src/mojo/edk/test:mojo_public_system_unittests",  # PASSES 2/25/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_utility_unittests",
       "//ui/accessibility:accessibility_unittests",  # PASSES 2/25/2015
       "//ui/app_list:app_list_unittests",  # PASSES 2/25/2015
       "//ui/aura:aura_unittests",  # PASSES 2/25/2015
@@ -758,4 +758,73 @@
       deps += [ "//components/nacl:nacl_loader_unittests" ]  # PASSES 3/28/2015
     }
   }
+} else if (is_win) {
+  group("windows_default_tests") {
+    testonly = true
+    deps = [
+      "//ash:ash_unittests",  # FAILS 4/20/2015
+      "//base:base_unittests",  # PASSES 4/17/2015 in 32-bit, some 64-bit failures.
+      "//cc:cc_unittests",  # PASSES 4/17/2015
+      "//chrome_elf:chrome_elf_unittests",  # FAILS 4/20/2015
+      "//chrome/test:browser_tests",
+      "//chrome/test:interactive_ui_tests",
+      "//chrome/test:sync_integration_tests",  # Note: need to turn off incremental linking for debug.
+      "//chrome/test:unit_tests",
+      "//chrome/test/chromedriver:chromedriver_unittests",  # PASSES 4/20/2015
+      "//components:components_browsertests",
+      "//components:components_unittests",  # PASSES 4/17/2015
+      "//courgette:courgette_unittests",  # PASSES 4/20/2015
+      "//content/test:content_browsertests",
+      "//content/test:content_unittests",  # PASSES 4/17/2015
+      "//crypto:crypto_unittests",  # PASSES 4/17/2015
+      "//device:device_unittests",  # PASSES 4/17/2015
+      "//extensions:extensions_browsertests",  # PASSES 4/17/2015
+      "//extensions:extensions_unittests",  # PASSES 4/17/2015
+      "//extensions/shell:app_shell_unittests",  # Doesn't compile in 64-bit
+      "//google_apis/gcm:gcm_unit_tests",  # PASSES 4/17/2015
+      "//google_apis:google_apis_unittests",  # PASSES 4/17/2015
+      "//gpu:gpu_unittests",  # PASSES 4/17/2015
+      "//ipc:ipc_tests",  # PASSES 4/17/2015
+      "//ipc/mojo:ipc_mojo_unittests",  # PASSES 4/17/2015
+      "//jingle:jingle_unittests",  # PASSES 4/17/2015
+      "//media/cast:cast_unittests",  # PASSES 4/17/2015
+      "//media:media_unittests",  # PASSES 4/17/2015
+      "//mojo/common:mojo_common_unittests",  # PASSES 4/17/2015
+      "//net:net_unittests",  # PASSES 4/17/2015
+      "//ppapi:ppapi_unittests",  # PASSES 4/17/2015
+      "//printing:printing_unittests",  # PASSES 4/17/2015
+      "//remoting:remoting_unittests",  # PASSES 4/17/2015
+      "//sandbox/win:sbox_integration_tests",  # PASSES 4/20/2015
+      "//sandbox/win:sbox_unittests",  # PASSES 4/20/2015
+      "//sandbox/win:sbox_validation_tests",  # PASSES 4/20/2015
+      "//skia:skia_unittests",  # PASSES 4/17/2015
+      "//sql:sql_unittests",  # PASSES 4/17/2015
+      "//sync:sync_unit_tests",  # PASSES 4/20/2015
+      "//third_party/cacheinvalidation:cacheinvalidation_unittests",  # PASSES 4/20/2015
+      "//third_party/mojo/src/mojo/edk/system:mojo_system_unittests",  # Seems to hang?
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_bindings_unittests",  # FAILS
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_environment_unittests",  # PASSES 4/20/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_system_unittests",  # PASSES 4/20/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_utility_unittests",  # PASSES 4/20/2015
+      "//ui/accessibility:accessibility_unittests",  # PASSES 4/20/2015
+      "//ui/app_list:app_list_unittests",  # PASSES 4/20/2015
+      "//ui/aura:aura_unittests",  # PASSES 4/17/2015
+      "//ui/base:ui_base_unittests",  # PASSES 4/20/2015
+      "//ui/compositor:compositor_unittests",  # PASSES 4/20/2015
+      "//ui/display:display_unittests",  # PASSES 4/20/2015
+      "//ui/events:events_unittests",  # PASSES 4/20/2015
+      "//ui/gfx:gfx_unittests",  # PASSES (with assertion failure?) 4/20/2015
+      "//ui/message_center:message_center_unittests",  # PASSES 4/20/2015
+      "//ui/touch_selection:ui_touch_selection_unittests",  # PASSES 4/20/2015
+      "//ui/views:views_unittests",  # Same as WM unittests
+      "//ui/wm:wm_unittests",  # CRASHES, looks like something simple missing.
+      "//url:url_unittests",  # PASSES 4/17/2015
+
+      # TODO(GYP) installer_util_unittests
+      # TODO(GYP) app_installer_unittests
+      # TODO(GYP) nacl_integration
+      # TODO(GYP) telemetry_perf_unittests
+      # TODO(GYP) telemetry_unittests
+    ]
+  }
 }
diff --git a/DEPS b/DEPS
index 3561fa6..d79a5e914 100644
--- a/DEPS
+++ b/DEPS
@@ -34,31 +34,31 @@
   'llvm_url': 'http://src.chromium.org/llvm-project',
   'llvm_git': 'https://llvm.googlesource.com',
   'webkit_trunk': 'http://src.chromium.org/blink/trunk',
-  'webkit_revision': 'fc69639936aee079feee18eb2ca09d2875dad003', # from svn revision 194104
+  'webkit_revision': 'ed1c4f3c9dbd0a07e21a4b8b68e39632f474cb20', # from svn revision 194275
   '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': '0816cf21b0f04c1d2cf86b4e3d120a49e4ac8fa6',
+  'libvpx_revision': 'c600ca703b712ac0d2db719970a1fce6de70fcb4',
   'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
-  'skia_revision': '0e95b116fcc7bec1bbdf5f0459ebd464c458f714',
+  'skia_revision': '743be194eda4c1f37c4a5f62f38ef88f09f30649',
   # 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': '95ffd2a05fa5fe78cf3aeb3e41bcc586518ae518',
+  'v8_revision': 'e2ee9248e7c7b2a5a2f919f593290478b5905bb7',
   # 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': '13e7c88b5a9494467259603486f001694ea85721',
+  'swarming_revision': 'f222001cc23c7cdb574bf4cfb447f65c94bc6da3',
   # 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': '8d95b741c56cc05cfba65d1a98496c5623c6b47f',
+  'angle_revision': 'ad0a486b943316caef81084b10fbaa8be70a8956',
   # 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.
@@ -66,7 +66,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': '19ae17578f99621100a26dac3e2c7c3dbf7c7cd1',
+  'pdfium_revision': '97d10aff654e42c1b7c3d2abf33fbcf8d341799e',
   # 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.
@@ -90,11 +90,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling lss
   # and whatever else without interference from each other.
-  'lss_revision': 'e079768b7e3a94dcbe7d338496c0c3bde7151b6e',
+  'lss_revision': '6f97298fe3794e92c8c896a6bc06e0b36e4c3de3',
   # 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': 'b1ee35b27061683b3405e7a67616120c2853067a',
+  'nacl_revision': 'efe1c643770e76a1c4747e4c5bf9338e5a0ef945',
 }
 
 # Only these hosts are allowed for dependencies in this DEPS file.
@@ -108,7 +108,7 @@
 
 deps = {
   'src/breakpad/src':
-   Var('chromium_git') + '/external/google-breakpad/src.git' + '@' + 'ad88d965aa35dabdfe0cded39f72dde9e4a3591e', # from svn revision 1447
+   Var('chromium_git') + '/external/google-breakpad/src.git' + '@' + 'fa5a6b3449dbe77a107a891b96c0e47387302e2e', # from svn revision 1453
 
   'src/buildtools':
    Var('chromium_git') + '/chromium/buildtools.git' + '@' +  Var('buildtools_revision'),
@@ -132,7 +132,7 @@
    Var('chromium_git') + '/crashpad/crashpad.git' + '@' + '1baff4ff92fe1a1ead6b88b5f01633a4f0b6b51c',
 
   'src/third_party/trace-viewer':
-   Var('chromium_git') + '/external/trace-viewer.git' + '@' + '337d7911f38529a2a42c5e6c13240076c3fc7d17',
+   Var('chromium_git') + '/external/trace-viewer.git' + '@' + '98cca163de50a003a33712e1bc0b64a400bd3915',
 
   'src/third_party/WebKit':
    Var('chromium_git') + '/chromium/blink.git' + '@' +  Var('webkit_revision'),
@@ -210,7 +210,7 @@
    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '104f872faf2cd809cdada885a1e39be85e5b3316',
 
   'src/third_party/libjingle/source/talk':
-    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'b0e40f3acddbc205818c8f0109095053e1626fe4', # commit position 9029
+    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '58bf070857c078248d300f2c4bc7daabe0dd43ec',
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215
@@ -234,7 +234,7 @@
    Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '647d7226458ac2abc675eeeb2395151e660dee4d', # commit position 9030
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '0f07171706abb5174bdf002eee928b4852fc6c22',
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -263,7 +263,7 @@
    Var('chromium_git') + '/chromium/tools/deps2git.git' + '@' + 'f04828eb0b5acd3e7ad983c024870f17f17b06d9',
 
   'src/third_party/webpagereplay':
-   Var('chromium_git') + '/external/github.com/chromium/web-page-replay.git' + '@' + '13560f74b4f40f12108de7fc43f20b873471d48d',
+   Var('chromium_git') + '/external/github.com/chromium/web-page-replay.git' + '@' + '4e4d540a18c099e2ad805696072f95815f313c0e',
 
   'src/third_party/pywebsocket/src':
     Var('chromium_git') + '/external/pywebsocket/src.git' + '@' + 'cb349e87ddb30ff8d1fa1a89be39cec901f4a29c',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 99c02609..71360cb 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -251,13 +251,16 @@
       ),
     ),
     (
-      'MessageLoopProxy',
+      '\<MessageLoopProxy\>',
       (
         'MessageLoopProxy is deprecated. ',
         'Please use SingleThreadTaskRunner or ThreadTaskRunnerHandle instead.'
       ),
       True,
-      (),
+      (
+        # Internal message_loop related code may still use it.
+        r'^base[\\\/]message_loop[\\\/].*',
+      ),
     ),
 )
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 1aa2750..7f26da13 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -629,7 +629,7 @@
     },
     'scheduler': {
       'filepath': 'cc/scheduler'\
-                  '|content/child/scheduler'\
+                  '|components/scheduler'\
                   '|content/renderer/scheduler'
     },
     'search': {
diff --git a/android_webview/DEPS b/android_webview/DEPS
index 2803eaf..319db9e 100644
--- a/android_webview/DEPS
+++ b/android_webview/DEPS
@@ -8,6 +8,7 @@
   "-android_webview/lib",
 
   "+components/data_reduction_proxy",
+  "+components/devtools_discovery",
   "+content/public/common",
   "+crypto",
   "+gpu",
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
index fb4c3fff..9fbaf73 100644
--- a/android_webview/android_webview.gyp
+++ b/android_webview/android_webview.gyp
@@ -163,6 +163,7 @@
         '../components/components.gyp:cdm_renderer',
         '../components/components.gyp:crash_component',
         '../components/components.gyp:data_reduction_proxy_core_browser',
+        '../components/components.gyp:devtools_discovery',
         '../components/components.gyp:navigation_interception',
         '../components/components.gyp:printing_common',
         '../components/components.gyp:printing_renderer',
@@ -206,6 +207,8 @@
         'browser/aw_contents_io_thread_client.h',
         'browser/aw_cookie_access_policy.cc',
         'browser/aw_cookie_access_policy.h',
+        'browser/aw_dev_tools_discovery_provider.cc',
+        'browser/aw_dev_tools_discovery_provider.h',
         'browser/aw_dev_tools_manager_delegate.cc',
         'browser/aw_dev_tools_manager_delegate.h',
         'browser/aw_download_manager_delegate.cc',
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index e108895..1623736 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -12,6 +12,7 @@
 #include "android_webview/browser/jni_dependency_factory.h"
 #include "android_webview/browser/net/aw_url_request_context_getter.h"
 #include "android_webview/browser/net/init_native_callback.h"
+#include "android_webview/common/aw_content_client.h"
 #include "base/base_paths_android.h"
 #include "base/bind.h"
 #include "base/path_service.h"
@@ -161,7 +162,8 @@
           url_request_context_getter_->GetNetLog(),
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
-          false /* enable_quic */));
+          false /* enable_quic */,
+          GetUserAgent()));
   data_reduction_proxy_settings_.reset(
       new data_reduction_proxy::DataReductionProxySettings());
   data_reduction_proxy_service_.reset(
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
index d894e7e..be793ee 100644
--- a/android_webview/browser/aw_browser_main_parts.cc
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -5,6 +5,7 @@
 #include "android_webview/browser/aw_browser_main_parts.h"
 
 #include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_dev_tools_discovery_provider.h"
 #include "android_webview/browser/aw_result_codes.h"
 #include "android_webview/native/public/aw_assets.h"
 #include "base/android/build_info.h"
@@ -12,6 +13,7 @@
 #include "base/android/memory_pressure_listener_android.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
@@ -92,6 +94,12 @@
 
 void AwBrowserMainParts::PreMainMessageLoopRun() {
   browser_context_->PreMainMessageLoopRun();
+
+  devtools_discovery::DevToolsDiscoveryManager* discovery_manager =
+      devtools_discovery::DevToolsDiscoveryManager::GetInstance();
+  discovery_manager->AddProvider(make_scoped_ptr(
+      new AwDevToolsDiscoveryProvider()));
+
   // This is needed for WebView Classic backwards compatibility
   // See crbug.com/298495
   content::SetMaxURLChars(20 * 1024 * 1024);
diff --git a/android_webview/browser/aw_dev_tools_discovery_provider.cc b/android_webview/browser/aw_dev_tools_discovery_provider.cc
new file mode 100644
index 0000000..c38189d
--- /dev/null
+++ b/android_webview/browser/aw_dev_tools_discovery_provider.cc
@@ -0,0 +1,79 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_dev_tools_discovery_provider.h"
+
+#include "android_webview/browser/browser_view_renderer.h"
+#include "base/json/json_writer.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/devtools_discovery/basic_target_descriptor.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/web_contents.h"
+
+using content::DevToolsAgentHost;
+using content::WebContents;
+
+namespace {
+
+std::string GetViewDescription(WebContents* web_contents) {
+  android_webview::BrowserViewRenderer* bvr =
+      android_webview::BrowserViewRenderer::FromWebContents(web_contents);
+  if (!bvr) return "";
+  base::DictionaryValue description;
+  description.SetBoolean("attached", bvr->attached_to_window());
+  description.SetBoolean("visible", bvr->IsVisible());
+  gfx::Rect screen_rect = bvr->GetScreenRect();
+  description.SetInteger("screenX", screen_rect.x());
+  description.SetInteger("screenY", screen_rect.y());
+  description.SetBoolean("empty", screen_rect.size().IsEmpty());
+  if (!screen_rect.size().IsEmpty()) {
+    description.SetInteger("width", screen_rect.width());
+    description.SetInteger("height", screen_rect.height());
+  }
+  std::string json;
+  base::JSONWriter::Write(&description, &json);
+  return json;
+}
+
+class TargetDescriptor : public devtools_discovery::BasicTargetDescriptor {
+ public:
+  explicit TargetDescriptor(scoped_refptr<DevToolsAgentHost> agent_host);
+
+  // devtools_discovery::BasicTargetDescriptor overrides.
+  std::string GetDescription() const override { return description_; }
+
+ private:
+  std::string description_;
+};
+
+TargetDescriptor::TargetDescriptor(scoped_refptr<DevToolsAgentHost> agent_host)
+    : BasicTargetDescriptor(agent_host) {
+  if (WebContents* web_contents = agent_host->GetWebContents())
+    description_ = GetViewDescription(web_contents);
+}
+
+}  // namespace
+
+namespace android_webview {
+
+AwDevToolsDiscoveryProvider::AwDevToolsDiscoveryProvider() {
+}
+
+AwDevToolsDiscoveryProvider::~AwDevToolsDiscoveryProvider() {
+}
+
+devtools_discovery::DevToolsTargetDescriptor::List
+AwDevToolsDiscoveryProvider::GetDescriptors() {
+  DevToolsAgentHost::List agent_hosts = DevToolsAgentHost::GetOrCreateAll();
+  devtools_discovery::DevToolsTargetDescriptor::List result;
+  result.reserve(agent_hosts.size());
+  for (const auto& agent_host : agent_hosts)
+    result.push_back(new TargetDescriptor(agent_host));
+  return result;
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_dev_tools_discovery_provider.h b/android_webview/browser/aw_dev_tools_discovery_provider.h
new file mode 100644
index 0000000..81fdffe
--- /dev/null
+++ b/android_webview/browser/aw_dev_tools_discovery_provider.h
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_DEV_TOOLS_DISCOVERY_PROVIDER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_DEV_TOOLS_DISCOVERY_PROVIDER_H_
+
+#include "components/devtools_discovery/devtools_discovery_manager.h"
+
+namespace android_webview {
+
+class AwDevToolsDiscoveryProvider :
+    public devtools_discovery::DevToolsDiscoveryManager::Provider {
+ public:
+  AwDevToolsDiscoveryProvider();
+  ~AwDevToolsDiscoveryProvider() override;
+
+  // devtools_discovery::DevToolsDiscoveryManager::Provider implementation.
+  devtools_discovery::DevToolsTargetDescriptor::List GetDescriptors() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AwDevToolsDiscoveryProvider);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_DEV_TOOLS_DISCOVERY_PROVIDER_H_
diff --git a/android_webview/browser/aw_dev_tools_manager_delegate.cc b/android_webview/browser/aw_dev_tools_manager_delegate.cc
index 1b3517d..d46e402 100644
--- a/android_webview/browser/aw_dev_tools_manager_delegate.cc
+++ b/android_webview/browser/aw_dev_tools_manager_delegate.cc
@@ -4,94 +4,8 @@
 
 #include "android_webview/browser/aw_dev_tools_manager_delegate.h"
 
-#include "android_webview/browser/browser_view_renderer.h"
-#include "base/bind.h"
-#include "base/json/json_writer.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "content/public/browser/devtools_agent_host.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
 #include "content/public/browser/devtools_target.h"
-#include "content/public/browser/web_contents.h"
-
-using content::DevToolsAgentHost;
-using content::RenderViewHost;
-using content::WebContents;
-
-namespace {
-
-const char kTargetTypePage[] = "page";
-const char kTargetTypeServiceWorker[] = "service_worker";
-const char kTargetTypeOther[] = "other";
-
-std::string GetViewDescription(WebContents* web_contents);
-
-class Target : public content::DevToolsTarget {
- public:
-  explicit Target(scoped_refptr<DevToolsAgentHost> agent_host);
-
-  std::string GetId() const override { return agent_host_->GetId(); }
-  std::string GetParentId() const override { return std::string(); }
-  std::string GetType() const override {
-    switch (agent_host_->GetType()) {
-      case DevToolsAgentHost::TYPE_WEB_CONTENTS:
-        return kTargetTypePage;
-      case DevToolsAgentHost::TYPE_SERVICE_WORKER:
-        return kTargetTypeServiceWorker;
-      default:
-        break;
-    }
-    return kTargetTypeOther;
-  }
-  std::string GetTitle() const override { return agent_host_->GetTitle(); }
-  std::string GetDescription() const override { return description_; }
-  GURL GetURL() const override { return agent_host_->GetURL(); }
-  GURL GetFaviconURL() const override { return GURL(); }
-  base::TimeTicks GetLastActivityTime() const override {
-    return last_activity_time_;
-  }
-  bool IsAttached() const override { return agent_host_->IsAttached(); }
-  scoped_refptr<DevToolsAgentHost> GetAgentHost() const override {
-    return agent_host_;
-  }
-  bool Activate() const override { return agent_host_->Activate(); }
-  bool Close() const override { return agent_host_->Close(); }
-
- private:
-  scoped_refptr<DevToolsAgentHost> agent_host_;
-  std::string description_;
-  base::TimeTicks last_activity_time_;
-};
-
-Target::Target(scoped_refptr<DevToolsAgentHost> agent_host)
-    : agent_host_(agent_host) {
-  if (WebContents* web_contents = agent_host->GetWebContents()) {
-    description_ = GetViewDescription(web_contents);
-    last_activity_time_ = web_contents->GetLastActiveTime();
-  }
-}
-
-std::string GetViewDescription(WebContents* web_contents) {
-  android_webview::BrowserViewRenderer* bvr =
-      android_webview::BrowserViewRenderer::FromWebContents(web_contents);
-  if (!bvr) return "";
-  base::DictionaryValue description;
-  description.SetBoolean("attached", bvr->attached_to_window());
-  description.SetBoolean("visible", bvr->IsVisible());
-  gfx::Rect screen_rect = bvr->GetScreenRect();
-  description.SetInteger("screenX", screen_rect.x());
-  description.SetInteger("screenY", screen_rect.y());
-  description.SetBoolean("empty", screen_rect.size().IsEmpty());
-  if (!screen_rect.size().IsEmpty()) {
-    description.SetInteger("width", screen_rect.width());
-    description.SetInteger("height", screen_rect.height());
-  }
-  std::string json;
-  base::JSONWriter::Write(&description, &json);
-  return json;
-}
-
-}  // namespace
 
 namespace android_webview {
 
@@ -109,11 +23,10 @@
 
 void AwDevToolsManagerDelegate::EnumerateTargets(TargetCallback callback) {
   TargetList targets;
-  DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
-  for (DevToolsAgentHost::List::iterator it = agents.begin();
-      it != agents.end(); ++it) {
-    targets.push_back(new Target(*it));
-  }
+  devtools_discovery::DevToolsDiscoveryManager* discovery_manager =
+      devtools_discovery::DevToolsDiscoveryManager::GetInstance();
+  for (const auto& descriptor : discovery_manager->GetDescriptors())
+    targets.push_back(descriptor);
   callback.Run(targets);
 }
 
diff --git a/android_webview/browser/aw_dev_tools_manager_delegate.h b/android_webview/browser/aw_dev_tools_manager_delegate.h
index 68f22851..52b7c85f 100644
--- a/android_webview/browser/aw_dev_tools_manager_delegate.h
+++ b/android_webview/browser/aw_dev_tools_manager_delegate.h
@@ -10,6 +10,8 @@
 
 namespace android_webview {
 
+// TODO(dgozman): remove this class after componentization of devtools_discovery
+// is finished.
 class AwDevToolsManagerDelegate : public content::DevToolsManagerDelegate {
  public:
   AwDevToolsManagerDelegate();
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.cc b/android_webview/browser/aw_ssl_host_state_delegate.cc
index 59d717fb..1da4747 100644
--- a/android_webview/browser/aw_ssl_host_state_delegate.cc
+++ b/android_webview/browser/aw_ssl_host_state_delegate.cc
@@ -86,4 +86,15 @@
              : SSLHostStateDelegate::DENIED;
 }
 
+void AwSSLHostStateDelegate::RevokeUserAllowExceptions(
+    const std::string& host) {
+  cert_policy_for_host_.erase(host);
+}
+
+bool AwSSLHostStateDelegate::HasAllowException(const std::string& host) const {
+  auto policy_iterator = cert_policy_for_host_.find(host);
+  return policy_iterator != cert_policy_for_host_.end() &&
+         policy_iterator->second.HasAllowException();
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.h b/android_webview/browser/aw_ssl_host_state_delegate.h
index bc3e1a8..b5a34f4a 100644
--- a/android_webview/browser/aw_ssl_host_state_delegate.h
+++ b/android_webview/browser/aw_ssl_host_state_delegate.h
@@ -30,6 +30,10 @@
   // remember the user's choice.
   void Allow(const net::X509Certificate& cert, net::CertStatus error);
 
+  // Returns true if and only if there exists a user allow exception for some
+  // certificate.
+  bool HasAllowException() const { return allowed_.size() > 0; }
+
  private:
   // The set of fingerprints of allowed certificates.
   std::map<net::SHA256HashValue, net::CertStatus, net::SHA256HashValueLessThan>
@@ -65,6 +69,16 @@
   bool DidHostRunInsecureContent(const std::string& host,
                                  int pid) const override;
 
+  // Revokes all SSL certificate error allow exceptions made by the user for
+  // |host|.
+  void RevokeUserAllowExceptions(const std::string& host) override;
+
+  // Returns whether the user has allowed a certificate error exception for
+  // |host|. This does not mean that *all* certificate errors are allowed, just
+  // that there exists an exception. To see if a particular certificate and
+  // error combination exception is allowed, use QueryPolicy().
+  bool HasAllowException(const std::string& host) const override;
+
  private:
   // Certificate policies for each host.
   std::map<std::string, internal::CertPolicy> cert_policy_for_host_;
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
index 041ffe2..d608ac9 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -125,7 +125,7 @@
 
         ThreadUtils.setWillOverrideUiThread();
         // Load chromium library.
-        AwBrowserProcess.loadLibrary();
+        AwBrowserProcess.loadLibrary(getWrappedCurrentApplicationContext());
 
         final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo();
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
index 96d9fb0..c1529e6 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -30,8 +30,8 @@
      * to run webview in this process. Does not create threads; safe to call from zygote.
      * Note: it is up to the caller to ensure this is only called once.
      */
-    public static void loadLibrary() {
-        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
+    public static void loadLibrary(Context context) {
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
         try {
             LibraryLoader libraryLoader = LibraryLoader.get(LibraryProcessType.PROCESS_WEBVIEW);
             libraryLoader.loadNow();
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java
index a397d79..0f4e866a 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java
@@ -195,11 +195,6 @@
     }
 
     @Override
-    public boolean isJavascriptEnabled() {
-        return mAwSettings != null && mAwSettings.getJavaScriptEnabled();
-    }
-
-    @Override
     public boolean isExternalFlingActive() {
         return mAwContents.isFlingActive();
     }
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 6b061fed..b7603afd 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -2245,14 +2245,14 @@
      * @see android.webkit.WebView#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
      */
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        if (!isDestroyed()) mContentViewCore.onInitializeAccessibilityNodeInfo(info);
+        // TODO(boliu): remove this method.
     }
 
     /**
      * @see android.webkit.WebView#onInitializeAccessibilityEvent(AccessibilityEvent)
      */
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        if (!isDestroyed()) mContentViewCore.onInitializeAccessibilityEvent(event);
+     // TODO(boliu): remove this method.
     }
 
     public boolean supportsAccessibilityAction(int action) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
index 9a4569e..333e9a6 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.android_webview.test;
 
+import android.content.Context;
 import android.os.Build;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -71,11 +72,11 @@
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testLegacyHttpCacheDirIsRemovedOnStartup() throws Exception {
+        Context targetContext = getInstrumentation().getTargetContext();
         PathUtils.setPrivateDataDirectorySuffix(
-                AwBrowserProcess.PRIVATE_DATA_DIRECTORY_SUFFIX,
-                getInstrumentation().getTargetContext());
+                AwBrowserProcess.PRIVATE_DATA_DIRECTORY_SUFFIX, targetContext);
         File webViewLegacyCacheDir = new File(
-                PathUtils.getDataDirectory(getInstrumentation().getTargetContext()), "Cache");
+                PathUtils.getDataDirectory(targetContext), "Cache");
         if (!webViewLegacyCacheDir.isDirectory()) {
             assertTrue(webViewLegacyCacheDir.mkdir());
             assertTrue(webViewLegacyCacheDir.isDirectory());
@@ -84,7 +85,7 @@
         assertTrue(dummyCacheFile.exists());
 
         // Set up JNI bindings.
-        AwBrowserProcess.loadLibrary();
+        AwBrowserProcess.loadLibrary(targetContext);
         // No delay before removing the legacy cache files.
         AwContentsStatics.setLegacyCacheRemovalDelayForTest(0);
 
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
index 638d1d9..5e1a0701 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
@@ -39,7 +39,7 @@
             Log.e(TAG, "Java debugger connected. Resuming execution.");
         }
 
-        AwBrowserProcess.loadLibrary();
+        AwBrowserProcess.loadLibrary(this);
 
         if (CommandLine.getInstance().hasSwitch(AwShellSwitches.ENABLE_ATRACE)) {
             Log.e(TAG, "Enabling Android trace.");
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
index c95a4eaf..1373a2b9 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
@@ -15,8 +15,6 @@
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
@@ -412,20 +410,6 @@
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(AwContents.class.getName());
-        mAwContents.onInitializeAccessibilityNodeInfo(info);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setClassName(AwContents.class.getName());
-        mAwContents.onInitializeAccessibilityEvent(event);
-    }
-
-    @Override
     public boolean performAccessibilityAction(int action, Bundle arguments) {
         return mAwContents.performAccessibilityAction(action, arguments);
     }
diff --git a/ash/ash_chromeos_strings.grdp b/ash/ash_chromeos_strings.grdp
index f14825d3..ab48212f 100644
--- a/ash/ash_chromeos_strings.grdp
+++ b/ash/ash_chromeos_strings.grdp
@@ -337,11 +337,11 @@
   <message name="IDS_ASH_STATUS_TRAY_NOTIFICATION_SESSION_LENGTH_LIMIT" desc="Notification shown to inform the user that the session length is limited.">
     Session ends in <ph name="session_time_remaining">$1<ex>4 minutes 23 seconds</ex></ph>. You will be signed out.
   </message>
-  <message name="IDS_ASH_STATUS_TRAY_ROTATION_LOCK_AUTO" desc="The text shown in the tray menu when rotation is set to auto.">
-    Rotation on (Tap here to change)
+  <message name="IDS_ASH_STATUS_TRAY_ROTATION_LOCK_AUTO" desc="The text shown in the tray menu when rotation is set to auto and the user can enable the rotation lock by tapping.">
+    Enable rotation lock
   </message>
-  <message name="IDS_ASH_STATUS_TRAY_ROTATION_LOCK_LOCKED" desc="The text shown in the tray menu when rotation is set to locked.">
-    Rotation locked (Tap here to change)
+  <message name="IDS_ASH_STATUS_TRAY_ROTATION_LOCK_LOCKED" desc="The text shown in the tray menu when rotation is set to locked and tapping will disable the lock.">
+    Disable rotation lock
   </message>
   <message name="IDS_ASH_STATUS_TRAY_KEYBOARD_DISABLED" desc="The text shown in the tray menu when the virtual keyboard is disabled.">
     On-screen keyboard disabled
@@ -412,4 +412,10 @@
   <message name="IDS_ASH_LOGOUT_CONFIRMATION_BUTTON" desc="The text for okay button of the logout confirmation dialog.">
     Sign out now
   </message>
+  <message name="IDS_ASH_STATUS_TRAY_NEW_LOGIN_UI_ENABLED" desc="The text shown in the tray menu when the WebView-based sign-in is enabled.">
+    New login UI is ON
+  </message>
+  <message name="IDS_ASH_STATUS_TRAY_NEW_LOGIN_UI_DISABLED" desc="The text shown in the tray menu when the WebView-based sign-in is disabled.">
+    New login UI is OFF
+  </message>
 </grit-part>
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 0623d3b1..40aba02 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -47,15 +47,6 @@
 ASH_EXPORT extern const char kForceAshToDesktop[];
 #endif
 
-// Returns true if items can be dragged off the shelf to unpin.
-ASH_EXPORT bool UseDragOffShelf();
-
-#if defined(OS_CHROMEOS)
-// Returns true if a notification should appear when a low-power USB charger
-// is connected.
-ASH_EXPORT bool UseUsbChargerNotification();
-#endif
-
 }  // namespace switches
 }  // namespace ash
 
diff --git a/ash/content/display/screen_orientation_controller_chromeos.cc b/ash/content/display/screen_orientation_controller_chromeos.cc
index dbd4465..ac15726 100644
--- a/ash/content/display/screen_orientation_controller_chromeos.cc
+++ b/ash/content/display/screen_orientation_controller_chromeos.cc
@@ -37,13 +37,12 @@
 const float kMinimumAccelerationScreenRotation = 4.2f;
 
 blink::WebScreenOrientationLockType GetDisplayNaturalOrientation() {
-  ash::DisplayManager* display_manager =
-      ash::Shell::GetInstance()->display_manager();
-  if (!display_manager->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return blink::WebScreenOrientationLockLandscape;
 
   ash::DisplayInfo info =
-      display_manager->GetDisplayInfo(gfx::Display::InternalDisplayId());
+      ash::Shell::GetInstance()->display_manager()->GetDisplayInfo(
+          gfx::Display::InternalDisplayId());
   gfx::Size size = info.size_in_pixel();
   switch (info.rotation()) {
     case gfx::Display::ROTATE_0:
@@ -102,19 +101,17 @@
     rotation_locked_orientation_ = blink::WebScreenOrientationLockAny;
   FOR_EACH_OBSERVER(Observer, observers_,
                     OnRotationLockChanged(rotation_locked_));
-  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  if (!display_manager->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return;
   base::AutoReset<bool> auto_ignore_display_configuration_updates(
       &ignore_display_configuration_updates_, true);
-  display_manager->RegisterDisplayRotationProperties(rotation_locked_,
-                                                     current_rotation_);
+  Shell::GetInstance()->display_manager()->RegisterDisplayRotationProperties(
+      rotation_locked_, current_rotation_);
 }
 
 void ScreenOrientationController::SetDisplayRotation(
     gfx::Display::Rotation rotation) {
-  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  if (!display_manager->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return;
   current_rotation_ = rotation;
   base::AutoReset<bool> auto_ignore_display_configuration_updates(
@@ -196,9 +193,9 @@
 void ScreenOrientationController::OnDisplayConfigurationChanged() {
   if (ignore_display_configuration_updates_)
     return;
-  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  if (!display_manager->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return;
+  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   gfx::Display::Rotation user_rotation =
       display_manager->GetDisplayInfo(gfx::Display::InternalDisplayId())
           .rotation();
@@ -212,13 +209,14 @@
 }
 
 void ScreenOrientationController::OnMaximizeModeStarted() {
-  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   // Do not exit early, as the internal display can be determined after Maximize
   // Mode has started. (chrome-os-partner:38796)
   // Always start observing.
-  if (display_manager->HasInternalDisplay()) {
+  if (gfx::Display::HasInternalDisplay()) {
     current_rotation_ = user_rotation_ =
-        display_manager->GetDisplayInfo(gfx::Display::InternalDisplayId())
+        Shell::GetInstance()
+            ->display_manager()
+            ->GetDisplayInfo(gfx::Display::InternalDisplayId())
             .rotation();
   }
   if (!rotation_locked_)
@@ -294,10 +292,10 @@
 
 void ScreenOrientationController::LockToRotationMatchingOrientation(
     blink::WebScreenOrientationLockType lock_orientation) {
-  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  if (!display_manager->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return;
 
+  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   gfx::Display::Rotation rotation =
       display_manager->GetDisplayInfo(gfx::Display::InternalDisplayId())
           .rotation();
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index 166a76f..0068e95c 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -340,7 +340,6 @@
       RootWindowController::CreateForSecondaryDisplay(ash_host);
     }
   }
-  UpdateHostWindowNames();
 
   FOR_EACH_OBSERVER(Observer, observers_, OnDisplaysInitialized());
 }
@@ -436,10 +435,9 @@
   Shell* shell = Shell::GetInstance();
   DisplayConfiguratorAnimation* animation =
       shell->display_configurator_animation();
-  animation->StartFadeOutAnimation(
-      base::Bind(&DisplayController::SetMirrorModeAfterAnimation,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 !display_manager->IsMirrored()));
+  animation->StartFadeOutAnimation(base::Bind(
+      &DisplayController::SetMirrorModeAfterAnimation,
+      weak_ptr_factory_.GetWeakPtr(), !display_manager->IsInMirrorMode()));
 #endif
 }
 
@@ -481,10 +479,10 @@
     const gfx::Display& new_primary_display) {
   DisplayManager* display_manager = GetDisplayManager();
   DCHECK(new_primary_display.is_valid());
-  DCHECK(display_manager->IsActiveDisplay(new_primary_display));
+  DCHECK(display_manager->GetDisplayForId(new_primary_display.id()).is_valid());
 
   if (!new_primary_display.is_valid() ||
-      !display_manager->IsActiveDisplay(new_primary_display)) {
+      !display_manager->GetDisplayForId(new_primary_display.id()).is_valid()) {
     LOG(ERROR) << "Invalid or non-existent display is requested:"
                << new_primary_display.ToString();
     return;
@@ -781,7 +779,7 @@
   DisplayLayoutStore* layout_store = display_manager->layout_store();
   if (display_manager->num_connected_displays() > 1) {
     DisplayIdPair pair = display_manager->GetCurrentDisplayIdPair();
-    layout_store->UpdateMirrorStatus(pair, display_manager->IsMirrored());
+    layout_store->UpdateMirrorStatus(pair, display_manager->IsInMirrorMode());
     DisplayLayout layout = layout_store->GetRegisteredDisplayLayout(pair);
 
     if (Shell::GetScreen()->GetNumDisplays() > 1 ) {
@@ -798,7 +796,6 @@
     }
   }
   FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged());
-  UpdateHostWindowNames();
   UpdateMouseLocationAfterDisplayChange();
 }
 
@@ -847,21 +844,4 @@
   GetDisplayManager()->SetMirrorMode(mirror);
 }
 
-void DisplayController::UpdateHostWindowNames() {
-#if defined(USE_X11)
-  // crbug.com/120229 - set the window title for the primary dislpay
-  // to "aura_root_0" so gtalk can find the primary root window to broadcast.
-  // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting.
-  aura::Window* primary = Shell::GetPrimaryRootWindow();
-  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-  for (size_t i = 0; i < root_windows.size(); ++i) {
-    std::string name =
-        root_windows[i] == primary ? "aura_root_0" : "aura_root_x";
-    gfx::AcceleratedWidget xwindow =
-        root_windows[i]->GetHost()->GetAcceleratedWidget();
-    XStoreName(gfx::GetXDisplay(), xwindow, name.c_str());
-  }
-#endif
-}
-
 }  // namespace ash
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h
index e795d77..3dc8189 100644
--- a/ash/display/display_controller.h
+++ b/ash/display/display_controller.h
@@ -174,8 +174,6 @@
 
   void SetMirrorModeAfterAnimation(bool mirror);
 
-  void UpdateHostWindowNames();
-
   class DisplayChangeLimiter {
    public:
     DisplayChangeLimiter();
diff --git a/ash/display/display_controller_unittest.cc b/ash/display/display_controller_unittest.cc
index 6945fac2..6b9e056 100644
--- a/ash/display/display_controller_unittest.cc
+++ b/ash/display/display_controller_unittest.cc
@@ -36,12 +36,6 @@
 #include "ui/wm/public/activation_change_observer.h"
 #include "ui/wm/public/activation_client.h"
 
-#if defined(USE_X11)
-#include <X11/Xlib.h>
-#include "ui/gfx/x/x11_types.h"
-#undef RootWindow
-#endif
-
 namespace ash {
 namespace {
 
@@ -361,23 +355,6 @@
       GetEffectiveUIScale();
 }
 
-#if defined(USE_X11)
-void GetPrimaryAndSeconary(aura::Window** primary,
-                           aura::Window** secondary) {
-  *primary = Shell::GetPrimaryRootWindow();
-  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-  *secondary = root_windows[0] == *primary ? root_windows[1] : root_windows[0];
-}
-
-std::string GetXWindowName(aura::WindowTreeHost* host) {
-  char* name = NULL;
-  XFetchName(gfx::GetXDisplay(), host->GetAcceleratedWidget(), &name);
-  std::string ret(name);
-  XFree(name);
-  return ret;
-}
-#endif
-
 class TestMouseWatcherListener : public views::MouseWatcherListener {
  public:
   TestMouseWatcherListener() {}
@@ -1307,32 +1284,6 @@
   EXPECT_EQ(20, Shell::GetScreen()->GetPrimaryDisplay().id());
 }
 
-#if defined(USE_X11)
-TEST_F(DisplayControllerTest, XWidowNameForRootWindow) {
-  EXPECT_EQ("aura_root_0", GetXWindowName(
-      Shell::GetPrimaryRootWindow()->GetHost()));
-
-  // Multiple display.
-  UpdateDisplay("200x200,300x300");
-  aura::Window* primary, *secondary;
-  GetPrimaryAndSeconary(&primary, &secondary);
-  EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
-  EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
-
-  // Swap primary.
-  primary = secondary = NULL;
-  Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
-  GetPrimaryAndSeconary(&primary, &secondary);
-  EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
-  EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
-
-  // Switching back to single display.
-  UpdateDisplay("300x400");
-  EXPECT_EQ("aura_root_0", GetXWindowName(
-      Shell::GetPrimaryRootWindow()->GetHost()));
-}
-#endif
-
 TEST_F(DisplayControllerTest, UpdateMouseLocationAfterDisplayChange) {
   if (!SupportsMultipleDisplays())
     return;
diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc
index b731ded..d40917ac 100644
--- a/ash/display/display_manager.cc
+++ b/ash/display/display_manager.cc
@@ -20,6 +20,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
+#include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
@@ -103,6 +104,10 @@
   }
 }
 
+bool IsInternalDisplayId(int64 id) {
+  return gfx::Display::InternalDisplayId() == id;
+}
+
 }  // namespace
 
 using std::string;
@@ -110,19 +115,17 @@
 
 DisplayManager::DisplayManager()
     : delegate_(NULL),
-      screen_ash_(new ScreenAsh),
-      screen_(screen_ash_.get()),
+      screen_(new ScreenAsh),
       layout_store_(new DisplayLayoutStore),
       first_display_id_(gfx::Display::kInvalidDisplayID),
       num_connected_displays_(0),
       force_bounds_changed_(false),
       change_display_upon_host_resize_(false),
       second_display_mode_(EXTENDED),
-      mirrored_display_id_(gfx::Display::kInvalidDisplayID),
+      mirroring_display_id_(gfx::Display::kInvalidDisplayID),
       registered_internal_display_rotation_lock_(false),
       registered_internal_display_rotation_(gfx::Display::ROTATE_0),
       weak_ptr_factory_(this) {
-
 #if defined(OS_CHROMEOS)
   // Enable only on the device so that DisplayManagerFontTest passes.
   if (base::SysInfo::IsRunningOnChromeOS())
@@ -130,16 +133,14 @@
 
   change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS();
 #endif
-  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE,
-                                 screen_ash_.get());
+  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get());
   gfx::Screen* current_native =
       gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE);
   // If there is no native, or the native was for shutdown,
   // use ash's screen.
   if (!current_native ||
       current_native == screen_for_shutdown) {
-    gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
-                                   screen_ash_.get());
+    gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
   }
 }
 
@@ -187,7 +188,7 @@
   // internal display may have bigger scale factor in case the external display
   // is an 4K display.
   float largest_device_scale_factor = 1.0f;
-  for (const gfx::Display& display : displays_) {
+  for (const gfx::Display& display : active_display_list_) {
     const ash::DisplayInfo& info = display_info_[display.id()];
     largest_device_scale_factor = std::max(
         largest_device_scale_factor, info.GetEffectiveDeviceScaleFactor());
@@ -196,23 +197,6 @@
 #endif  // OS_CHROMEOS
 }
 
-bool DisplayManager::IsActiveDisplay(const gfx::Display& display) const {
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    if ((*iter).id() == display.id())
-      return true;
-  }
-  return false;
-}
-
-bool DisplayManager::HasInternalDisplay() const {
-  return gfx::Display::InternalDisplayId() != gfx::Display::kInvalidDisplayID;
-}
-
-bool DisplayManager::IsInternalDisplayId(int64 id) const {
-  return gfx::Display::InternalDisplayId() == id;
-}
-
 DisplayLayout DisplayManager::GetCurrentDisplayLayout() {
   DCHECK_LE(2U, num_connected_displays());
   // Invert if the primary was swapped.
@@ -228,27 +212,27 @@
   // On release build, just fallback to default instead of blowing up.
   DisplayLayout layout =
       layout_store_->default_display_layout();
-  layout.primary_id = displays_[0].id();
+  layout.primary_id = active_display_list_[0].id();
   return layout;
 }
 
 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const {
-  if (IsMirrored()) {
+  if (IsInMirrorMode()) {
     if (software_mirroring_enabled()) {
       CHECK_EQ(2u, num_connected_displays());
       // This comment is to make it easy to distinguish the crash
       // between two checks.
-      CHECK_EQ(1u, displays_.size());
+      CHECK_EQ(1u, active_display_list_.size());
     }
-    return std::make_pair(displays_[0].id(), mirrored_display_id_);
+    return std::make_pair(active_display_list_[0].id(), mirroring_display_id_);
   } else {
-    CHECK_LE(2u, displays_.size());
-    int64 id_at_zero = displays_[0].id();
+    CHECK_LE(2u, active_display_list_.size());
+    int64 id_at_zero = active_display_list_[0].id();
     if (id_at_zero == gfx::Display::InternalDisplayId() ||
         id_at_zero == first_display_id()) {
-      return std::make_pair(id_at_zero, displays_[1].id());
+      return std::make_pair(id_at_zero, active_display_list_[1].id());
     } else {
-      return std::make_pair(displays_[1].id(), id_at_zero);
+      return std::make_pair(active_display_list_[1].id(), id_at_zero);
     }
   }
 }
@@ -281,10 +265,10 @@
 
     // Primary's bounds stay the same. Just notify bounds change
     // on the secondary.
-    screen_ash_->NotifyMetricsChanged(
+    screen_->NotifyMetricsChanged(
         ScreenUtil::GetSecondaryDisplay(),
         gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS |
-        gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
+            gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
     if (delegate_)
       delegate_->PostDisplayConfigurationChange();
   }
@@ -298,13 +282,12 @@
 
 const gfx::Display& DisplayManager::FindDisplayContainingPoint(
     const gfx::Point& point_in_screen) const {
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    const gfx::Display& display = *iter;
-    if (display.bounds().Contains(point_in_screen))
-      return display;
-  }
-  return GetInvalidDisplay();
+  auto iter =
+      std::find_if(active_display_list_.begin(), active_display_list_.end(),
+                   [point_in_screen](const gfx::Display& display) {
+                     return display.bounds().Contains(point_in_screen);
+                   });
+  return iter != active_display_list_.end() ? *iter : GetInvalidDisplay();
 }
 
 bool DisplayManager::UpdateWorkAreaOfDisplay(int64 display_id,
@@ -320,9 +303,8 @@
                                        const gfx::Insets& insets_in_dip) {
   bool update = false;
   DisplayInfoList display_info_list;
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    DisplayInfo info = GetDisplayInfo(iter->id());
+  for (const auto& display : active_display_list_) {
+    DisplayInfo info = GetDisplayInfo(display.id());
     if (info.id() == display_id) {
       if (insets_in_dip.empty()) {
         info.set_clear_overscan_insets(true);
@@ -345,9 +327,8 @@
 void DisplayManager::SetDisplayRotation(int64 display_id,
                                         gfx::Display::Rotation rotation) {
   DisplayInfoList display_info_list;
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    DisplayInfo info = GetDisplayInfo(iter->id());
+  for (const auto& display : active_display_list_) {
+    DisplayInfo info = GetDisplayInfo(display.id());
     if (info.id() == display_id) {
       if (info.rotation() == rotation)
         return;
@@ -368,9 +349,8 @@
   bool found = false;
   // TODO(mukai): merge this implementation into SetDisplayMode().
   DisplayInfoList display_info_list;
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    DisplayInfo info = GetDisplayInfo(iter->id());
+  for (const auto& display : active_display_list_) {
+    DisplayInfo info = GetDisplayInfo(display.id());
     if (info.id() == display_id) {
       found = true;
       if (info.configured_ui_scale() == ui_scale)
@@ -423,9 +403,8 @@
   DisplayInfoList display_info_list;
   bool display_property_changed = false;
   bool resolution_changed = false;
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    DisplayInfo info = GetDisplayInfo(iter->id());
+  for (const auto& display : active_display_list_) {
+    DisplayInfo info = GetDisplayInfo(display.id());
     if (info.id() == display_id) {
       const std::vector<DisplayMode>& modes = info.display_modes();
       std::vector<DisplayMode>::const_iterator iter =
@@ -571,11 +550,11 @@
     const std::vector<DisplayInfo>& updated_displays) {
   if (updated_displays.empty()) {
     VLOG(1) << "OnNativeDisplaysChanged(0): # of current displays="
-            << displays_.size();
+            << active_display_list_.size();
     // If the device is booted without display, or chrome is started
     // without --ash-host-window-bounds on linux desktop, use the
     // default display.
-    if (displays_.empty()) {
+    if (active_display_list_.empty()) {
       std::vector<DisplayInfo> init_displays;
       init_displays.push_back(DisplayInfo::CreateFromSpec(std::string()));
       MaybeInitInternalDisplay(&init_displays[0]);
@@ -607,8 +586,8 @@
 
   bool internal_display_connected = false;
   num_connected_displays_ = updated_displays.size();
-  mirrored_display_id_ = gfx::Display::kInvalidDisplayID;
-  mirroring_display_ = gfx::Display();
+  mirroring_display_id_ = gfx::Display::kInvalidDisplayID;
+  software_mirroring_display_ = gfx::Display();
   DisplayInfoList new_display_info_list;
   for (DisplayInfoList::const_iterator iter = updated_displays.begin();
        iter != updated_displays.end();
@@ -619,7 +598,7 @@
     gfx::Point origin = iter->bounds_in_native().origin();
     if (origins.find(origin) != origins.end()) {
       InsertAndUpdateDisplayInfo(*iter);
-      mirrored_display_id_ = iter->id();
+      mirroring_display_id_ = iter->id();
     } else {
       origins.insert(origin);
       new_display_info_list.push_back(*iter);
@@ -643,10 +622,9 @@
     else if (display_modes_.find(iter->id()) != display_modes_.end())
       display_modes_[iter->id()] = *display_modes_iter;
   }
-  if (HasInternalDisplay() &&
-      !internal_display_connected &&
+  if (gfx::Display::HasInternalDisplay() && !internal_display_connected &&
       display_info_.find(gfx::Display::InternalDisplayId()) ==
-      display_info_.end()) {
+          display_info_.end()) {
     DisplayInfo internal_display_info(
         gfx::Display::InternalDisplayId(),
         l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME),
@@ -659,10 +637,8 @@
 
 void DisplayManager::UpdateDisplays() {
   DisplayInfoList display_info_list;
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    display_info_list.push_back(GetDisplayInfo(iter->id()));
-  }
+  for (const auto& display : active_display_list_)
+    display_info_list.push_back(GetDisplayInfo(display.id()));
   AddMirrorDisplayInfoIfAny(&display_info_list);
   UpdateDisplays(display_info_list);
 }
@@ -676,55 +652,30 @@
 #endif
 
   DisplayInfoList new_display_info_list = updated_display_info_list;
-  std::sort(displays_.begin(), displays_.end(), DisplaySortFunctor());
+  std::sort(active_display_list_.begin(), active_display_list_.end(),
+            DisplaySortFunctor());
   std::sort(new_display_info_list.begin(),
             new_display_info_list.end(),
             DisplayInfoSortFunctor());
+  // Close the mirroring window if any here to avoid creating two compositor on
+  // one display.
+  if (delegate_)
+    delegate_->CloseMirroringDisplay();
+
+  if (second_display_mode_ == MIRRORING && new_display_info_list.size() == 2)
+    CreateSoftwareMirroringDisplay(&new_display_info_list);
+
+  DisplayList new_displays;
   DisplayList removed_displays;
   std::map<size_t, uint32_t> display_changes;
   std::vector<size_t> added_display_indices;
 
-  DisplayList::iterator curr_iter = displays_.begin();
+  DisplayList::iterator curr_iter = active_display_list_.begin();
   DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin();
 
-  DisplayList new_displays;
-
-  // Use the internal display or 1st as the mirror source, then scale
-  // the root window so that it matches the external display's
-  // resolution. This is necessary in order for scaling to work while
-  // mirrored.
-  int64 mirroing_display_id = gfx::Display::kInvalidDisplayID;
-
-  if (second_display_mode_ != EXTENDED && new_display_info_list.size() == 2) {
-    bool zero_is_source =
-        first_display_id_ == new_display_info_list[0].id() ||
-        gfx::Display::InternalDisplayId() == new_display_info_list[0].id();
-    DCHECK_EQ(MIRRORING, second_display_mode_);
-    mirrored_display_id_ = new_display_info_list[zero_is_source ? 1 : 0].id();
-    mirroing_display_id = mirrored_display_id_;
-  }
-
-  while (curr_iter != displays_.end() ||
+  while (curr_iter != active_display_list_.end() ||
          new_info_iter != new_display_info_list.end()) {
-    if (new_info_iter != new_display_info_list.end() &&
-        mirroing_display_id == new_info_iter->id()) {
-      DisplayInfo info = *new_info_iter;
-      info.SetOverscanInsets(gfx::Insets());
-      InsertAndUpdateDisplayInfo(info);
-      mirroring_display_ =
-          CreateDisplayFromDisplayInfoById(mirroing_display_id);
-      ++new_info_iter;
-      // Remove existing external display if it is going to be used as
-      // mirroring display.
-      if (curr_iter != displays_.end() &&
-          curr_iter->id() == mirroing_display_id) {
-        removed_displays.push_back(*curr_iter);
-        ++curr_iter;
-      }
-      continue;
-    }
-
-    if (curr_iter == displays_.end()) {
+    if (curr_iter == active_display_list_.end()) {
       // more displays in new list.
       added_display_indices.push_back(new_displays.size());
       InsertAndUpdateDisplayInfo(*new_info_iter);
@@ -794,7 +745,7 @@
   }
   gfx::Display old_primary;
   if (delegate_)
-    old_primary = screen_ash_->GetPrimaryDisplay();
+    old_primary = screen_->GetPrimaryDisplay();
 
   // Clear focus if the display has been removed, but don't clear focus if
   // the destkop has been moved from one display to another
@@ -805,29 +756,6 @@
   if (delegate_)
     delegate_->PreDisplayConfigurationChange(clear_focus);
 
-  // Do not update |displays_| if there's nothing to be updated. Without this,
-  // it will not update the display layout, which causes the bug
-  // http://crbug.com/155948.
-  if (display_changes.empty() && added_display_indices.empty() &&
-      removed_displays.empty()) {
-    // When changing from software mirroring mode to sinlge display
-    // mode, it is possible there is no need to update |displays_| and
-    // we early out here. But we still need to update the mirroring
-    // window and call the PostDisplayConfigurationChange() cause
-    // there are some clients need to act on this,
-    // e.g. TouchTransformerController needs to adjust the
-    // TouchTransformer when/ switching from dual displays to single
-    // display.
-    if (delegate_) {
-      if (HasSoftwareMirroringDisplay())
-        CreateMirrorWindowAsyncIfAny();
-      else
-        delegate_->CloseMirroringDisplay();
-      delegate_->PostDisplayConfigurationChange();
-    }
-    return;
-  }
-
   std::vector<size_t> updated_indices;
   if (UpdateNonPrimaryDisplayBoundsForLayout(&new_displays, &updated_indices)) {
     for (std::vector<size_t>::iterator it = updated_indices.begin();
@@ -846,31 +774,25 @@
     }
   }
 
-  displays_ = new_displays;
+  active_display_list_ = new_displays;
 
   RefreshFontParams();
   base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false);
 
   // Temporarily add displays to be removed because display object
   // being removed are accessed during shutting down the root.
-  displays_.insert(displays_.end(), removed_displays.begin(),
-                   removed_displays.end());
+  active_display_list_.insert(active_display_list_.end(),
+                              removed_displays.begin(), removed_displays.end());
 
   for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin();
        iter != removed_displays.rend(); ++iter) {
-    screen_ash_->NotifyDisplayRemoved(displays_.back());
-    displays_.pop_back();
+    screen_->NotifyDisplayRemoved(active_display_list_.back());
+    active_display_list_.pop_back();
   }
 
-  bool has_mirroring_display = HasSoftwareMirroringDisplay();
-  // Close the mirroring window here to avoid creating two compositor on
-  // one display.
-  if (!has_mirroring_display && delegate_)
-    delegate_->CloseMirroringDisplay();
-
   for (std::vector<size_t>::iterator iter = added_display_indices.begin();
        iter != added_display_indices.end(); ++iter) {
-    screen_ash_->NotifyDisplayAdded(displays_[*iter]);
+    screen_->NotifyDisplayAdded(active_display_list_[*iter]);
   }
 
   bool notify_primary_change =
@@ -880,14 +802,14 @@
        iter != display_changes.end();
        ++iter) {
     uint32_t metrics = iter->second;
-    const gfx::Display& updated_display = displays_[iter->first];
+    const gfx::Display& updated_display = active_display_list_[iter->first];
 
     if (notify_primary_change &&
         updated_display.id() == screen_->GetPrimaryDisplay().id()) {
       metrics |= gfx::DisplayObserver::DISPLAY_METRIC_PRIMARY;
       notify_primary_change = false;
     }
-    screen_ash_->NotifyMetricsChanged(updated_display, metrics);
+    screen_->NotifyMetricsChanged(updated_display, metrics);
   }
 
   if (notify_primary_change) {
@@ -903,7 +825,7 @@
       if (primary.device_scale_factor() != old_primary.device_scale_factor())
         metrics |= gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
 
-      screen_ash_->NotifyMetricsChanged(primary, metrics);
+      screen_->NotifyMetricsChanged(primary, metrics);
     }
   }
 
@@ -922,24 +844,24 @@
 }
 
 const gfx::Display& DisplayManager::GetDisplayAt(size_t index) const {
-  DCHECK_LT(index, displays_.size());
-  return displays_[index];
+  DCHECK_LT(index, active_display_list_.size());
+  return active_display_list_[index];
 }
 
 const gfx::Display& DisplayManager::GetPrimaryDisplayCandidate() const {
   if (GetNumDisplays() != 2)
-    return displays_[0];
+    return active_display_list_[0];
   DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout(
       GetCurrentDisplayIdPair());
   return GetDisplayForId(layout.primary_id);
 }
 
 size_t DisplayManager::GetNumDisplays() const {
-  return displays_.size();
+  return active_display_list_.size();
 }
 
-bool DisplayManager::IsMirrored() const {
-  return mirrored_display_id_ != gfx::Display::kInvalidDisplayID;
+bool DisplayManager::IsInMirrorMode() const {
+  return mirroring_display_id_ != gfx::Display::kInvalidDisplayID;
 }
 
 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const {
@@ -1003,9 +925,10 @@
 }
 
 void DisplayManager::AddRemoveDisplay() {
-  DCHECK(!displays_.empty());
+  DCHECK(!active_display_list_.empty());
   std::vector<DisplayInfo> new_display_info_list;
-  const DisplayInfo& first_display = GetDisplayInfo(displays_[0].id());
+  const DisplayInfo& first_display =
+      GetDisplayInfo(active_display_list_[0].id());
   new_display_info_list.push_back(first_display);
   // Add if there is only one display connected.
   if (num_connected_displays() == 1) {
@@ -1016,16 +939,16 @@
             "%d+%d-500x400", host_bounds.x(), host_bounds.bottom())));
   }
   num_connected_displays_ = new_display_info_list.size();
-  mirrored_display_id_ = gfx::Display::kInvalidDisplayID;
-  mirroring_display_ = gfx::Display();
+  mirroring_display_id_ = gfx::Display::kInvalidDisplayID;
+  software_mirroring_display_ = gfx::Display();
   UpdateDisplays(new_display_info_list);
 }
 
 void DisplayManager::ToggleDisplayScaleFactor() {
-  DCHECK(!displays_.empty());
+  DCHECK(!active_display_list_.empty());
   std::vector<DisplayInfo> new_display_info_list;
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
+  for (DisplayList::const_iterator iter = active_display_list_.begin();
+       iter != active_display_list_.end(); ++iter) {
     DisplayInfo display_info = GetDisplayInfo(iter->id());
     display_info.set_device_scale_factor(
         display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f);
@@ -1047,8 +970,8 @@
 
 void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) {
   second_display_mode_ = mode;
-  mirrored_display_id_ = gfx::Display::kInvalidDisplayID;
-  mirroring_display_ = gfx::Display();
+  mirroring_display_id_ = gfx::Display::kInvalidDisplayID;
+  software_mirroring_display_ = gfx::Display();
 }
 
 bool DisplayManager::UpdateDisplayBounds(int64 display_id,
@@ -1056,12 +979,12 @@
   if (change_display_upon_host_resize_) {
     display_info_[display_id].SetBounds(new_bounds);
     // Don't notify observers if the mirrored window has changed.
-    if (software_mirroring_enabled() && mirrored_display_id_ == display_id)
+    if (software_mirroring_enabled() && mirroring_display_id_ == display_id)
       return false;
     gfx::Display* display = FindDisplayForId(display_id);
     display->SetSize(display_info_[display_id].size_in_pixel());
-    screen_ash_->NotifyMetricsChanged(
-        *display, gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
+    screen_->NotifyMetricsChanged(*display,
+                                  gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
     return true;
   }
   return false;
@@ -1071,7 +994,7 @@
   // Do not post a task if the software mirroring doesn't exist, or
   // during initialization when compositor's init task isn't posted yet.
   // ash::Shell::Init() will call this after the compositor is initialized.
-  if (!HasSoftwareMirroringDisplay() || !delegate_)
+  if (!software_mirroring_display_.is_valid() || !delegate_)
     return;
   base::MessageLoopForUI::current()->PostTask(
       FROM_HERE,
@@ -1081,10 +1004,9 @@
 
 void DisplayManager::CreateScreenForShutdown() const {
   bool native_is_ash =
-      gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE) ==
-      screen_ash_.get();
+      gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE) == screen_.get();
   delete screen_for_shutdown;
-  screen_for_shutdown = screen_ash_->CloneForShutdown();
+  screen_for_shutdown = screen_->CloneForShutdown();
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE,
                                  screen_for_shutdown);
   if (native_is_ash) {
@@ -1100,20 +1022,45 @@
   SetInternalDisplayModeList(info);
 }
 
+void DisplayManager::CreateSoftwareMirroringDisplay(
+    DisplayInfoList* display_info_list) {
+  // Use the internal display or 1st as the mirror source, then scale
+  // the root window so that it matches the external display's
+  // resolution. This is necessary in order for scaling to work while
+  // mirrored.
+  bool zero_is_source =
+      first_display_id_ == (*display_info_list)[0].id() ||
+      gfx::Display::InternalDisplayId() == (*display_info_list)[0].id();
+  DCHECK_EQ(MIRRORING, second_display_mode_);
+  mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id();
+  int64 display_id = mirroring_display_id_;
+  auto iter = std::find_if(display_info_list->begin(), display_info_list->end(),
+                           [display_id](const DisplayInfo& info) {
+                             return info.id() == display_id;
+                           });
+  DCHECK(iter != display_info_list->end());
+  DisplayInfo info = *iter;
+  info.SetOverscanInsets(gfx::Insets());
+  InsertAndUpdateDisplayInfo(info);
+  software_mirroring_display_ =
+      CreateDisplayFromDisplayInfoById(mirroring_display_id_);
+  display_info_list->erase(iter);
+}
+
 gfx::Display* DisplayManager::FindDisplayForId(int64 id) {
-  for (DisplayList::iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    if ((*iter).id() == id)
-      return &(*iter);
-  }
+  auto iter = std::find_if(
+      active_display_list_.begin(), active_display_list_.end(),
+      [id](const gfx::Display& display) { return display.id() == id; });
+  if (iter != active_display_list_.end())
+    return &(*iter);
   DLOG(WARNING) << "Could not find display:" << id;
   return NULL;
 }
 
 void DisplayManager::AddMirrorDisplayInfoIfAny(
     std::vector<DisplayInfo>* display_info_list) {
-  if (software_mirroring_enabled() && IsMirrored())
-    display_info_list->push_back(GetDisplayInfo(mirrored_display_id_));
+  if (software_mirroring_enabled() && IsInMirrorMode())
+    display_info_list->push_back(GetDisplayInfo(mirroring_display_id_));
 }
 
 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) {
@@ -1214,17 +1161,12 @@
 }
 
 void DisplayManager::CreateMirrorWindowIfAny() {
-  if (HasSoftwareMirroringDisplay() && delegate_) {
-    DisplayInfo display_info = GetDisplayInfo(mirroring_display_.id());
+  if (software_mirroring_display_.is_valid() && delegate_) {
+    DisplayInfo display_info = GetDisplayInfo(software_mirroring_display_.id());
     delegate_->CreateOrUpdateMirroringDisplay(display_info);
   }
 }
 
-bool DisplayManager::HasSoftwareMirroringDisplay() {
-  return second_display_mode_ != DisplayManager::EXTENDED &&
-      mirroring_display_.is_valid();
-}
-
 // static
 void DisplayManager::UpdateDisplayBoundsForLayout(
     const DisplayLayout& layout,
@@ -1272,4 +1214,9 @@
   secondary_display->UpdateWorkAreaFromInsets(insets);
 }
 
+void DisplayManager::RunPendingTasksForTest() {
+  if (software_mirroring_display_.is_valid())
+    base::RunLoop().RunUntilIdle();
+}
+
 }  // namespace ash
diff --git a/ash/display/display_manager.h b/ash/display/display_manager.h
index 092d2b0..9aa686c 100644
--- a/ash/display/display_manager.h
+++ b/ash/display/display_manager.h
@@ -68,6 +68,8 @@
     virtual void PostDisplayConfigurationChange() = 0;
   };
 
+  typedef std::vector<gfx::Display> DisplayList;
+
   // How the second display will be used.
   // 1) EXTENDED mode extends the desktop to the second dislpay.
   // 2) MIRRORING mode copies the content of the primary display to
@@ -88,13 +90,9 @@
     return layout_store_.get();
   }
 
-  gfx::Screen* screen() {
-    return screen_;
-  }
-
   void set_delegate(Delegate* delegate) { delegate_ = delegate; }
 
-  // When set to true, the MonitorManager calls OnDisplayMetricsChanged
+  // When set to true, the DisplayManager calls OnDisplayMetricsChanged
   // even if the display's bounds didn't change. Used to swap primary
   // display.
   void set_force_bounds_changed(bool force_bounds_changed) {
@@ -115,14 +113,6 @@
   // configuration.
   void RefreshFontParams();
 
-  // True if the given |display| is currently connected.
-  bool IsActiveDisplay(const gfx::Display& display) const;
-
-  // True if there is an internal display.
-  bool HasInternalDisplay() const;
-
-  bool IsInternalDisplayId(int64 id) const;
-
   // Returns the display layout used for current displays.
   DisplayLayout GetCurrentDisplayLayout();
 
@@ -237,19 +227,21 @@
   // when displays are mirrored.
   size_t GetNumDisplays() const;
 
-  const std::vector<gfx::Display>& displays() const { return displays_; }
+  const DisplayList& active_display_list() const {
+    return active_display_list_;
+  }
 
   // Returns the number of connected displays. This returns 2
   // when displays are mirrored.
   size_t num_connected_displays() const { return num_connected_displays_; }
 
   // Returns the mirroring status.
-  bool IsMirrored() const;
-  int64 mirrored_display_id() const { return mirrored_display_id_; }
+  bool IsInMirrorMode() const;
+  int64 mirroring_display_id() const { return mirroring_display_id_; }
 
   // Returns the display used for software mirrroring.
-  const gfx::Display& mirroring_display() const {
-    return mirroring_display_;
+  const gfx::Display& software_mirroring_display() const {
+    return software_mirroring_display_;
   }
 
   // Retuns the display info associated with |display_id|.
@@ -315,17 +307,21 @@
   friend class test::DisplayManagerTestApi;
   friend class test::SystemGestureEventFilterTest;
 
-  typedef std::vector<gfx::Display> DisplayList;
+  typedef std::vector<DisplayInfo> DisplayInfoList;
 
   void set_change_display_upon_host_resize(bool value) {
     change_display_upon_host_resize_ = value;
   }
 
+  // Creates software mirroring display related information. The display
+  // used to mirror the content is removed from the |display_info_list|.
+  void CreateSoftwareMirroringDisplay(DisplayInfoList* display_info_list);
+
   gfx::Display* FindDisplayForId(int64 id);
 
   // Add the mirror display's display info if the software based
   // mirroring is in use.
-  void AddMirrorDisplayInfoIfAny(std::vector<DisplayInfo>* display_info_list);
+  void AddMirrorDisplayInfoIfAny(DisplayInfoList* display_info_list);
 
   // Inserts and update the DisplayInfo according to the overscan
   // state. Note that The DisplayInfo stored in the |internal_display_info_|
@@ -352,7 +348,7 @@
 
   void CreateMirrorWindowIfAny();
 
-  bool HasSoftwareMirroringDisplay();
+  void RunPendingTasksForTest();
 
   static void UpdateDisplayBoundsForLayout(
       const DisplayLayout& layout,
@@ -361,16 +357,14 @@
 
   Delegate* delegate_;  // not owned.
 
-  scoped_ptr<ScreenAsh> screen_ash_;
-  // This is to have an accessor without ScreenAsh definition.
-  gfx::Screen* screen_;
+  scoped_ptr<ScreenAsh> screen_;
 
   scoped_ptr<DisplayLayoutStore> layout_store_;
 
   int64 first_display_id_;
 
   // List of current active displays.
-  DisplayList displays_;
+  DisplayList active_display_list_;
 
   int num_connected_displays_;
 
@@ -390,8 +384,8 @@
   bool change_display_upon_host_resize_;
 
   SecondDisplayMode second_display_mode_;
-  int64 mirrored_display_id_;
-  gfx::Display mirroring_display_;
+  int64 mirroring_display_id_;
+  gfx::Display software_mirroring_display_;
 
   // User preference for rotation lock of the internal display.
   bool registered_internal_display_rotation_lock_;
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index 4fc4057..9ed1039 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -487,7 +487,7 @@
       CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
   const DisplayInfo external_display_info =
       CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
-  const DisplayInfo mirrored_display_info =
+  const DisplayInfo mirroring_display_info =
       CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500));
 
   EXPECT_EQ(1U, display_manager()->GetNumDisplays());
@@ -502,7 +502,7 @@
   EXPECT_EQ(default_bounds,
             display_manager()->GetDisplayAt(0).bounds().ToString());
   EXPECT_EQ(1U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 
   if (!SupportsMultipleDisplays())
     return;
@@ -516,7 +516,7 @@
   EXPECT_EQ("1,1 100x100",
             GetDisplayInfoForId(external_id).bounds_in_native().ToString());
   EXPECT_EQ(1U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
   EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id());
 
   EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId());
@@ -535,7 +535,7 @@
   EXPECT_EQ("1,1 100x100",
             GetDisplayInfoForId(10).bounds_in_native().ToString());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
   EXPECT_EQ(ToDisplayName(internal_display_id),
             display_manager()->GetDisplayNameForId(internal_display_id));
 
@@ -548,7 +548,7 @@
   EXPECT_EQ("1,1 100x100",
             GetDisplayInfoForId(10).bounds_in_native().ToString());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
   EXPECT_EQ(ToDisplayName(internal_display_id),
             display_manager()->GetDisplayNameForId(internal_display_id));
 
@@ -559,21 +559,21 @@
   EXPECT_EQ("0,0 500x500",
             GetDisplayForId(internal_display_id).bounds().ToString());
   EXPECT_EQ(1U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 
   // External display was changed during suspend.
   display_info_list.push_back(external_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 
   // suspend...
   display_info_list.clear();
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 
   // and resume with different external display.
   display_info_list.push_back(internal_display_info);
@@ -581,20 +581,20 @@
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 
   // mirrored...
   display_info_list.clear();
   display_info_list.push_back(internal_display_info);
-  display_info_list.push_back(mirrored_display_info);
+  display_info_list.push_back(mirroring_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(1U, display_manager()->GetNumDisplays());
   EXPECT_EQ("0,0 500x500",
             GetDisplayForId(internal_display_id).bounds().ToString());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_EQ(11U, display_manager()->mirrored_display_id());
-  EXPECT_TRUE(display_manager()->IsMirrored());
+  EXPECT_EQ(11U, display_manager()->mirroring_display_id());
+  EXPECT_TRUE(display_manager()->IsInMirrorMode());
 
   // Test display name.
   EXPECT_EQ(ToDisplayName(internal_display_id),
@@ -612,7 +612,7 @@
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
   EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
   EXPECT_EQ("0,0 500x500",
             GetDisplayForId(internal_display_id).bounds().ToString());
   EXPECT_EQ("500,0 100x100",
@@ -627,7 +627,7 @@
   EXPECT_EQ("1,1 100x100",
             GetDisplayInfoForId(external_id).bounds_in_native().ToString());
   EXPECT_EQ(1U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 
   // Switched to another display
   display_info_list.clear();
@@ -638,7 +638,7 @@
       "0,0 500x500",
       GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString());
   EXPECT_EQ(1U, display_manager()->num_connected_displays());
-  EXPECT_FALSE(display_manager()->IsMirrored());
+  EXPECT_FALSE(display_manager()->IsInMirrorMode());
 }
 
 // Make sure crash does not happen if add and remove happens at the same time.
@@ -1217,13 +1217,13 @@
   EXPECT_EQ("400x500", test_api.GetHost()->GetBounds().size().ToString());
   EXPECT_EQ("300x400",
             test_api.GetHost()->window()->bounds().size().ToString());
-  EXPECT_TRUE(display_manager->IsMirrored());
+  EXPECT_TRUE(display_manager->IsInMirrorMode());
 
   display_manager->SetMirrorMode(false);
   EXPECT_TRUE(display_observer.changed_and_reset());
   EXPECT_EQ(NULL, test_api.GetHost());
   EXPECT_EQ(2U, display_manager->GetNumDisplays());
-  EXPECT_FALSE(display_manager->IsMirrored());
+  EXPECT_FALSE(display_manager->IsInMirrorMode());
 
   // Make sure the mirror window has the pixel size of the
   // source display.
@@ -1268,14 +1268,14 @@
   display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING);
   UpdateDisplay("600x400,600x400");
 
-  EXPECT_TRUE(display_manager->IsMirrored());
+  EXPECT_TRUE(display_manager->IsInMirrorMode());
   EXPECT_EQ(1U, display_manager->GetNumDisplays());
   DisplayController* display_controller =
       ash::Shell::GetInstance()->display_controller();
   EXPECT_TRUE(display_controller->mirror_window_controller()->GetWindow());
 
   UpdateDisplay("600x400");
-  EXPECT_FALSE(display_manager->IsMirrored());
+  EXPECT_FALSE(display_manager->IsInMirrorMode());
   EXPECT_EQ(1U, display_manager->GetNumDisplays());
   EXPECT_FALSE(display_controller->mirror_window_controller()->GetWindow());
 }
diff --git a/ash/display/mirror_window_controller.cc b/ash/display/mirror_window_controller.cc
index 1a08296..c7e5acf0 100644
--- a/ash/display/mirror_window_controller.cc
+++ b/ash/display/mirror_window_controller.cc
@@ -125,7 +125,7 @@
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
       Shell::GetScreen()->GetPrimaryDisplay().id());
-  DCHECK(display_manager->IsMirrored());
+  DCHECK(display_manager->IsInMirrorMode());
   scoped_ptr<RootWindowTransformer> transformer(
       CreateRootWindowTransformerForMirroredDisplay(source_display_info,
                                                     display_info));
@@ -136,7 +136,7 @@
   if (ash_host_.get()) {
     DisplayManager* display_manager = Shell::GetInstance()->display_manager();
     const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
-        display_manager->mirrored_display_id());
+        display_manager->mirroring_display_id());
     UpdateWindow(mirror_display_info);
   }
 }
@@ -175,11 +175,11 @@
 scoped_ptr<RootWindowTransformer>
 MirrorWindowController::CreateRootWindowTransformer() const {
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
-      display_manager->mirrored_display_id());
+  const DisplayInfo& mirror_display_info =
+      display_manager->GetDisplayInfo(display_manager->mirroring_display_id());
   const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
       Shell::GetScreen()->GetPrimaryDisplay().id());
-  DCHECK(display_manager->IsMirrored());
+  DCHECK(display_manager->IsInMirrorMode());
   return scoped_ptr<RootWindowTransformer>(
       CreateRootWindowTransformerForMirroredDisplay(source_display_info,
                                                     mirror_display_info));
diff --git a/ash/display/mirror_window_controller_unittest.cc b/ash/display/mirror_window_controller_unittest.cc
index 15bdefaf..c1fe0cb 100644
--- a/ash/display/mirror_window_controller_unittest.cc
+++ b/ash/display/mirror_window_controller_unittest.cc
@@ -283,8 +283,8 @@
   EXPECT_EQ(internal_id, internal_display_id);
 
   EXPECT_EQ(1U, display_manager->GetNumDisplays());
-  EXPECT_TRUE(display_manager->IsMirrored());
-  EXPECT_EQ(external_id, display_manager->mirrored_display_id());
+  EXPECT_TRUE(display_manager->IsInMirrorMode());
+  EXPECT_EQ(external_id, display_manager->mirroring_display_id());
 
   // dock mode.
   display_info_list.clear();
@@ -292,7 +292,7 @@
   display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING);
   display_manager->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(1U, display_manager->GetNumDisplays());
-  EXPECT_FALSE(display_manager->IsMirrored());
+  EXPECT_FALSE(display_manager->IsInMirrorMode());
 
   // back to software mirroring.
   display_info_list.clear();
@@ -301,13 +301,13 @@
   display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING);
   display_manager->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(1U, display_manager->GetNumDisplays());
-  EXPECT_TRUE(display_manager->IsMirrored());
-  EXPECT_EQ(external_id, display_manager->mirrored_display_id());
+  EXPECT_TRUE(display_manager->IsInMirrorMode());
+  EXPECT_EQ(external_id, display_manager->mirroring_display_id());
 }
 
 TEST_F(MirrorOnBootTest, MAYBE_MirrorOnBoot) {
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  EXPECT_TRUE(display_manager->IsMirrored());
+  EXPECT_TRUE(display_manager->IsInMirrorMode());
   RunAllPendingInMessageLoop();
   test::MirrorWindowTestApi test_api;
   EXPECT_TRUE(test_api.GetHost());
diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc
index c736901..e904881 100644
--- a/ash/display/mouse_cursor_event_filter.cc
+++ b/ash/display/mouse_cursor_event_filter.cc
@@ -109,9 +109,8 @@
 }  // namespace
 
 MouseCursorEventFilter::MouseCursorEventFilter()
-    : mouse_warp_mode_(WARP_ALWAYS),
+    : mouse_warp_enabled_(true),
       drag_source_root_(NULL),
-      scale_when_drag_started_(1.0f),
       shared_display_edge_indicator_(new SharedDisplayEdgeIndicator) {
   Shell::GetInstance()->display_controller()->AddObserver(this);
 }
@@ -174,14 +173,6 @@
 }
 
 void MouseCursorEventFilter::OnMouseEvent(ui::MouseEvent* event) {
-  aura::Window* target = static_cast<aura::Window*>(event->target());
-
-  if (event->type() == ui::ET_MOUSE_PRESSED) {
-    scale_when_drag_started_ = ui::GetDeviceScaleFactor(target->layer());
-  } else if (event->type() == ui::ET_MOUSE_RELEASED) {
-    scale_when_drag_started_ = 1.0f;
-  }
-
   // Handle both MOVED and DRAGGED events here because when the mouse pointer
   // enters the other root window while dragging, the underlying window system
   // (at least X11) stops generating a ui::ET_MOUSE_MOVED event.
@@ -246,8 +237,7 @@
 bool MouseCursorEventFilter::WarpMouseCursorInNativeCoords(
     const gfx::Point& point_in_native,
     const gfx::Point& point_in_screen) {
-  if (Shell::GetScreen()->GetNumDisplays() <= 1 ||
-      mouse_warp_mode_ == WARP_NONE)
+  if (Shell::GetScreen()->GetNumDisplays() <= 1 || !mouse_warp_enabled_)
     return false;
 
   bool in_src_edge = src_edge_bounds_in_native_.Contains(point_in_native);
diff --git a/ash/display/mouse_cursor_event_filter.h b/ash/display/mouse_cursor_event_filter.h
index 62c02cb6..44496cf 100644
--- a/ash/display/mouse_cursor_event_filter.h
+++ b/ash/display/mouse_cursor_event_filter.h
@@ -26,20 +26,10 @@
 class ASH_EXPORT MouseCursorEventFilter : public ui::EventHandler,
                                           public DisplayController::Observer {
  public:
-  enum MouseWarpMode {
-    WARP_ALWAYS,   // Always warp the mouse when possible.
-    WARP_DRAG,     // Used when dragging a window. Top and bottom
-                   // corner of the shared edge is reserved for window
-                   // snapping.
-    WARP_NONE,     // No mouse warping. Used when resizing the window.
-  };
-
   MouseCursorEventFilter();
   ~MouseCursorEventFilter() override;
 
-  void set_mouse_warp_mode(MouseWarpMode mouse_warp_mode) {
-    mouse_warp_mode_ = mouse_warp_mode;
-  }
+  void set_mouse_warp_enabled(bool enabled) { mouse_warp_enabled_ = enabled; }
 
   // Shows/Hide the indicator for window dragging. The |from|
   // is the window where the dragging started.
@@ -88,18 +78,17 @@
   void UpdateHorizontalEdgeBounds();
   void UpdateVerticalEdgeBounds();
 
-  // Returns the source and destination window. When the
-  // mouse_warp_mode_ is WARP_DRAG, src_window is the root window
-  // where the drag starts. When the mouse_warp_mode_ is WARP_ALWAYS,
-  // the src_window is always the primary root window, because there
-  // is no difference between moving src to dst and moving dst to src.
+  // Returns the source and destination window. When |src_window| is
+  // |drag_soruce_root_| when it is set. Otherwise, the |src_window|
+  // is always the primary root window, because there is no difference
+  // between moving src to dst and moving dst to src.
   void GetSrcAndDstRootWindows(aura::Window** src_window,
                                aura::Window** dst_window);
 
   bool WarpMouseCursorIfNecessaryForTest(aura::Window* target_root,
                                          const gfx::Point& point_in_screen);
 
-  MouseWarpMode mouse_warp_mode_;
+  bool mouse_warp_enabled_;
 
   // The bounds for warp hole windows. |dst_indicator_bounds_| is kept
   // in the instance for testing.
@@ -112,8 +101,6 @@
   // The root window in which the dragging started.
   aura::Window* drag_source_root_;
 
-  float scale_when_drag_started_;
-
   // Shows the area where a window can be dragged in to/out from
   // another display.
   scoped_ptr<SharedDisplayEdgeIndicator> shared_display_edge_indicator_;
diff --git a/ash/display/mouse_cursor_event_filter_unittest.cc b/ash/display/mouse_cursor_event_filter_unittest.cc
index d1b9f38..58a1a0f 100644
--- a/ash/display/mouse_cursor_event_filter_unittest.cc
+++ b/ash/display/mouse_cursor_event_filter_unittest.cc
@@ -172,13 +172,12 @@
   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1));
 
-  event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE);
+  event_filter()->set_mouse_warp_enabled(false);
   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0],
                                           gfx::Point(499, 11)));
   EXPECT_EQ("1,1",
             aura::Env::GetInstance()->last_mouse_location().ToString());
-
-  event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_ALWAYS);
+  event_filter()->set_mouse_warp_enabled(true);
   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11)));
   EXPECT_EQ("501,11",
             aura::Env::GetInstance()->last_mouse_location().ToString());
diff --git a/ash/display/resolution_notification_controller.cc b/ash/display/resolution_notification_controller.cc
index bea5554..a0e98ea 100644
--- a/ash/display/resolution_notification_controller.cc
+++ b/ash/display/resolution_notification_controller.cc
@@ -139,7 +139,7 @@
       accept_callback(accept_callback),
       timeout_count(0) {
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
-  if (!display_manager->HasInternalDisplay() &&
+  if (!gfx::Display::HasInternalDisplay() &&
       display_manager->num_connected_displays() == 1u) {
     timeout_count = kTimeoutInSec;
   }
diff --git a/ash/display/screen_ash.cc b/ash/display/screen_ash.cc
index 271b8e62..700abe6 100644
--- a/ash/display/screen_ash.cc
+++ b/ash/display/screen_ash.cc
@@ -146,7 +146,7 @@
 }
 
 std::vector<gfx::Display> ScreenAsh::GetAllDisplays() const {
-  return GetDisplayManager()->displays();
+  return GetDisplayManager()->active_display_list();
 }
 
 gfx::Display ScreenAsh::GetDisplayNearestWindow(gfx::NativeView window) const {
@@ -165,8 +165,8 @@
   DisplayManager* display_manager = GetDisplayManager();
   // RootWindow needs Display to determine its device scale factor
   // for non desktop display.
-  if (display_manager->mirroring_display().id() == id)
-    return display_manager->mirroring_display();
+  if (display_manager->software_mirroring_display().id() == id)
+    return display_manager->software_mirroring_display();
   return display_manager->GetDisplayForId(id);
 }
 
@@ -178,14 +178,15 @@
   // Fallback to the display that has the shortest Manhattan distance from
   // the |point|. This is correct in the only areas that matter, namely in the
   // corners between the physical screens.
-  return FindDisplayNearestPoint(GetDisplayManager()->displays(), point);
+  return FindDisplayNearestPoint(GetDisplayManager()->active_display_list(),
+                                 point);
 }
 
 gfx::Display ScreenAsh::GetDisplayMatching(const gfx::Rect& match_rect) const {
   if (match_rect.IsEmpty())
     return GetDisplayNearestPoint(match_rect.origin());
-  const gfx::Display* matching =
-      FindDisplayMatching(GetDisplayManager()->displays(), match_rect);
+  const gfx::Display* matching = FindDisplayMatching(
+      GetDisplayManager()->active_display_list(), match_rect);
   // Fallback to the primary display if there is no matching display.
   return matching ? *matching : GetPrimaryDisplay();
 }
diff --git a/ash/host/ash_remote_window_tree_host_win.h b/ash/host/ash_remote_window_tree_host_win.h
index 8c97db92..143a0ce 100644
--- a/ash/host/ash_remote_window_tree_host_win.h
+++ b/ash/host/ash_remote_window_tree_host_win.h
@@ -21,22 +21,22 @@
   explicit AshRemoteWindowTreeHostWin(HWND remote_hwnd);
 
  private:
-  virtual ~AshRemoteWindowTreeHostWin();
+  ~AshRemoteWindowTreeHostWin() override;
 
   // AshWindowTreeHost:
-  virtual void ToggleFullScreen() override;
-  virtual bool ConfineCursorToRootWindow() override;
-  virtual void UnConfineCursor() override;
-  virtual void SetRootWindowTransformer(
+  void ToggleFullScreen() override;
+  bool ConfineCursorToRootWindow() override;
+  void UnConfineCursor() override;
+  void SetRootWindowTransformer(
       scoped_ptr<RootWindowTransformer> transformer) override;
-  virtual gfx::Insets GetHostInsets() const override;
-  virtual aura::WindowTreeHost* AsWindowTreeHost() override;
+  gfx::Insets GetHostInsets() const override;
+  aura::WindowTreeHost* AsWindowTreeHost() override;
 
   // WindowTreeHostWin:
-  virtual gfx::Transform GetRootTransform() const override;
-  virtual void SetRootTransform(const gfx::Transform& transform) override;
-  virtual gfx::Transform GetInverseRootTransform() const override;
-  virtual void UpdateRootWindowSize(const gfx::Size& host_size) override;
+  gfx::Transform GetRootTransform() const override;
+  void SetRootTransform(const gfx::Transform& transform) override;
+  gfx::Transform GetInverseRootTransform() const override;
+  void UpdateRootWindowSize(const gfx::Size& host_size) override;
 
   TransformerHelper transformer_helper_;
 
diff --git a/ash/host/ash_window_tree_host_win.cc b/ash/host/ash_window_tree_host_win.cc
index d8ab45b..9d0988de 100644
--- a/ash/host/ash_window_tree_host_win.cc
+++ b/ash/host/ash_window_tree_host_win.cc
@@ -28,11 +28,11 @@
         saved_window_style_(0),
         saved_window_ex_style_(0),
         transformer_helper_(this) {}
-  virtual ~AshWindowTreeHostWin() {}
+  ~AshWindowTreeHostWin() override {}
 
  private:
   // AshWindowTreeHost:
-  virtual void ToggleFullScreen() override {
+  void ToggleFullScreen() override {
     gfx::Rect target_rect;
     if (!fullscreen_) {
       fullscreen_ = true;
@@ -66,19 +66,18 @@
                  target_rect.height(),
                  SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
   }
-  virtual bool ConfineCursorToRootWindow() override { return false; }
-  virtual void UnConfineCursor() override { NOTIMPLEMENTED(); }
-  virtual void SetRootWindowTransformer(
-      scoped_ptr<RootWindowTransformer> transformer) {
+  bool ConfineCursorToRootWindow() override { return false; }
+  void UnConfineCursor() override { NOTIMPLEMENTED(); }
+  void SetRootWindowTransformer(scoped_ptr<RootWindowTransformer> transformer) {
     transformer_helper_.SetRootWindowTransformer(transformer.Pass());
   }
-  virtual gfx::Insets GetHostInsets() const override {
+  gfx::Insets GetHostInsets() const override {
     return transformer_helper_.GetHostInsets();
   }
-  virtual aura::WindowTreeHost* AsWindowTreeHost() override { return this; }
+  aura::WindowTreeHost* AsWindowTreeHost() override { return this; }
 
   // WindowTreeHostWin:
-  virtual void SetBounds(const gfx::Rect& bounds) override {
+  void SetBounds(const gfx::Rect& bounds) override {
     if (fullscreen_) {
       saved_window_rect_.right = saved_window_rect_.left + bounds.width();
       saved_window_rect_.bottom = saved_window_rect_.top + bounds.height();
@@ -86,16 +85,16 @@
     }
     WindowTreeHostWin::SetBounds(bounds);
   }
-  virtual void SetRootTransform(const gfx::Transform& transform) override {
+  void SetRootTransform(const gfx::Transform& transform) override {
     transformer_helper_.SetTransform(transform);
   }
   gfx::Transform GetRootTransform() const {
     return transformer_helper_.GetTransform();
   }
-  virtual gfx::Transform GetInverseRootTransform() const override {
+  gfx::Transform GetInverseRootTransform() const override {
     return transformer_helper_.GetInverseTransform();
   }
-  virtual void UpdateRootWindowSize(const gfx::Size& host_size) override {
+  void UpdateRootWindowSize(const gfx::Size& host_size) override {
     transformer_helper_.UpdateWindowSize(host_size);
   }
 
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc
index c1c9e63..ccdcb8f4 100644
--- a/ash/metrics/user_metrics_recorder.cc
+++ b/ash/metrics/user_metrics_recorder.cc
@@ -203,6 +203,9 @@
     case ash::UMA_LAUNCHER_LAUNCH_TASK:
       base::RecordAction(base::UserMetricsAction("Launcher_LaunchTask"));
       break;
+    case ash::UMA_LAUNCHER_SWITCH_TASK:
+      base::RecordAction(base::UserMetricsAction("Launcher_SwitchTask"));
+      break;
     case UMA_MAXIMIZE_MODE_DISABLED:
       base::RecordAction(base::UserMetricsAction("Touchview_Disabled"));
       break;
diff --git a/ash/metrics/user_metrics_recorder.h b/ash/metrics/user_metrics_recorder.h
index da39a106..7c27326 100644
--- a/ash/metrics/user_metrics_recorder.h
+++ b/ash/metrics/user_metrics_recorder.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 ASH_USER_METRICS_RECORDER_H_
-#define ASH_USER_METRICS_RECORDER_H_
+#ifndef ASH_METRICS_USER_METRICS_RECORDER_H_
+#define ASH_METRICS_USER_METRICS_RECORDER_H_
 
 #include "ash/ash_export.h"
 #include "base/timer/timer.h"
@@ -30,6 +30,7 @@
   UMA_LAUNCHER_CLICK_ON_APP,
   UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON,
   UMA_LAUNCHER_LAUNCH_TASK,
+  UMA_LAUNCHER_SWITCH_TASK,
   UMA_MAXIMIZE_MODE_DISABLED,
   UMA_MAXIMIZE_MODE_ENABLED,
   UMA_MAXIMIZE_MODE_INITIALLY_DISABLED,
@@ -139,4 +140,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_USER_METRICS_RECORDER_H_
+#endif  // ASH_METRICS_USER_METRICS_RECORDER_H_
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd
index 62b9159..d2ebea9 100644
--- a/ash/resources/ash_resources.grd
+++ b/ash/resources/ash_resources.grd
@@ -80,6 +80,11 @@
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED_HOVER" file="cros/status/status_bluetooth_disabled_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED" file="cros/status/status_bluetooth_enabled.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED_HOVER" file="cros/status/status_bluetooth_enabled_hover.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_CAST" file="cros/status/status_cast.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_CAST_DISABLED" file="cros/status/status_cast_disabled.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_CAST_DISABLED_HOVER" file="cros/status/status_cast_disabled_hover.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_CAST_ENABLED" file="cros/status/status_cast_enabled.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_CAST_ENABLED_HOVER" file="cros/status/status_cast_enabled_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_DRIVE" file="cros/status/status_drive.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_DRIVE_CANCEL" file="cros/status/status_drive_item_cancel.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_DRIVE_CANCEL_HOVER" file="cros/status/status_drive_item_cancel_hover.png" />
diff --git a/ash/resources/default_100_percent/cros/status/status_cast.png b/ash/resources/default_100_percent/cros/status/status_cast.png
new file mode 100644
index 0000000..d5694f6
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_cast.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_cast_disabled.png b/ash/resources/default_100_percent/cros/status/status_cast_disabled.png
new file mode 100644
index 0000000..7f91cc3
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_cast_disabled.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_cast_disabled_hover.png b/ash/resources/default_100_percent/cros/status/status_cast_disabled_hover.png
new file mode 100644
index 0000000..7f91cc3
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_cast_disabled_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_cast_enabled.png b/ash/resources/default_100_percent/cros/status/status_cast_enabled.png
new file mode 100644
index 0000000..cbfdc15
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_cast_enabled.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_cast_enabled_hover.png b/ash/resources/default_100_percent/cros/status/status_cast_enabled_hover.png
new file mode 100644
index 0000000..cbfdc15
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_cast_enabled_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_cast.png b/ash/resources/default_200_percent/cros/status/status_cast.png
new file mode 100644
index 0000000..7420999
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_cast.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_cast_disabled.png b/ash/resources/default_200_percent/cros/status/status_cast_disabled.png
new file mode 100644
index 0000000..f52ea74
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_cast_disabled.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_cast_disabled_hover.png b/ash/resources/default_200_percent/cros/status/status_cast_disabled_hover.png
new file mode 100644
index 0000000..f52ea74
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_cast_disabled_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_cast_enabled.png b/ash/resources/default_200_percent/cros/status/status_cast_enabled.png
new file mode 100644
index 0000000..be30650
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_cast_enabled.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_cast_enabled_hover.png b/ash/resources/default_200_percent/cros/status/status_cast_enabled_hover.png
new file mode 100644
index 0000000..be30650
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_cast_enabled_hover.png
Binary files differ
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc
index 21651b4..06d6dd4 100644
--- a/ash/shelf/shelf_view.cc
+++ b/ash/shelf/shelf_view.cc
@@ -20,7 +20,6 @@
 #include "ash/shelf/shelf_constants.h"
 #include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_icon_observer.h"
-#include "ash/shelf/shelf_item_delegate.h"
 #include "ash/shelf/shelf_item_delegate_manager.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_menu_model.h"
@@ -309,16 +308,6 @@
   }
 }
 
-void RecordIconActivatedAction(const ui::Event& event) {
-  if (event.IsMouseEvent()) {
-    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
-        UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE);
-  } else if (event.IsGestureEvent()) {
-    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
-        UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH);
-  }
-}
-
 }  // namespace
 
 // AnimationDelegate used when deleting an item. This steadily decreased the
@@ -1693,7 +1682,7 @@
 
   if (sender == overflow_button_) {
     ToggleOverflowBubble();
-    RecordIconActivatedAction(event);
+    RecordIconActivatedSource(event);
     return;
   }
 
@@ -1752,21 +1741,44 @@
         break;
     }
 
-    RecordIconActivatedAction(event);
+    RecordIconActivatedSource(event);
 
-    switch (item_manager_->GetShelfItemDelegate(model_->items()[view_index].id)
-                ->ItemSelected(event)) {
-      case ShelfItemDelegate::kNoAction:
-      case ShelfItemDelegate::kExistingWindowActivated:
-      case ShelfItemDelegate::kExistingWindowMinimized:
-      case ShelfItemDelegate::kAppListMenuShown:
-        ShowListMenuForView(model_->items()[view_index], sender, event);
-        break;
-      case ShelfItemDelegate::kNewWindowCreated:
-        Shell::GetInstance()->metrics()->RecordUserMetricsAction(
-            UMA_LAUNCHER_LAUNCH_TASK);
-        break;
-    }
+    ShelfItemDelegate::PerformedAction performed_action =
+        item_manager_->GetShelfItemDelegate(model_->items()[view_index].id)
+            ->ItemSelected(event);
+
+    RecordIconActivatedAction(performed_action);
+
+    if (performed_action != ShelfItemDelegate::kNewWindowCreated)
+      ShowListMenuForView(model_->items()[view_index], sender, event);
+  }
+}
+
+void ShelfView::RecordIconActivatedSource(const ui::Event& event) {
+  if (event.IsMouseEvent()) {
+    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
+        UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE);
+  } else if (event.IsGestureEvent()) {
+    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
+        UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH);
+  }
+}
+
+void ShelfView::RecordIconActivatedAction(
+    ShelfItemDelegate::PerformedAction performed_action) {
+  switch (performed_action) {
+    case ShelfItemDelegate::kNoAction:
+    case ShelfItemDelegate::kExistingWindowMinimized:
+    case ShelfItemDelegate::kAppListMenuShown:
+      break;
+    case ShelfItemDelegate::kNewWindowCreated:
+      Shell::GetInstance()->metrics()->RecordUserMetricsAction(
+          UMA_LAUNCHER_LAUNCH_TASK);
+      break;
+    case ShelfItemDelegate::kExistingWindowActivated:
+      Shell::GetInstance()->metrics()->RecordUserMetricsAction(
+          UMA_LAUNCHER_SWITCH_TASK);
+      break;
   }
 }
 
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h
index 037922e..56dd95bc 100644
--- a/ash/shelf/shelf_view.h
+++ b/ash/shelf/shelf_view.h
@@ -5,10 +5,12 @@
 #ifndef ASH_SHELF_SHELF_VIEW_H_
 #define ASH_SHELF_SHELF_VIEW_H_
 
+#include <string>
 #include <utility>
 #include <vector>
 
 #include "ash/shelf/shelf_button_host.h"
+#include "ash/shelf/shelf_item_delegate.h"
 #include "ash/shelf/shelf_model_observer.h"
 #include "ash/wm/gestures/shelf_gesture_handler.h"
 #include "base/observer_list.h"
@@ -276,6 +278,13 @@
   // Overridden from views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
+  // Records UMA statistics for the input source when an icon was activated.
+  void RecordIconActivatedSource(const ui::Event& event);
+
+  // Records UMA statistics for the action performed by activating an icon.
+  void RecordIconActivatedAction(
+      ShelfItemDelegate::PerformedAction performed_action);
+
   // Show the list of all running items for this |item|. It will return true
   // when the menu was shown and false if there were no possible items to
   // choose from. |source| specifies the view which is responsible for showing
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index 39afb9a..beb6620 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -34,6 +34,8 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/user_action_tester.h"
+#include "base/time/time.h"
 #include "ui/aura/test/aura_test_base.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -43,6 +45,7 @@
 #include "ui/events/event_constants.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/test/event_generator.h"
+#include "ui/gfx/geometry/point.h"
 #include "ui/views/view_model.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -121,14 +124,21 @@
 // TestShelfItemDelegate which tracks whether it gets selected.
 class ShelfItemSelectionTracker : public TestShelfItemDelegate {
  public:
-  ShelfItemSelectionTracker() : TestShelfItemDelegate(NULL), selected_(false) {
-  }
+  ShelfItemSelectionTracker()
+      : TestShelfItemDelegate(NULL),
+        selected_(false),
+        item_selected_action_(kNoAction) {}
 
   ~ShelfItemSelectionTracker() override {}
 
   // Resets to the initial state.
   void Reset() { selected_ = false; }
 
+  void set_item_selected_action(
+      ShelfItemDelegate::PerformedAction item_selected_action) {
+    item_selected_action_ = item_selected_action;
+  }
+
   // Returns true if the delegate was selected.
   bool WasSelected() {
     return selected_;
@@ -138,12 +148,15 @@
   ShelfItemDelegate::PerformedAction ItemSelected(
       const ui::Event& event) override {
     selected_ = true;
-    return kNoAction;
+    return item_selected_action_;
   }
 
  private:
   bool selected_;
 
+  // The action returned from ItemSelected(const ui::Event&).
+  ShelfItemDelegate::PerformedAction item_selected_action_;
+
   DISALLOW_COPY_AND_ASSIGN(ShelfItemSelectionTracker);
 };
 
@@ -1762,6 +1775,82 @@
   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
 }
 
+// Verifies that Launcher_ButtonPressed_* UMA user actions are recorded when an
+// item is selected.
+TEST_F(ShelfViewTest,
+       Launcher_ButtonPressedUserActionsRecordedWhenItemSelected) {
+  base::UserActionTester user_action_tester;
+
+  ShelfID browser_shelf_id = model_->items()[browser_index_].id;
+  ShelfItemSelectionTracker* selection_tracker = new ShelfItemSelectionTracker;
+  item_manager_->SetShelfItemDelegate(
+      browser_shelf_id,
+      scoped_ptr<ShelfItemDelegate>(selection_tracker).Pass());
+
+  SimulateClick(browser_index_);
+  EXPECT_EQ(1,
+            user_action_tester.GetActionCount("Launcher_ButtonPressed_Mouse"));
+}
+
+// Verifies that Launcher_*Task UMA user actions are recorded when an item is
+// selected.
+TEST_F(ShelfViewTest, Launcher_TaskUserActionsRecordedWhenItemSelected) {
+  base::UserActionTester user_action_tester;
+
+  ShelfID browser_shelf_id = model_->items()[browser_index_].id;
+  ShelfItemSelectionTracker* selection_tracker = new ShelfItemSelectionTracker;
+  selection_tracker->set_item_selected_action(
+      ShelfItemDelegate::kNewWindowCreated);
+  item_manager_->SetShelfItemDelegate(
+      browser_shelf_id,
+      scoped_ptr<ShelfItemDelegate>(selection_tracker).Pass());
+
+  SimulateClick(browser_index_);
+  EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_LaunchTask"));
+}
+
+// Verifies that a Launcher_ButtonPressed_Mouse UMA user action is recorded when
+// an icon is activated by a mouse event.
+TEST_F(ShelfViewTest,
+       Launcher_ButtonPressed_MouseIsRecordedWhenIconActivatedByMouse) {
+  base::UserActionTester user_action_tester;
+  ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
+                             base::TimeDelta(), 0, 0);
+  test_api_->RecordIconActivatedSource(mouse_event);
+  EXPECT_EQ(1,
+            user_action_tester.GetActionCount("Launcher_ButtonPressed_Mouse"));
+}
+
+// Verifies that a Launcher_ButtonPressed_Touch UMA user action is recorded when
+// an icon is activated by a touch event.
+TEST_F(ShelfViewTest,
+       Launcher_ButtonPressed_MouseIsRecordedWhenIconActivatedByTouch) {
+  base::UserActionTester user_action_tester;
+  ui::TouchEvent touch_event(ui::ET_GESTURE_TAP, gfx::Point(), 0,
+                             base::TimeDelta());
+  test_api_->RecordIconActivatedSource(touch_event);
+  EXPECT_EQ(1,
+            user_action_tester.GetActionCount("Launcher_ButtonPressed_Touch"));
+}
+
+// Verifies that a Launcher_LaunchTask UMA user action is recorded when
+// selecting an icon causes a new window to be created.
+TEST_F(ShelfViewTest, Launcher_LaunchTaskIsRecordedWhenNewWindowIsCreated) {
+  base::UserActionTester user_action_tester;
+  test_api_->RecordIconActivatedAction(ShelfItemDelegate::kNewWindowCreated);
+  EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_LaunchTask"));
+}
+
+// Verifies that a Launcher_SwitchTask UMA user action is recorded when
+// selecting an icon causes an existing window to be activated.
+TEST_F(ShelfViewTest,
+       Launcher_SwitchTaskIsRecordedWhenExistingWindowIsActivated) {
+  base::UserActionTester user_action_tester;
+  test_api_->RecordIconActivatedAction(
+      ShelfItemDelegate::kExistingWindowActivated);
+  EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_SwitchTask"));
+}
+
 class ShelfViewVisibleBoundsTest : public ShelfViewTest,
                                    public testing::WithParamInterface<bool> {
  public:
diff --git a/ash/system/chromeos/brightness/tray_brightness.cc b/ash/system/chromeos/brightness/tray_brightness.cc
index e874ccf..3e8b330 100644
--- a/ash/system/chromeos/brightness/tray_brightness.cc
+++ b/ash/system/chromeos/brightness/tray_brightness.cc
@@ -8,7 +8,6 @@
 
 #include "ash/accelerators/accelerator_controller.h"
 #include "ash/ash_constants.h"
-#include "ash/display/display_manager.h"
 #include "ash/metrics/user_metrics_recorder.h"
 #include "ash/shell.h"
 #include "ash/shell_observer.h"
@@ -26,6 +25,7 @@
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/display.h"
 #include "ui/gfx/image/image.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/image_view.h"
@@ -273,7 +273,7 @@
   // Never show the bubble on systems that lack internal displays: if an
   // external display's brightness is changed, it may already display the new
   // level via an on-screen display.
-  if (!Shell::GetInstance()->display_manager()->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return;
 
   if (brightness_view_)
diff --git a/ash/system/chromeos/tray_display.cc b/ash/system/chromeos/tray_display.cc
index 10f9ede..aaeead2 100644
--- a/ash/system/chromeos/tray_display.cc
+++ b/ash/system/chromeos/tray_display.cc
@@ -52,9 +52,9 @@
 
   // We don't show display size for mirrored display. Fallback
   // to empty string if this happens on release build.
-  bool mirrored_display = display_manager->mirrored_display_id() == display_id;
-  DCHECK(!mirrored_display);
-  if (mirrored_display)
+  bool mirroring = display_manager->mirroring_display_id() == display_id;
+  DCHECK(!mirroring);
+  if (mirroring)
     return base::string16();
 
   DCHECK(display->is_valid());
@@ -66,7 +66,7 @@
 base::string16 GetDisplayInfoLine(int64 display_id) {
   const DisplayInfo& display_info =
       GetDisplayManager()->GetDisplayInfo(display_id);
-  if (GetDisplayManager()->mirrored_display_id() == display_id)
+  if (GetDisplayManager()->mirroring_display_id() == display_id)
     return GetDisplayName(display_id);
 
   base::string16 size_text = GetDisplaySize(display_id);
@@ -92,9 +92,9 @@
   std::vector<base::string16> lines;
   int64 internal_id = gfx::Display::kInvalidDisplayID;
   // Make sure to show the internal display first.
-  if (display_manager->HasInternalDisplay() &&
-      display_manager->IsInternalDisplayId(
-          display_manager->first_display_id())) {
+  if (gfx::Display::HasInternalDisplay() &&
+      gfx::Display::InternalDisplayId() ==
+          display_manager->first_display_id()) {
     internal_id = display_manager->first_display_id();
     lines.push_back(GetDisplayInfoLine(internal_id));
   }
@@ -186,7 +186,7 @@
   // mirroring.
   static base::string16 GetExternalDisplayName() {
     DisplayManager* display_manager = GetDisplayManager();
-    DCHECK(!display_manager->IsMirrored());
+    DCHECK(!display_manager->IsInMirrorMode());
 
     int64 external_id = gfx::Display::kInvalidDisplayID;
     for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
@@ -228,7 +228,7 @@
       base::string16* additional_message_out) {
     DisplayManager* display_manager = GetDisplayManager();
     if (display_manager->GetNumDisplays() > 1) {
-      if (GetDisplayManager()->HasInternalDisplay()) {
+      if (gfx::Display::HasInternalDisplay()) {
         return l10n_util::GetStringFUTF16(
             IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName());
       }
@@ -236,19 +236,19 @@
           IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL);
     }
 
-    if (display_manager->IsMirrored()) {
-      if (GetDisplayManager()->HasInternalDisplay()) {
+    if (display_manager->IsInMirrorMode()) {
+      if (gfx::Display::HasInternalDisplay()) {
         return l10n_util::GetStringFUTF16(
             IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
-            GetDisplayName(display_manager->mirrored_display_id()));
+            GetDisplayName(display_manager->mirroring_display_id()));
       }
       return l10n_util::GetStringUTF16(
           IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL);
     }
 
     int64 primary_id = Shell::GetScreen()->GetPrimaryDisplay().id();
-    if (display_manager->HasInternalDisplay() &&
-        !display_manager->IsInternalDisplayId(primary_id)) {
+    if (gfx::Display::HasInternalDisplay() &&
+        !(gfx::Display::InternalDisplayId() == primary_id)) {
       if (additional_message_out) {
         *additional_message_out = l10n_util::GetStringUTF16(
             IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED_DESCRIPTION);
diff --git a/ash/system/chromeos/tray_display_unittest.cc b/ash/system/chromeos/tray_display_unittest.cc
index d2a1641..e289fa24 100644
--- a/ash/system/chromeos/tray_display_unittest.cc
+++ b/ash/system/chromeos/tray_display_unittest.cc
@@ -65,10 +65,10 @@
           ScreenUtil::GetSecondaryDisplay().id()));
 }
 
-base::string16 GetMirroredDisplayName() {
+base::string16 GetMirroringDisplayName() {
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   return base::UTF8ToUTF16(display_manager->GetDisplayNameForId(
-      display_manager->mirrored_display_id()));
+      display_manager->mirroring_display_id()));
 }
 
 class TrayDisplayTest : public ash::test::AshTestBase {
@@ -228,8 +228,8 @@
   tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
   EXPECT_TRUE(IsDisplayVisibleInTray());
 
-  expected = l10n_util::GetStringFUTF16(
-      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName());
+  expected = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
+                                        GetMirroringDisplayName());
   EXPECT_EQ(expected, GetTrayDisplayText());
   EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "400x400"),
             GetTrayDisplayTooltipText());
@@ -270,8 +270,8 @@
   UpdateDisplay("400x400@1.5,200x200");
   tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
   EXPECT_TRUE(IsDisplayVisibleInTray());
-  expected = l10n_util::GetStringFUTF16(
-      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName());
+  expected = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
+                                        GetMirroringDisplayName());
   EXPECT_EQ(expected, GetTrayDisplayText());
   EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "600x600"),
             GetTrayDisplayTooltipText());
@@ -325,8 +325,8 @@
   UpdateDisplay("400x400,200x200@1.5");
   tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
   EXPECT_TRUE(IsDisplayVisibleInTray());
-  expected = l10n_util::GetStringFUTF16(
-      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName());
+  expected = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
+                                        GetMirroringDisplayName());
   EXPECT_EQ(expected, GetTrayDisplayText());
   EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "400x400"),
             GetTrayDisplayTooltipText());
@@ -480,10 +480,9 @@
   CloseNotification();
   display_manager->SetSoftwareMirroring(true);
   UpdateDisplay("400x400,200x200");
-  EXPECT_EQ(
-      l10n_util::GetStringFUTF16(
-          IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName()),
-      GetDisplayNotificationText());
+  EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
+                                       GetMirroringDisplayName()),
+            GetDisplayNotificationText());
   EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
 
   // Back to extended.
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc
index 8a6fc5e..516a5ba 100644
--- a/ash/system/overview/overview_button_tray_unittest.cc
+++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -4,8 +4,10 @@
 
 #include "ash/system/overview/overview_button_tray.h"
 
+#include "ash/ash_switches.h"
 #include "ash/display/display_manager.h"
 #include "ash/root_window_controller.h"
+#include "ash/rotator/screen_rotation_animator.h"
 #include "ash/shelf/shelf_types.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
@@ -15,7 +17,9 @@
 #include "ash/test/status_area_widget_test_helper.h"
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
 #include "ash/wm/overview/window_selector_controller.h"
+#include "base/command_line.h"
 #include "base/time/time.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/events/event.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/gestures/gesture_types.h"
@@ -42,6 +46,8 @@
   OverviewButtonTrayTest() {}
   ~OverviewButtonTrayTest() override {}
 
+  void SetUp() override;
+
  protected:
   views::ImageView* GetImageView(OverviewButtonTray* tray) {
     return tray->icon_;
@@ -51,6 +57,14 @@
   DISALLOW_COPY_AND_ASSIGN(OverviewButtonTrayTest);
 };
 
+void OverviewButtonTrayTest::SetUp() {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kAshUseFirstDisplayAsInternal);
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kAshEnableScreenRotationAnimation);
+  AshTestBase::SetUp();
+}
+
 // Ensures that creation doesn't cause any crashes and adds the image icon.
 TEST_F(OverviewButtonTrayTest, BasicConstruction) {
   EXPECT_TRUE(GetImageView(GetTray()) != NULL);
@@ -156,4 +170,29 @@
   EXPECT_FALSE(GetTray()->draw_background_as_active());
 }
 
+// Test that when a hide animation is aborted via deletion, that the
+// OverviewButton is still hidden.
+TEST_F(OverviewButtonTrayTest, HideAnimationAlwaysCompletes) {
+  Shell::GetInstance()
+      ->maximize_mode_controller()
+      ->EnableMaximizeModeWindowManager(true);
+
+  // Long duration for hide animation, to allow it to be interrupted.
+  scoped_ptr<ui::ScopedAnimationDurationScaleMode> hide_duration(
+      new ui::ScopedAnimationDurationScaleMode(
+          ui::ScopedAnimationDurationScaleMode::SLOW_DURATION));
+  GetTray()->SetVisible(false);
+
+  // ScreenRotationAnimator copies the current layers, and deletes them upon
+  // completion. Allow its animation to complete first.
+  scoped_ptr<ui::ScopedAnimationDurationScaleMode> rotate_duration(
+      new ui::ScopedAnimationDurationScaleMode(
+          ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
+  ash::ScreenRotationAnimator(gfx::Display::InternalDisplayId())
+      .Rotate(gfx::Display::ROTATE_270);
+
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(GetTray()->visible());
+}
+
 }  // namespace ash
diff --git a/ash/system/system_notifier.cc b/ash/system/system_notifier.cc
index 6ff6dcb..c762930 100644
--- a/ash/system/system_notifier.cc
+++ b/ash/system/system_notifier.cc
@@ -27,6 +27,7 @@
     kNotifierDisplayError,
 #if defined(OS_CHROMEOS)
     ui::NetworkStateNotifier::kNotifierNetworkError,
+    kNotifierOobeScreen,
 #endif
     kNotifierPower,
     // Note: Order doesn't matter here, so keep this in alphabetic order, don't
@@ -76,6 +77,7 @@
 const char kNotifierLocale[] = "ash.locale";
 const char kNotifierMultiProfileFirstRun[] = "ash.multi-profile.first-run";
 const char kNotifierNetworkPortalDetector[] = "ash.network.portal-detector";
+const char kNotifierOobeScreen[] = "ash.oobe-screen";
 const char kNotifierPower[] = "ash.power";
 const char kNotifierScreenshot[] = "ash.screenshot";
 const char kNotifierScreenCapture[] = "ash.screen-capture";
diff --git a/ash/system/system_notifier.h b/ash/system/system_notifier.h
index 9461389..540f328 100644
--- a/ash/system/system_notifier.h
+++ b/ash/system/system_notifier.h
@@ -24,6 +24,7 @@
 ASH_EXPORT extern const char kNotifierNetwork[];
 ASH_EXPORT extern const char kNotifierNetworkError[];
 ASH_EXPORT extern const char kNotifierNetworkPortalDetector[];
+ASH_EXPORT extern const char kNotifierOobeScreen[];
 ASH_EXPORT extern const char kNotifierPower[];
 ASH_EXPORT extern const char kNotifierScreenshot[];
 ASH_EXPORT extern const char kNotifierScreenCapture[];
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc
index 9b4afd3..53e116f0 100644
--- a/ash/system/tray/tray_background_view.cc
+++ b/ash/system/tray/tray_background_view.cc
@@ -256,6 +256,7 @@
 TrayBackgroundView::~TrayBackgroundView() {
   if (GetWidget())
     GetWidget()->RemoveObserver(widget_observer_.get());
+  StopObservingImplicitAnimations();
 }
 
 void TrayBackgroundView::Initialize() {
@@ -439,6 +440,15 @@
   views::View::SetVisible(false);
 }
 
+bool TrayBackgroundView::RequiresNotificationWhenAnimatorDestroyed() const {
+  // This is needed so that OnImplicitAnimationsCompleted() is called even upon
+  // destruction of the animator. This can occure when parallel animations
+  // caused by ScreenRotationAnimator end before the animations of
+  // TrayBackgroundView. This allows for a proper update to the visual state of
+  // the view. (crbug.com/476667)
+  return true;
+}
+
 void TrayBackgroundView::HideTransformation() {
   gfx::Transform transform;
   if (shelf_alignment_ == SHELF_ALIGNMENT_BOTTOM ||
diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h
index b424cfc..f1562b7 100644
--- a/ash/system/tray/tray_background_view.h
+++ b/ash/system/tray/tray_background_view.h
@@ -158,6 +158,7 @@
 
   // ui::ImplicitAnimationObserver:
   void OnImplicitAnimationsCompleted() override;
+  bool RequiresNotificationWhenAnimatorDestroyed() const override;
 
   // Applies transformations to the |layer()| to animate the view when
   // SetVisible(false) is called.
diff --git a/ash/system/win/audio/tray_audio_delegate_win.h b/ash/system/win/audio/tray_audio_delegate_win.h
index a299b7d..9ab0208 100644
--- a/ash/system/win/audio/tray_audio_delegate_win.h
+++ b/ash/system/win/audio/tray_audio_delegate_win.h
@@ -18,18 +18,18 @@
 
 class ASH_EXPORT TrayAudioDelegateWin : public TrayAudioDelegate {
  public:
-  virtual ~TrayAudioDelegateWin() {}
+  ~TrayAudioDelegateWin() override {}
 
   // Overridden from TrayAudioDelegate.
-  virtual void AdjustOutputVolumeToAudibleLevel() override;
-  virtual int GetOutputDefaultVolumeMuteLevel() override;
-  virtual int GetOutputVolumeLevel() override;
-  virtual int GetActiveOutputDeviceIconId() override;
-  virtual bool HasAlternativeSources() override;
-  virtual bool IsOutputAudioMuted() override;
-  virtual void SetOutputAudioIsMuted(bool is_muted) override;
-  virtual void SetOutputVolumeLevel(int level) override;
-  virtual void SetInternalSpeakerChannelMode(AudioChannelMode mode) override;
+  void AdjustOutputVolumeToAudibleLevel() override;
+  int GetOutputDefaultVolumeMuteLevel() override;
+  int GetOutputVolumeLevel() override;
+  int GetActiveOutputDeviceIconId() override;
+  bool HasAlternativeSources() override;
+  bool IsOutputAudioMuted() override;
+  void SetOutputAudioIsMuted(bool is_muted) override;
+  void SetOutputVolumeLevel(int level) override;
+  void SetInternalSpeakerChannelMode(AudioChannelMode mode) override;
 
  private:
   base::win::ScopedComPtr<ISimpleAudioVolume> CreateDefaultVolumeControl();
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index ef7fba3..6e6f78d 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -214,8 +214,7 @@
   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   DisplayManagerTestApi display_manager_test_api(display_manager);
   display_manager_test_api.UpdateDisplay(display_specs);
-  if (display_manager->HasSoftwareMirroringDisplay())
-    RunAllPendingInMessageLoop();
+  display_manager->RunPendingTasksForTest();
 }
 
 aura::Window* AshTestBase::CurrentContext() {
diff --git a/ash/test/display_manager_test_api.cc b/ash/test/display_manager_test_api.cc
index 9bed696..87326ee 100644
--- a/ash/test/display_manager_test_api.cc
+++ b/ash/test/display_manager_test_api.cc
@@ -82,7 +82,7 @@
 }
 
 int64 DisplayManagerTestApi::SetFirstDisplayAsInternalDisplay() {
-  const gfx::Display& internal = display_manager_->displays_[0];
+  const gfx::Display& internal = display_manager_->active_display_list_[0];
   SetInternalDisplayId(internal.id());
   return gfx::Display::InternalDisplayId();
 }
diff --git a/ash/test/shelf_view_test_api.cc b/ash/test/shelf_view_test_api.cc
index b829b87d5..715b986c 100644
--- a/ash/test/shelf_view_test_api.cc
+++ b/ash/test/shelf_view_test_api.cc
@@ -118,6 +118,15 @@
   return shelf_view_->ButtonPressed(sender, event);
 }
 
+void ShelfViewTestAPI::RecordIconActivatedSource(const ui::Event& event) {
+  shelf_view_->RecordIconActivatedSource(event);
+}
+
+void ShelfViewTestAPI::RecordIconActivatedAction(
+    ShelfItemDelegate::PerformedAction performed_action) {
+  shelf_view_->RecordIconActivatedAction(performed_action);
+}
+
 bool ShelfViewTestAPI::SameDragType(ShelfItemType typea,
                                     ShelfItemType typeb) const {
   return shelf_view_->SameDragType(typea, typeb);
diff --git a/ash/test/shelf_view_test_api.h b/ash/test/shelf_view_test_api.h
index 7916ea7..04e5d40 100644
--- a/ash/test/shelf_view_test_api.h
+++ b/ash/test/shelf_view_test_api.h
@@ -5,6 +5,7 @@
 #ifndef ASH_TEST_SHELF_VIEW_TEST_API_H_
 #define ASH_TEST_SHELF_VIEW_TEST_API_H_
 
+#include "ash/shelf/shelf_item_delegate.h"
 #include "ash/shelf/shelf_item_types.h"
 #include "base/basictypes.h"
 
@@ -81,6 +82,14 @@
   // Wrapper for ShelfView::ButtonPressed.
   void ButtonPressed(views::Button* sender, const ui::Event& event);
 
+  // Wrapper for ShelfView::RecordIconActivatedSource(const ui::Event&).
+  void RecordIconActivatedSource(const ui::Event& event);
+
+  // Wrapper for ShelfView::RecordIconActivatedAction(
+  // ShelfItemDelegate::PerformedAction).
+  void RecordIconActivatedAction(
+      ShelfItemDelegate::PerformedAction performed_action);
+
   // Wrapper for ShelfView::SameDragType.
   bool SameDragType(ShelfItemType typea, ShelfItemType typeb) const;
 
diff --git a/ash/test/test_metro_viewer_process_host.h b/ash/test/test_metro_viewer_process_host.h
index bb393515..a25095ef 100644
--- a/ash/test/test_metro_viewer_process_host.h
+++ b/ash/test/test_metro_viewer_process_host.h
@@ -17,7 +17,7 @@
  public:
   TestMetroViewerProcessHost(
       const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner);
-  virtual ~TestMetroViewerProcessHost();
+  ~TestMetroViewerProcessHost() override;
 
   bool closed_unexpectedly() { return closed_unexpectedly_; }
 
@@ -27,13 +27,12 @@
 
  private:
   // win8::MetroViewerProcessHost implementation
-  virtual void OnChannelError() override;
-  virtual void OnSetTargetSurface(gfx::NativeViewId target_surface,
-                                  float device_scale) override;
-  virtual void OnOpenURL(const base::string16& url) override;
-  virtual void OnHandleSearchRequest(
-      const base::string16& search_string) override;
-  virtual void OnWindowSizeChanged(uint32 width, uint32 height) override;
+  void OnChannelError() override;
+  void OnSetTargetSurface(gfx::NativeViewId target_surface,
+                          float device_scale) override;
+  void OnOpenURL(const base::string16& url) override;
+  void OnHandleSearchRequest(const base::string16& search_string) override;
+  void OnWindowSizeChanged(uint32 width, uint32 height) override;
 
   bool closed_unexpectedly_;
 
diff --git a/ash/touch/touch_transformer_controller.cc b/ash/touch/touch_transformer_controller.cc
index 8adb644..d2582c0 100644
--- a/ash/touch/touch_transformer_controller.cc
+++ b/ash/touch/touch_transformer_controller.cc
@@ -174,7 +174,7 @@
   gfx::Size fb_size =
       Shell::GetInstance()->display_configurator()->framebuffer_size();
 
-  if (display_manager->IsMirrored()) {
+  if (display_manager->IsInMirrorMode()) {
     if (GetDisplayManager()->software_mirroring_enabled()) {
       // In extended but software mirroring mode, there is a WindowTreeHost for
       // each display, but all touches are forwarded to the primary root
diff --git a/ash/wm/drag_window_resizer.cc b/ash/wm/drag_window_resizer.cc
index 1cb72e2..948137e 100644
--- a/ash/wm/drag_window_resizer.cc
+++ b/ash/wm/drag_window_resizer.cc
@@ -57,8 +57,7 @@
   if (window_state_)
     window_state_->DeleteDragDetails();
   Shell* shell = Shell::GetInstance();
-  shell->mouse_cursor_filter()->set_mouse_warp_mode(
-      MouseCursorEventFilter::WARP_ALWAYS);
+  shell->mouse_cursor_filter()->set_mouse_warp_enabled(true);
   shell->mouse_cursor_filter()->HideSharedEdgeIndicator();
   if (instance_ == this)
     instance_ = NULL;
@@ -156,9 +155,7 @@
   // window/tab to another display.
   MouseCursorEventFilter* mouse_cursor_filter =
       Shell::GetInstance()->mouse_cursor_filter();
-  mouse_cursor_filter->set_mouse_warp_mode(
-      ShouldAllowMouseWarp() ?
-      MouseCursorEventFilter::WARP_DRAG : MouseCursorEventFilter::WARP_NONE);
+  mouse_cursor_filter->set_mouse_warp_enabled(ShouldAllowMouseWarp());
   if (ShouldAllowMouseWarp())
     mouse_cursor_filter->ShowSharedEdgeIndicator(GetTarget()->GetRootWindow());
   instance_ = this;
diff --git a/ash/wm/drag_window_resizer_unittest.cc b/ash/wm/drag_window_resizer_unittest.cc
index 7429254..c5c5be5e 100644
--- a/ash/wm/drag_window_resizer_unittest.cc
+++ b/ash/wm/drag_window_resizer_unittest.cc
@@ -427,49 +427,40 @@
   ASSERT_TRUE(event_filter);
   window_->SetBounds(gfx::Rect(0, 0, 50, 60));
 
-  EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
-            event_filter->mouse_warp_mode_);
+  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
   {
     scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
         window_.get(), gfx::Point(), HTCAPTION));
     // While dragging a window, warp should be allowed.
-    EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG,
-              event_filter->mouse_warp_mode_);
+    EXPECT_TRUE(event_filter->mouse_warp_enabled_);
     resizer->CompleteDrag();
   }
-  EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
-            event_filter->mouse_warp_mode_);
+  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
 
   {
     scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
         window_.get(), gfx::Point(), HTCAPTION));
-    EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG,
-              event_filter->mouse_warp_mode_);
+    EXPECT_TRUE(event_filter->mouse_warp_enabled_);
     resizer->RevertDrag();
   }
-  EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
-            event_filter->mouse_warp_mode_);
+  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
 
   {
     scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
         window_.get(), gfx::Point(), HTRIGHT));
     // While resizing a window, warp should NOT be allowed.
-    EXPECT_EQ(MouseCursorEventFilter::WARP_NONE,
-              event_filter->mouse_warp_mode_);
+    EXPECT_FALSE(event_filter->mouse_warp_enabled_);
     resizer->CompleteDrag();
   }
-  EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
-            event_filter->mouse_warp_mode_);
+  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
 
   {
     scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
         window_.get(), gfx::Point(), HTRIGHT));
-    EXPECT_EQ(MouseCursorEventFilter::WARP_NONE,
-              event_filter->mouse_warp_mode_);
+    EXPECT_FALSE(event_filter->mouse_warp_enabled_);
     resizer->RevertDrag();
   }
-  EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
-            event_filter->mouse_warp_mode_);
+  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
 }
 
 // Verifies cursor's device scale factor is updated whe a window is moved across
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 8a7acc4..7750eeec 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -91,6 +91,8 @@
     "android/important_file_writer_android.h",
     "android/java_handler_thread.cc",
     "android/java_handler_thread.h",
+    "android/java_runtime.cc",
+    "android/java_runtime.h",
     "android/jni_android.cc",
     "android/jni_android.h",
     "android/jni_array.cc",
@@ -1410,9 +1412,20 @@
       "android/java/src/org/chromium/base/metrics/RecordHistogram.java",
       "android/java/src/org/chromium/base/metrics/RecordUserAction.java",
     ]
+
+    deps = [
+      ":android_runtime_jni_headers",
+    ]
+
     jni_package = "base"
   }
 
+  # GYP: //base.gyp:android_runtime_jni_headers
+  generate_jar_jni("android_runtime_jni_headers") {
+    jni_package = "base"
+    classes = [ "java/lang/Runtime.class" ]
+  }
+
   # GYP: //base.gyp:base_java
   android_library("base_java") {
     srcjar_deps = [
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index 46781e8..43ba635 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -14,6 +14,7 @@
 #include "base/android/field_trial_list.h"
 #include "base/android/important_file_writer_android.h"
 #include "base/android/java_handler_thread.h"
+#include "base/android/java_runtime.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_registrar.h"
 #include "base/android/jni_utils.h"
@@ -57,6 +58,7 @@
     {"PowerMonitor", base::RegisterPowerMonitor},
     {"RecordHistogram", base::android::RegisterRecordHistogram},
     {"RecordUserAction", base::android::RegisterRecordUserAction},
+    {"Runtime", base::android::JavaRuntime::Register},
     {"SystemMessageHandler", base::MessagePumpForUI::RegisterBindings},
     {"SysUtils", base::android::SysUtils::Register},
     {"ThreadUtils", base::RegisterThreadUtils},
diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java
index bcd850c..5da080e 100644
--- a/base/android/java/src/org/chromium/base/PathUtils.java
+++ b/base/android/java/src/org/chromium/base/PathUtils.java
@@ -16,8 +16,6 @@
  */
 public abstract class PathUtils {
 
-    private static String sDataDirectorySuffix;
-
     private static final int DATA_DIRECTORY = 0;
     private static final int DATABASE_DIRECTORY = 1;
     private static final int CACHE_DIRECTORY = 2;
@@ -28,30 +26,14 @@
     private PathUtils() {}
 
     /**
-     * Sets the suffix that should be used for the directory where private data is to be stored
-     * by the application.
-     *
-     * TODO(wnwen): Remove this after all clients have migrated and add asserts for not null.
-     *
-     * @param suffix The private data directory suffix.
-     * @see Context#getDir(String, int)
-     * @deprecated
-     */
-    @Deprecated
-    public static void setPrivateDataDirectorySuffix(String suffix) {
-        sDirPathFetchTask = null;
-        sDataDirectorySuffix = suffix;
-    }
-
-    /**
      * Starts an asynchronous task to fetch the path of the directory where private data is to be
      * stored by the application.
      *
      * @param suffix The private data directory suffix.
      * @see Context#getDir(String, int)
      */
-    public static void setPrivateDataDirectorySuffix(String suffix, final Context appContext) {
-        sDataDirectorySuffix = null;
+    public static void setPrivateDataDirectorySuffix(String suffix, Context context) {
+        final Context appContext = context.getApplicationContext();
         sDirPathFetchTask = new AsyncTask<String, Void, String[]>() {
             @Override
             protected String[] doInBackground(String... dataDirectorySuffix) {
@@ -83,15 +65,8 @@
      */
     @CalledByNative
     public static String getDataDirectory(Context appContext) {
-        if (sDataDirectorySuffix == null && sDirPathFetchTask == null) {
-            throw new IllegalStateException(
-                    "setDataDirectorySuffix must be called before getDataDirectory");
-        } else if (sDirPathFetchTask != null) {
-            return getDirectoryPath(DATA_DIRECTORY);
-        } else {
-            // Temporarily allow UI thread directory fetching until all callers have been migrated.
-            return appContext.getDir(sDataDirectorySuffix, Context.MODE_PRIVATE).getPath();
-        }
+        assert sDirPathFetchTask != null : "setDataDirectorySuffix must be called first.";
+        return getDirectoryPath(DATA_DIRECTORY);
     }
 
     /**
@@ -99,11 +74,8 @@
      */
     @CalledByNative
     public static String getDatabaseDirectory(Context appContext) {
-        if (sDirPathFetchTask != null) {
-            return getDirectoryPath(DATABASE_DIRECTORY);
-        }
-        // Context.getDatabasePath() returns path for the provided filename.
-        return appContext.getDatabasePath("foo").getParent();
+        assert sDirPathFetchTask != null : "setDataDirectorySuffix must be called first.";
+        return getDirectoryPath(DATABASE_DIRECTORY);
     }
 
     /**
@@ -112,10 +84,8 @@
     @SuppressWarnings("unused")
     @CalledByNative
     public static String getCacheDirectory(Context appContext) {
-        if (sDirPathFetchTask != null) {
-            return getDirectoryPath(CACHE_DIRECTORY);
-        }
-        return appContext.getCacheDir().getPath();
+        assert sDirPathFetchTask != null : "setDataDirectorySuffix must be called first.";
+        return getDirectoryPath(CACHE_DIRECTORY);
     }
 
     /**
diff --git a/base/android/java_runtime.cc b/base/android/java_runtime.cc
new file mode 100644
index 0000000..5be9adfd
--- /dev/null
+++ b/base/android/java_runtime.cc
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/java_runtime.h"
+
+#include "jni/Runtime_jni.h"
+
+namespace base {
+namespace android {
+
+bool JavaRuntime::Register(JNIEnv* env) {
+  return JNI_Runtime::RegisterNativesImpl(env);
+}
+
+void JavaRuntime::GetMemoryUsage(long* total_memory, long* free_memory) {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  base::android::ScopedJavaLocalRef<jobject> runtime =
+      JNI_Runtime::Java_Runtime_getRuntime(env);
+  *total_memory = JNI_Runtime::Java_Runtime_totalMemory(env, runtime.obj());
+  *free_memory = JNI_Runtime::Java_Runtime_freeMemory(env, runtime.obj());
+}
+
+}  // namespace android
+}  // namespace base
diff --git a/base/android/java_runtime.h b/base/android/java_runtime.h
new file mode 100644
index 0000000..bde4c5c6b
--- /dev/null
+++ b/base/android/java_runtime.h
@@ -0,0 +1,28 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ANDROID_JAVA_RUNTIME_H
+#define BASE_ANDROID_JAVA_RUNTIME_H
+
+#include "base/android/scoped_java_ref.h"
+#include "base/base_export.h"
+
+namespace base {
+namespace android {
+
+// Wrapper class for using the java.lang.Runtime object from jni.
+class BASE_EXPORT JavaRuntime {
+ public:
+  // Registers the jni class (once per process).
+  static bool Register(JNIEnv* env);
+
+  // Fills the total memory used and memory allocated for objects by the java
+  // heap in the current process. Returns true on success.
+  static void GetMemoryUsage(long* total_memory, long* free_memory);
+};
+
+}  // namespace android
+}  // namespace base
+
+#endif  // BASE_ANDROID_JAVA_RUNTIME_H
diff --git a/base/base.gyp b/base/base.gyp
index 4c066a6..325210f 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -1390,9 +1390,22 @@
           'variables': {
             'jni_gen_package': 'base',
           },
+          'dependencies': [
+            'android_runtime_jni_headers',
+          ],
           'includes': [ '../build/jni_generator.gypi' ],
         },
         {
+          # GN: //base:android_runtime_jni_headers
+          'target_name': 'android_runtime_jni_headers',
+          'type': 'none',
+          'variables': {
+            'jni_gen_package': 'base',
+            'input_java_class': 'java/lang/Runtime.class',
+          },
+          'includes': [ '../build/jar_file_jni_generator.gypi' ],
+        },
+        {
           # TODO(GN)
           'target_name': 'base_unittests_jni_headers',
           'type': 'none',
diff --git a/base/base.gypi b/base/base.gypi
index 23f1c8a..a45a387 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -45,6 +45,8 @@
           'android/important_file_writer_android.h',
           'android/java_handler_thread.cc',
           'android/java_handler_thread.h',
+          'android/java_runtime.cc',
+          'android/java_runtime.h',
           'android/jni_android.cc',
           'android/jni_android.h',
           'android/jni_array.cc',
diff --git a/base/base_nacl.gyp b/base/base_nacl.gyp
index 90a2893..40005d2 100644
--- a/base/base_nacl.gyp
+++ b/base/base_nacl.gyp
@@ -39,9 +39,6 @@
               '-fno-strict-aliasing',
             ],
           },
-          'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
-          ],
         },
         {
           'target_name': 'base_i18n_nacl',
@@ -63,7 +60,6 @@
             ],
           },
           'dependencies': [
-            '../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',
@@ -113,7 +109,6 @@
             'rand_util_nacl.cc',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../third_party/libevent/libevent_nacl_nonsfi.gyp:event_nacl_nonsfi',
           ],
         },
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index a30b7756..f885403 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -778,10 +778,10 @@
 
   copies = 0;
   assigns = 0;
-  DerivedCopyCounter dervied(&copies, &assigns);
+  DerivedCopyCounter derived(&copies, &assigns);
   Callback<void(CopyCounter)> coerce_cb =
       Bind(&VoidPolymorphic1<CopyCounter>);
-  coerce_cb.Run(CopyCounter(dervied));
+  coerce_cb.Run(CopyCounter(derived));
   EXPECT_GE(2, copies);
   EXPECT_EQ(0, assigns);
 }
diff --git a/base/chromeos/memory_pressure_monitor_chromeos.h b/base/chromeos/memory_pressure_monitor_chromeos.h
index b2a845d..45855ebc 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos.h
+++ b/base/chromeos/memory_pressure_monitor_chromeos.h
@@ -6,6 +6,7 @@
 #define BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
 
 #include "base/base_export.h"
+#include "base/files/scoped_file.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/memory_pressure_listener.h"
@@ -13,10 +14,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
 
-#if defined (OS_POSIX)
-#include "base/files/scoped_file.h"
-#endif
-
 namespace base {
 
 class TestMemoryPressureMonitor;
@@ -103,10 +100,8 @@
   const int moderate_pressure_threshold_percent_;
   const int critical_pressure_threshold_percent_;
 
-#if defined(OS_POSIX)
   // File descriptor used to detect low memory condition.
   ScopedFD low_mem_file_;
-#endif
 
   base::WeakPtrFactory<MemoryPressureMonitorChromeOS> weak_ptr_factory_;
 
diff --git a/base/command_line.cc b/base/command_line.cc
index 3e143cc5..61ff5c10 100644
--- a/base/command_line.cc
+++ b/base/command_line.cc
@@ -263,7 +263,8 @@
 }
 
 bool CommandLine::HasSwitch(const std::string& switch_string) const {
-  return switches_.find(LowerASCIIOnWindows(switch_string)) != switches_.end();
+  DCHECK_EQ(StringToLowerASCII(switch_string), switch_string);
+  return switches_.find(switch_string) != switches_.end();
 }
 
 bool CommandLine::HasSwitch(const char string_constant[]) const {
diff --git a/base/command_line.h b/base/command_line.h
index 19df40c..439921e 100644
--- a/base/command_line.h
+++ b/base/command_line.h
@@ -142,7 +142,7 @@
   void SetProgram(const FilePath& program);
 
   // Returns true if this command line contains the given switch.
-  // (Switch names are case-insensitive).
+  // Switch names should only be lowercase.
   // The second override provides an optimized version to avoid inlining the
   // codegen for the string allocation.
   bool HasSwitch(const std::string& switch_string) const;
diff --git a/base/command_line_unittest.cc b/base/command_line_unittest.cc
index e395c856..db1a0b2 100644
--- a/base/command_line_unittest.cc
+++ b/base/command_line_unittest.cc
@@ -60,12 +60,13 @@
             cl.GetProgram().value());
 
   EXPECT_TRUE(cl.HasSwitch("foo"));
-  EXPECT_TRUE(cl.HasSwitch("bAr"));
+#if defined(OS_WIN)
+  EXPECT_TRUE(cl.HasSwitch("bar"));
+#else
+  EXPECT_FALSE(cl.HasSwitch("bar"));
+#endif
   EXPECT_TRUE(cl.HasSwitch("baz"));
   EXPECT_TRUE(cl.HasSwitch("spaetzle"));
-#if defined(OS_WIN)
-  EXPECT_TRUE(cl.HasSwitch("SPAETZLE"));
-#endif
   EXPECT_TRUE(cl.HasSwitch("other-switches"));
   EXPECT_TRUE(cl.HasSwitch("input-translation"));
 
@@ -128,7 +129,6 @@
   EXPECT_TRUE(cl.HasSwitch("bar"));
   EXPECT_TRUE(cl.HasSwitch("baz"));
   EXPECT_TRUE(cl.HasSwitch("spaetzle"));
-  EXPECT_TRUE(cl.HasSwitch("SPAETZLE"));
   EXPECT_TRUE(cl.HasSwitch("other-switches"));
   EXPECT_TRUE(cl.HasSwitch("input-translation"));
   EXPECT_TRUE(cl.HasSwitch("quotes"));
diff --git a/base/files/file_path.h b/base/files/file_path.h
index 93f9ec9..5225b12 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -443,11 +443,9 @@
 #if defined(OS_POSIX)
 #define FILE_PATH_LITERAL(x) x
 #define PRFilePath "s"
-#define PRFilePathLiteral "%s"
 #elif defined(OS_WIN)
 #define FILE_PATH_LITERAL(x) L ## x
 #define PRFilePath "ls"
-#define PRFilePathLiteral L"%ls"
 #endif  // OS_WIN
 
 // Provide a hash function so that hash_sets and maps can contain FilePath
diff --git a/base/files/file_path_watcher_stub.cc b/base/files/file_path_watcher_stub.cc
index d7ad2066..8138692e 100644
--- a/base/files/file_path_watcher_stub.cc
+++ b/base/files/file_path_watcher_stub.cc
@@ -13,18 +13,18 @@
 
 class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate {
  public:
-  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 {
     return false;
   }
 
-  virtual void Cancel() override {}
+  void Cancel() override {}
 
-  virtual void CancelOnMessageLoopThread() override {}
+  void CancelOnMessageLoopThread() override {}
 
  protected:
-  virtual ~FilePathWatcherImpl() {}
+  ~FilePathWatcherImpl() override {}
 };
 
 }  // namespace
diff --git a/base/json/json_value_converter.h b/base/json/json_value_converter.h
index c4bfe61..f94d46e3 100644
--- a/base/json/json_value_converter.h
+++ b/base/json/json_value_converter.h
@@ -123,8 +123,7 @@
         value_converter_(converter) {
   }
 
-  virtual bool ConvertField(
-      const base::Value& value, StructType* dst) const override {
+  bool ConvertField(const base::Value& value, StructType* dst) const override {
     return value_converter_->Convert(value, &(dst->*field_pointer_));
   }
 
@@ -202,8 +201,7 @@
   ValueFieldConverter(ConvertFunc convert_func)
       : convert_func_(convert_func) {}
 
-  virtual bool Convert(const base::Value& value,
-                       FieldType* field) const override {
+  bool Convert(const base::Value& value, FieldType* field) const override {
     return convert_func_(&value, field);
   }
 
@@ -221,8 +219,7 @@
   CustomFieldConverter(ConvertFunc convert_func)
       : convert_func_(convert_func) {}
 
-  virtual bool Convert(const base::Value& value,
-                       FieldType* field) const override {
+  bool Convert(const base::Value& value, FieldType* field) const override {
     std::string string_value;
     return value.GetAsString(&string_value) &&
         convert_func_(string_value, field);
@@ -239,8 +236,7 @@
  public:
   NestedValueConverter() {}
 
-  virtual bool Convert(
-      const base::Value& value, NestedType* field) const override {
+  bool Convert(const base::Value& value, NestedType* field) const override {
     return converter_.Convert(value, field);
   }
 
@@ -254,8 +250,8 @@
  public:
   RepeatedValueConverter() {}
 
-  virtual bool Convert(
-      const base::Value& value, ScopedVector<Element>* field) const override {
+  bool Convert(const base::Value& value,
+               ScopedVector<Element>* field) const override {
     const base::ListValue* list = NULL;
     if (!value.GetAsList(&list)) {
       // The field is not a list.
@@ -290,8 +286,8 @@
  public:
   RepeatedMessageConverter() {}
 
-  virtual bool Convert(const base::Value& value,
-                       ScopedVector<NestedType>* field) const override {
+  bool Convert(const base::Value& value,
+               ScopedVector<NestedType>* field) const override {
     const base::ListValue* list = NULL;
     if (!value.GetAsList(&list))
       return false;
@@ -327,8 +323,8 @@
   RepeatedCustomValueConverter(ConvertFunc convert_func)
       : convert_func_(convert_func) {}
 
-  virtual bool Convert(const base::Value& value,
-                       ScopedVector<NestedType>* field) const override {
+  bool Convert(const base::Value& value,
+               ScopedVector<NestedType>* field) const override {
     const base::ListValue* list = NULL;
     if (!value.GetAsList(&list))
       return false;
diff --git a/base/memory/discardable_memory.h b/base/memory/discardable_memory.h
index 4138684..fc189e746 100644
--- a/base/memory/discardable_memory.h
+++ b/base/memory/discardable_memory.h
@@ -56,8 +56,8 @@
   virtual void* data() const = 0;
 
   // Handy method to simplify calling data() with a reinterpret_cast.
-  template<typename T> const T* data_as() const {
-    return reinterpret_cast<const T*>(data());
+  template<typename T> T* data_as() const {
+    return reinterpret_cast<T*>(data());
   }
 };
 
diff --git a/base/memory/ref_counted_delete_on_message_loop.h b/base/memory/ref_counted_delete_on_message_loop.h
index 7b898ac..139a1ed 100644
--- a/base/memory/ref_counted_delete_on_message_loop.h
+++ b/base/memory/ref_counted_delete_on_message_loop.h
@@ -8,7 +8,9 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
+// TODO(ricea): Remove the following include once all callers have been fixed.
 #include "base/message_loop/message_loop_proxy.h"
+#include "base/single_thread_task_runner.h"
 
 namespace base {
 
@@ -18,7 +20,7 @@
 // Sample usage:
 // class Foo : public RefCountedDeleteOnMessageLoop<Foo> {
 //
-//   Foo(const scoped_refptr<MessageLoopProxy>& loop)
+//   Foo(const scoped_refptr<SingleThreadTaskRunner>& loop)
 //       : RefCountedDeleteOnMessageLoop<Foo>(loop) {
 //     ...
 //   }
@@ -33,9 +35,14 @@
 template <class T>
 class RefCountedDeleteOnMessageLoop : public subtle::RefCountedThreadSafeBase {
  public:
+  // This constructor will accept a MessageL00pProxy object, but new code should
+  // prefer a SingleThreadTaskRunner. A SingleThreadTaskRunner for the
+  // MessageLoop on the current thread can be acquired by calling
+  // MessageLoop::current()->task_runner().
   RefCountedDeleteOnMessageLoop(
-      const scoped_refptr<MessageLoopProxy>& proxy) : proxy_(proxy) {
-    DCHECK(proxy_.get());
+      const scoped_refptr<SingleThreadTaskRunner>& task_runner)
+      : task_runner_(task_runner) {
+    DCHECK(task_runner_.get());
   }
 
   void AddRef() const {
@@ -53,13 +60,13 @@
 
   void DestructOnMessageLoop() const {
     const T* t = static_cast<const T*>(this);
-    if (proxy_->BelongsToCurrentThread())
+    if (task_runner_->BelongsToCurrentThread())
       delete t;
     else
-      proxy_->DeleteSoon(FROM_HERE, t);
+      task_runner_->DeleteSoon(FROM_HERE, t);
   }
 
-  scoped_refptr<MessageLoopProxy> proxy_;
+  scoped_refptr<SingleThreadTaskRunner> task_runner_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(RefCountedDeleteOnMessageLoop);
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc
index 636aa83..46b350b 100644
--- a/base/observer_list_unittest.cc
+++ b/base/observer_list_unittest.cc
@@ -71,7 +71,7 @@
         adder(1) {
   }
 
-  virtual void Observe(int x) override {
+  void Observe(int x) override {
     if (!added) {
       added = true;
       observer_list->AddObserver(&adder);
diff --git a/base/prefs/pref_member.h b/base/prefs/pref_member.h
index 078be95..9b140d1 100644
--- a/base/prefs/pref_member.h
+++ b/base/prefs/pref_member.h
@@ -264,9 +264,9 @@
     }
 
    protected:
-    virtual ~Internal() {}
+    ~Internal() override {}
 
-    virtual BASE_PREFS_EXPORT bool UpdateValueInternal(
+    BASE_PREFS_EXPORT bool UpdateValueInternal(
         const base::Value& value) const override;
 
     // We cache the value of the pref so we don't have to keep walking the pref
@@ -277,8 +277,8 @@
     DISALLOW_COPY_AND_ASSIGN(Internal);
   };
 
-  virtual Internal* internal() const override { return internal_.get(); }
-  virtual void CreateInternal() const override { internal_ = new Internal(); }
+  Internal* internal() const override { return internal_.get(); }
+  void CreateInternal() const override { internal_ = new Internal(); }
 
   // This method is used to do the actual sync with pref of the specified type.
   void BASE_PREFS_EXPORT UpdatePref(const ValueType& value);
diff --git a/base/process/memory_unittest.cc b/base/process/memory_unittest.cc
index 29e76dd..0276b49 100644
--- a/base/process/memory_unittest.cc
+++ b/base/process/memory_unittest.cc
@@ -128,10 +128,11 @@
 
 // Android doesn't implement set_new_handler, so we can't use the
 // OutOfMemoryTest cases. OpenBSD does not support these tests either.
-// Don't test these on ASAN configurations: only test the real allocator.
+// Don't test these on ASan/TSan/MSan configurations: only test the real
+// allocator.
 // TODO(vandebo) make this work on Windows too.
 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && !defined(OS_WIN) && \
-    !defined(ADDRESS_SANITIZER)
+    !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
 
 #if defined(USE_TCMALLOC)
 extern "C" {
diff --git a/base/security_unittest.cc b/base/security_unittest.cc
index 5003269..07ba6f5a 100644
--- a/base/security_unittest.cc
+++ b/base/security_unittest.cc
@@ -69,7 +69,7 @@
 // We also use it so that the compiler doesn't discard certain return values
 // as something we don't need (see the comment with calloc below).
 template <typename Type>
-Type HideValueFromCompiler(volatile Type value) {
+NOINLINE Type HideValueFromCompiler(volatile Type value) {
 #if defined(__GNUC__)
   // In a GCC compatible compiler (GCC or Clang), make this compiler barrier
   // more robust than merely using "volatile".
@@ -290,11 +290,11 @@
 // Call calloc(), eventually free the memory and return whether or not
 // calloc() did succeed.
 bool CallocReturnsNull(size_t nmemb, size_t size) {
-  // We need the two calls to HideValueFromCompiler(): we have seen LLVM
+  scoped_ptr<char, base::FreeDeleter> array_pointer(
+      static_cast<char*>(calloc(nmemb, size)));
+  // We need the call to HideValueFromCompiler(): we have seen LLVM
   // optimize away the call to calloc() entirely and assume the pointer to not
   // be NULL.
-  scoped_ptr<char, base::FreeDeleter> array_pointer(
-      static_cast<char*>(HideValueFromCompiler(calloc(nmemb, size))));
   return HideValueFromCompiler(array_pointer.get()) == NULL;
 }
 
diff --git a/base/test/gtest_xml_util.h b/base/test/gtest_xml_util.h
index f832cde..9ff2406 100644
--- a/base/test/gtest_xml_util.h
+++ b/base/test/gtest_xml_util.h
@@ -21,17 +21,17 @@
 class XmlUnitTestResultPrinter : public testing::EmptyTestEventListener {
  public:
   XmlUnitTestResultPrinter();
-  virtual ~XmlUnitTestResultPrinter();
+  ~XmlUnitTestResultPrinter() override;
 
   // Must be called before adding as a listener. Returns true on success.
   bool Initialize(const FilePath& output_file_path) WARN_UNUSED_RESULT;
 
  private:
   // testing::EmptyTestEventListener:
-  virtual void OnTestCaseStart(const testing::TestCase& test_case) override;
-  virtual void OnTestStart(const testing::TestInfo& test_info) override;
-  virtual void OnTestEnd(const testing::TestInfo& test_info) override;
-  virtual void OnTestCaseEnd(const testing::TestCase& test_case) override;
+  void OnTestCaseStart(const testing::TestCase& test_case) override;
+  void OnTestStart(const testing::TestInfo& test_info) override;
+  void OnTestEnd(const testing::TestInfo& test_info) override;
+  void OnTestCaseEnd(const testing::TestCase& test_case) override;
 
   FILE* output_file_;
 
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index d40dd983..ee135e53 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -55,7 +55,7 @@
 
 class MaybeTestDisabler : public testing::EmptyTestEventListener {
  public:
-  virtual void OnTestStart(const testing::TestInfo& test_info) override {
+  void OnTestStart(const testing::TestInfo& test_info) override {
     ASSERT_FALSE(TestSuite::IsMarkedMaybe(test_info))
         << "Probably the OS #ifdefs don't include all of the necessary "
            "platforms.\nPlease ensure that no tests have the MAYBE_ prefix "
@@ -69,11 +69,11 @@
       : old_command_line_(base::CommandLine::NO_PROGRAM) {
   }
 
-  virtual void OnTestStart(const testing::TestInfo& test_info) override {
+  void OnTestStart(const testing::TestInfo& test_info) override {
     old_command_line_ = *base::CommandLine::ForCurrentProcess();
   }
 
-  virtual void OnTestEnd(const testing::TestInfo& test_info) override {
+  void OnTestEnd(const testing::TestInfo& test_info) override {
     *base::CommandLine::ForCurrentProcess() = old_command_line_;
   }
 
diff --git a/base/third_party/xdg_mime/README.chromium b/base/third_party/xdg_mime/README.chromium
index 29d239a..95f3a965 100644
--- a/base/third_party/xdg_mime/README.chromium
+++ b/base/third_party/xdg_mime/README.chromium
@@ -7,5 +7,7 @@
 @ 2cdd8d36d7930d5a594587286cb1949ff62f7027 on 2012/08/06.
 
 In addition, we have the following patch(es):
-- compile.patch: small tweaks to make the code compile.
-- Added a LICENSE file.
+  - compile.patch: small tweaks to make the code compile.
+  - free_pointer_later.patch: small patch that fixes potential crash in
+      xdg_mime_get_mime_type_for_file() - use of pointer after being freed.
+  - Added a LICENSE file.
diff --git a/base/third_party/xdg_mime/free_pointer_later.patch b/base/third_party/xdg_mime/free_pointer_later.patch
new file mode 100644
index 0000000..7668761
--- /dev/null
+++ b/base/third_party/xdg_mime/free_pointer_later.patch
@@ -0,0 +1,22 @@
+diff --git a/base/third_party/xdg_mime/xdgmime.c b/base/third_party/xdg_mime/xdgmime.c
+index c7b16bb..6dc58c2 100644
+--- a/base/third_party/xdg_mime/xdgmime.c
++++ b/base/third_party/xdg_mime/xdgmime.c
+@@ -558,13 +558,13 @@ xdg_mime_get_mime_type_for_file (const char  *file_name,
+   mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL,
+ 					   mime_types, n);
+ 
+-  free (data);
+   fclose (file);
+ 
+-  if (mime_type)
+-    return mime_type;
++  if (!mime_type)
++    mime_type = _xdg_binary_or_text_fallback(data, bytes_read);
+ 
+-  return _xdg_binary_or_text_fallback(data, bytes_read);
++  free (data);
++  return mime_type;
+ }
+ 
+ const char *
diff --git a/base/third_party/xdg_mime/xdgmime.c b/base/third_party/xdg_mime/xdgmime.c
index c7b16bbc..6dc58c2 100644
--- a/base/third_party/xdg_mime/xdgmime.c
+++ b/base/third_party/xdg_mime/xdgmime.c
@@ -558,13 +558,13 @@
   mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL,
 					   mime_types, n);
 
-  free (data);
   fclose (file);
 
-  if (mime_type)
-    return mime_type;
+  if (!mime_type)
+    mime_type = _xdg_binary_or_text_fallback(data, bytes_read);
 
-  return _xdg_binary_or_text_fallback(data, bytes_read);
+  free (data);
+  return mime_type;
 }
 
 const char *
diff --git a/base/threading/thread_perftest.cc b/base/threading/thread_perftest.cc
index b94f942..a08cc5bf 100644
--- a/base/threading/thread_perftest.cc
+++ b/base/threading/thread_perftest.cc
@@ -174,12 +174,12 @@
 template <typename WaitableEventType>
 class EventPerfTest : public ThreadPerfTest {
  public:
-  virtual void Init() override {
+  void Init() override {
     for (size_t i = 0; i < threads_.size(); i++)
       events_.push_back(new WaitableEventType(false, false));
   }
 
-  virtual void Reset() override { events_.clear(); }
+  void Reset() override { events_.clear(); }
 
   void WaitAndSignalOnThread(size_t event) {
     size_t next_event = (event + 1) % events_.size();
@@ -195,7 +195,7 @@
       FinishMeasurement();
   }
 
-  virtual void PingPong(int hops) override {
+  void PingPong(int hops) override {
     remaining_hops_ = hops;
     for (size_t i = 0; i < threads_.size(); i++) {
       threads_[i]->message_loop_proxy()->PostTask(
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc
index 94ef5ed..7d9931c 100644
--- a/base/trace_event/malloc_dump_provider.cc
+++ b/base/trace_event/malloc_dump_provider.cc
@@ -33,7 +33,6 @@
 // the current process.
 bool MallocDumpProvider::DumpInto(ProcessMemoryDump* pmd) {
   struct mallinfo info = mallinfo();
-  DCHECK(info.uordblks > 0);
   DCHECK_GE(info.arena + info.hblkhd, info.uordblks);
 
   MemoryAllocatorDump* dump =
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index 31fe92e..63d91bb4 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -13,6 +13,12 @@
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/trace_event_argument.h"
 
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+#include "base/trace_event/malloc_dump_provider.h"
+#include "base/trace_event/process_memory_maps_dump_provider.h"
+#include "base/trace_event/process_memory_totals_dump_provider.h"
+#endif
+
 namespace base {
 namespace trace_event {
 
@@ -20,9 +26,10 @@
 
 // TODO(primiano): this should be smarter and should do something similar to
 // trace event synthetic delays.
-const char kTraceCategory[] = TRACE_DISABLED_BY_DEFAULT("memory-dumps");
+const char kTraceCategory[] = TRACE_DISABLED_BY_DEFAULT("memory-infra");
 
 MemoryDumpManager* g_instance_for_testing = nullptr;
+const int kDumpIntervalSeconds = 2;
 const int kTraceEventNumArgs = 1;
 const char* kTraceEventArgNames[] = {"dumps"};
 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
@@ -108,6 +115,11 @@
   }
 }
 
+void RequestPeriodicGlobalDump() {
+  MemoryDumpManager::GetInstance()->RequestGlobalDump(
+      MemoryDumpType::PERIODIC_INTERVAL);
+}
+
 }  // namespace
 
 // static
@@ -124,13 +136,16 @@
 
 // static
 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) {
+  if (instance)
+    instance->skip_core_dumpers_auto_registration_for_testing_ = true;
   g_instance_for_testing = instance;
 }
 
 MemoryDumpManager::MemoryDumpManager()
     : dump_provider_currently_active_(nullptr),
       delegate_(nullptr),
-      memory_tracing_enabled_(0) {
+      memory_tracing_enabled_(0),
+      skip_core_dumpers_auto_registration_for_testing_(false) {
   g_next_guid.GetNext();  // Make sure that first guid is not zero.
 }
 
@@ -141,6 +156,16 @@
 void MemoryDumpManager::Initialize() {
   TRACE_EVENT0(kTraceCategory, "init");  // Add to trace-viewer category list.
   trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
+
+  if (skip_core_dumpers_auto_registration_for_testing_)
+    return;
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+  // Enable the core dump providers.
+  RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance());
+  RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance());
+  RegisterDumpProvider(MallocDumpProvider::GetInstance());
+#endif
 }
 
 void MemoryDumpManager::SetDelegate(MemoryDumpManagerDelegate* delegate) {
@@ -309,22 +334,33 @@
   TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled);
 
   AutoLock lock(lock_);
-  dump_providers_enabled_.clear();
-  if (enabled) {
-    // Merge the dictionary of allocator attributes from all dump providers
-    // into the session state.
-    session_state_ = new MemoryDumpSessionState();
-    for (const MemoryDumpProvider* mdp : dump_providers_registered_) {
-      session_state_->allocators_attributes_type_info.Update(
-          mdp->allocator_attributes_type_info());
-    }
-    dump_providers_enabled_ = dump_providers_registered_;
+
+  // There is no point starting the tracing without a delegate.
+  if (!enabled || !delegate_) {
+    dump_providers_enabled_.clear();
+    return;
   }
+
+  // Merge the dictionary of allocator attributes from all dump providers
+  // into the session state.
+  session_state_ = new MemoryDumpSessionState();
+  for (const MemoryDumpProvider* mdp : dump_providers_registered_) {
+    session_state_->allocators_attributes_type_info.Update(
+        mdp->allocator_attributes_type_info());
+  }
+  dump_providers_enabled_ = dump_providers_registered_;
   subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
+
+  if (delegate_->IsCoordinatorProcess()) {
+    periodic_dump_timer_.Start(FROM_HERE,
+                               TimeDelta::FromSeconds(kDumpIntervalSeconds),
+                               base::Bind(&RequestPeriodicGlobalDump));
+  }
 }
 
 void MemoryDumpManager::OnTraceLogDisabled() {
   AutoLock lock(lock_);
+  periodic_dump_timer_.Stop();
   dump_providers_enabled_.clear();
   subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
   session_state_ = nullptr;
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
index 6fc2341e..371a47a 100644
--- a/base/trace_event/memory_dump_manager.h
+++ b/base/trace_event/memory_dump_manager.h
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
 #include "base/synchronization/lock.h"
+#include "base/timer/timer.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/trace_event.h"
 
@@ -120,6 +121,12 @@
   // dump_providers_enabled_ list) when tracing is not enabled.
   subtle::AtomicWord memory_tracing_enabled_;
 
+  // For time-triggered periodic dumps.
+  RepeatingTimer<MemoryDumpManager> periodic_dump_timer_;
+
+  // Skips the auto-registration of the core dumpers during Initialize().
+  bool skip_core_dumpers_auto_registration_for_testing_;
+
   DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager);
 };
 
@@ -130,6 +137,10 @@
   virtual void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args,
                                        const MemoryDumpCallback& callback) = 0;
 
+  // Determines whether the MemoryDumpManager instance should be the master
+  // (the ones which initiates and coordinates the multiprocess dumps) or not.
+  virtual bool IsCoordinatorProcess() const = 0;
+
  protected:
   MemoryDumpManagerDelegate() {}
   virtual ~MemoryDumpManagerDelegate() {}
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 0de60b29..589c4061 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -30,6 +30,8 @@
       const MemoryDumpCallback& callback) override {
     CreateProcessDump(args, callback);
   }
+
+  bool IsCoordinatorProcess() const override { return false; }
 };
 
 class MemoryDumpManagerTest : public testing::Test {
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index 7c4d3ab..e0249f5 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -144,11 +144,11 @@
 //   class MyData : public base::trace_event::ConvertableToTraceFormat {
 //    public:
 //     MyData() {}
-//     virtual void AppendAsTraceFormat(std::string* out) const override {
+//     void AppendAsTraceFormat(std::string* out) const override {
 //       out->append("{\"foo\":1}");
 //     }
 //    private:
-//     virtual ~MyData() {}
+//     ~MyData() override {}
 //     DISALLOW_COPY_AND_ASSIGN(MyData);
 //   };
 //
@@ -601,6 +601,12 @@
         TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
         static_cast<int>(base::PlatformThread::CurrentId()), \
         timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, \
+        name, id, timestamp) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+        TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
+        static_cast<int>(base::PlatformThread::CurrentId()), \
+        timestamp, TRACE_EVENT_FLAG_COPY)
 
 // Records a single ASYNC_STEP_INTO event for |step| immediately. If the
 // category is not enabled, then this does nothing. The |name| and |id| must
diff --git a/base/win/event_trace_consumer.h b/base/win/event_trace_consumer.h
index 9322e1e..fd448949 100644
--- a/base/win/event_trace_consumer.h
+++ b/base/win/event_trace_consumer.h
@@ -119,7 +119,7 @@
 template <class ImplClass> inline
 HRESULT EtwTraceConsumerBase<ImplClass>::Consume() {
   ULONG err = ::ProcessTrace(&trace_handles_[0],
-                             trace_handles_.size(),
+                             static_cast<ULONG>(trace_handles_.size()),
                              NULL,
                              NULL);
   return HRESULT_FROM_WIN32(err);
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index 2ebef32..33a8aa5c 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -132,6 +132,10 @@
   // This lock only protects against races in this module, which is fine.
   AutoNativeLock lock(g_lock.Get());
   g_active_verifier = verifier ? verifier : new ActiveVerifier(true);
+
+  // TODO(shrikant): Enable handle verifier after figuring out
+  // AppContainer/DuplicateHandle error.
+  g_active_verifier->Disable();
 #endif
 }
 
diff --git a/breakpad/breakpad.gyp b/breakpad/breakpad.gyp
index cc5187d..545456ee 100644
--- a/breakpad/breakpad.gyp
+++ b/breakpad/breakpad.gyp
@@ -846,6 +846,11 @@
             'src/client/mac/Framework',
             'src/common/mac',
           ],
+          'direct_dependent_settings': {
+            'include_dirs': [
+              'src',
+            ],
+          },
         }
       ]
     }],
diff --git a/breakpad/breakpad_handler.gypi b/breakpad/breakpad_handler.gypi
index 540e87e..34b448d 100644
--- a/breakpad/breakpad_handler.gypi
+++ b/breakpad/breakpad_handler.gypi
@@ -39,6 +39,7 @@
     ['OS=="win"', {
       'targets': [
         {
+          # GN version: //breakpad:breakpad_handler
           'target_name': 'breakpad_handler',
           'type': 'static_library',
           'variables': {
diff --git a/build/PRESUBMIT.py b/build/PRESUBMIT.py
index 3c70193..fca962f 100644
--- a/build/PRESUBMIT.py
+++ b/build/PRESUBMIT.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-WHITELIST = [ r'.+_test.py$' ]
-
 
 def _RunTests(input_api, output_api):
   return (input_api.canned_checks.RunUnitTestsInDirectory(
diff --git a/build/all.gyp b/build/all.gyp
index 8f6295b..255a35c 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -495,7 +495,7 @@
   ],
   'conditions': [
     # TODO(GYP): make gn_migration.gypi work unconditionally.
-    ['OS=="win" or (OS=="linux" and target_arch=="x64" and chromecast==0)', {
+    ['OS=="mac" or OS=="win" or (OS=="linux" and target_arch=="x64" and chromecast==0)', {
       'includes': [
         'gn_migration.gypi',
       ],
@@ -833,6 +833,7 @@
             '../base/base.gyp:base_unittests_apk',
             '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests_apk',
             '../cc/cc_tests.gyp:cc_unittests_apk',
+            '../components/components_tests.gyp:components_browsertests_apk',
             '../components/components_tests.gyp:components_unittests_apk',
             '../content/content_shell_and_tests.gyp:content_browsertests_apk',
             '../content/content_shell_and_tests.gyp:content_gl_tests_apk',
diff --git a/build/android/gyp/util/build_device.py b/build/android/gyp/util/build_device.py
index b153a15..7e0d57b 100644
--- a/build/android/gyp/util/build_device.py
+++ b/build/android/gyp/util/build_device.py
@@ -40,7 +40,7 @@
     return self.id
 
   def Install(self, *args, **kwargs):
-    return self.device.old_interface.Install(*args, **kwargs)
+    return self.device.Install(*args, **kwargs)
 
   def GetInstallMetadata(self, apk_package):
     """Gets the metadata on the device for the apk_package apk."""
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index 5fc8955..d8f2d74 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -88,6 +88,10 @@
   parser.add_option('--native-libs', help='List of top-level native libs.')
   parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.')
 
+  parser.add_option('--tested-apk-config',
+      help='Path to the build config of the tested apk (for an instrumentation '
+      'test apk).')
+
   options, args = parser.parse_args(argv)
 
   if args:
@@ -217,13 +221,26 @@
         c['package_name'] for c in all_resources_deps if 'package_name' in c]
 
 
+  deps_dex_files = [c['dex_path'] for c in all_library_deps]
+  # An instrumentation test apk should exclude the dex files that are in the apk
+  # under test.
+  if options.type == 'android_apk' and options.tested_apk_config:
+    tested_apk_config_paths = GetAllDepsConfigsInOrder(
+        [options.tested_apk_config])
+    tested_apk_configs = [GetDepConfig(p) for p in tested_apk_config_paths]
+    tested_apk_library_deps = DepsOfType('java_library', tested_apk_configs)
+    tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps]
+    deps_dex_files = [
+        p for p in deps_dex_files if not p in tested_apk_deps_dex_files]
+
+
   # Dependencies for the final dex file of an apk or a 'deps_dex'.
   if options.type in ['android_apk', 'deps_dex']:
     config['final_dex'] = {}
     dex_config = config['final_dex']
     # TODO(cjhopman): proguard version
-    dex_deps_files = [c['dex_path'] for c in all_library_deps]
-    dex_config['dependency_dex_files'] = dex_deps_files
+    dex_config['dependency_dex_files'] = deps_dex_files
+
 
   if options.type == 'android_apk':
     config['dist_jar'] = {
diff --git a/build/android/pylib/constants.py b/build/android/pylib/constants/__init__.py
similarity index 95%
rename from build/android/pylib/constants.py
rename to build/android/pylib/constants/__init__.py
index 8f8e782..6e92f6d 100644
--- a/build/android/pylib/constants.py
+++ b/build/android/pylib/constants/__init__.py
@@ -3,6 +3,9 @@
 # found in the LICENSE file.
 
 """Defines a set of constants shared by test runners and other scripts."""
+
+# TODO(jbudorick): Split these constants into coherent modules.
+
 # pylint: disable=W0212
 
 import collections
@@ -13,7 +16,7 @@
 
 DIR_SOURCE_ROOT = os.environ.get('CHECKOUT_SOURCE_ROOT',
     os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                 os.pardir, os.pardir, os.pardir)))
+                                 os.pardir, os.pardir, os.pardir, os.pardir)))
 ISOLATE_DEPS_DIR = os.path.join(DIR_SOURCE_ROOT, 'isolate_deps_dir')
 
 CHROME_SHELL_HOST_DRIVEN_DIR = os.path.join(
@@ -103,6 +106,13 @@
         '/data/local/tmp/chrome-native-tests-command-line',
         None,
         None),
+    'components_browsertests': PackageInfo(
+        'org.chromium.components_browsertests_apk',
+        ('org.chromium.components_browsertests_apk' +
+         '.ComponentsBrowserTestsActivity'),
+        '/data/local/tmp/components-browser-tests-command-line',
+        None,
+        None),
     'content_browsertests': PackageInfo(
         'org.chromium.content_browsertests_apk',
         'org.chromium.content_browsertests_apk.ContentBrowserTestsActivity',
diff --git a/build/android/pylib/constants/keyevent.py b/build/android/pylib/constants/keyevent.py
new file mode 100644
index 0000000..06736b3d
--- /dev/null
+++ b/build/android/pylib/constants/keyevent.py
@@ -0,0 +1,14 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Android KeyEvent constants.
+
+http://developer.android.com/reference/android/view/KeyEvent.html
+"""
+
+KEYCODE_BACK = 4
+KEYCODE_DPAD_RIGHT = 22
+KEYCODE_ENTER = 66
+KEYCODE_MENU = 82
+
diff --git a/build/android/pylib/forwarder.py b/build/android/pylib/forwarder.py
index eb83d68..d16b9b1 100644
--- a/build/android/pylib/forwarder.py
+++ b/build/android/pylib/forwarder.py
@@ -288,11 +288,8 @@
         self._device_forwarder_path_on_host,
         Forwarder._DEVICE_FORWARDER_FOLDER)])
     cmd = '%s %s' % (tool.GetUtilWrapper(), Forwarder._DEVICE_FORWARDER_PATH)
-    (exit_code, output) = device.old_interface.GetAndroidToolStatusAndOutput(
-        cmd, lib_path=Forwarder._DEVICE_FORWARDER_FOLDER)
-    if exit_code != 0:
-      raise Exception(
-          'Failed to start device forwarder:\n%s' % '\n'.join(output))
+    device.RunShellCommand(
+        cmd, env={'LD_LIBRARY_PATH': Forwarder._DEVICE_FORWARDER_FOLDER})
     self._initialized_devices.add(device_serial)
 
   def _KillHostLocked(self):
@@ -328,5 +325,5 @@
 
     cmd = '%s %s --kill-server' % (tool.GetUtilWrapper(),
                                    Forwarder._DEVICE_FORWARDER_PATH)
-    device.old_interface.GetAndroidToolStatusAndOutput(
-        cmd, lib_path=Forwarder._DEVICE_FORWARDER_FOLDER)
+    device.RunShellCommand(
+        cmd, env={'LD_LIBRARY_PATH': Forwarder._DEVICE_FORWARDER_FOLDER})
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 8608ed70..6ce0fb1 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -6,6 +6,7 @@
 
 # Add new suites here before upgrading them to the stable list below.
 EXPERIMENTAL_TEST_SUITES = [
+    'components_browsertests',
     'content_gl_tests',
     'heap_profiler_unittests',
     'devtools_bridge_tests',
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py
index 186b8fc..b6f83b31 100644
--- a/build/android/pylib/gtest/gtest_test_instance.py
+++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -92,9 +92,10 @@
       raise ValueError('Platform mode currently supports only 1 gtest suite')
     self._suite = args.suite_name[0]
 
-    if self._suite == 'content_browsertests':
-      error_func('content_browsertests are not currently supported '
-                 'in platform mode.')
+    if (self._suite == 'content_browsertests' or
+        self._suite == 'components_browsertests'):
+      error_func('%s are not currently supported '
+                 'in platform mode.' % self._suite)
       self._apk_path = os.path.join(
           constants.GetOutDirectory(), 'apks', '%s.apk' % self._suite)
     else:
diff --git a/build/android/pylib/gtest/local_device_gtest_run.py b/build/android/pylib/gtest/local_device_gtest_run.py
index ff12d82a..fd143d6 100644
--- a/build/android/pylib/gtest/local_device_gtest_run.py
+++ b/build/android/pylib/gtest/local_device_gtest_run.py
@@ -30,7 +30,8 @@
 # TODO(jbudorick): Move this up to the test instance if the net test server is
 # handled outside of the APK for the remote_device environment.
 _SUITE_REQUIRES_TEST_SERVER_SPAWNER = [
-  'content_unittests', 'content_browsertests', 'net_unittests', 'unit_tests'
+  'components_browsertests', 'content_unittests', 'content_browsertests',
+  'net_unittests', 'unit_tests'
 ]
 
 class _ApkDelegate(object):
diff --git a/build/android/pylib/gtest/setup.py b/build/android/pylib/gtest/setup.py
index 1b882ca..44662d08 100644
--- a/build/android/pylib/gtest/setup.py
+++ b/build/android/pylib/gtest/setup.py
@@ -31,6 +31,7 @@
       'third_party/WebKit/Source/platform/heap/BlinkHeapUnitTests.isolate',
     'breakpad_unittests': 'breakpad/breakpad_unittests.isolate',
     'cc_perftests': 'cc/cc_perftests.isolate',
+    'components_browsertests': 'components/components_browsertests.isolate',
     'components_unittests': 'components/components_unittests.isolate',
     'content_browsertests': 'content/content_browsertests.isolate',
     'content_unittests': 'content/content_unittests.isolate',
@@ -236,7 +237,8 @@
     tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter)
 
   # Coalesce unit tests into a single test per device
-  if test_options.suite_name != 'content_browsertests':
+  if (test_options.suite_name != 'content_browsertests' and
+      test_options.suite_name != 'components_browsertests'):
     num_devices = len(devices)
     tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)]
     tests = [t for t in tests if t]
diff --git a/build/android/pylib/gtest/test_package_apk.py b/build/android/pylib/gtest/test_package_apk.py
index 3e579d2..8da3c74 100644
--- a/build/android/pylib/gtest/test_package_apk.py
+++ b/build/android/pylib/gtest/test_package_apk.py
@@ -34,6 +34,10 @@
       self.suite_path = os.path.join(
           constants.GetOutDirectory(), 'apks', '%s.apk' % suite_name)
       self._package_info = constants.PACKAGE_INFO['content_browsertests']
+    elif suite_name == 'components_browsertests':
+      self.suite_path = os.path.join(
+          constants.GetOutDirectory(), 'apks', '%s.apk' % suite_name)
+      self._package_info = constants.PACKAGE_INFO['components_browsertests']
     else:
       self.suite_path = os.path.join(
           constants.GetOutDirectory(), '%s_apk' % suite_name,
@@ -90,6 +94,15 @@
         # TODO(jbudorick) Handle this exception appropriately once the
         #                 conversions are done.
         pass
+    elif self.suite_name == 'components_browsertests':
+      try:
+        device.RunShellCommand(
+            'rm -r %s/components_shell' % device.GetExternalStoragePath(),
+            timeout=60 * 2)
+      except device_errors.CommandFailedError:
+        # TODO(jbudorick) Handle this exception appropriately once the
+        #                 conversions are done.
+        pass
 
   #override
   def CreateCommandLineFileOnDevice(self, device, test_filter, test_arguments):
diff --git a/build/android/pylib/gtest/test_runner.py b/build/android/pylib/gtest/test_runner.py
index 0fc6c12..49263888 100644
--- a/build/android/pylib/gtest/test_runner.py
+++ b/build/android/pylib/gtest/test_runner.py
@@ -26,10 +26,15 @@
 # to output the CRASHED marker when a crash happens.
 RE_CRASH = re.compile('\\[ CRASHED      \\](.*)\r\n')
 
+# Bots that don't output anything for 20 minutes get timed out, so that's our
+# hard cap.
+_INFRA_STDOUT_TIMEOUT = 20 * 60
+
 
 def _TestSuiteRequiresMockTestServer(suite_name):
   """Returns True if the test suite requires mock test server."""
   tests_require_net_test_server = ['unit_tests', 'net_unittests',
+                                   'components_browsertests',
                                    'content_unittests',
                                    'content_browsertests']
   return (suite_name in
@@ -62,7 +67,8 @@
     if os.environ.get('BUILDBOT_SLAVENAME'):
       timeout = timeout * 2
 
-    self._timeout = timeout * self.tool.GetTimeoutScale()
+    self._timeout = min(timeout * self.tool.GetTimeoutScale(),
+                        _INFRA_STDOUT_TIMEOUT)
     if _TestSuiteRequiresHighPerfMode(self.test_package.suite_name):
       self._perf_controller = perf_control.PerfControl(self.device)
 
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index ac3f5b1..1dc3ed4 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -3,11 +3,14 @@
 # found in the LICENSE file.
 
 import logging
+import re
 import time
 
 from pylib import flag_changer
 from pylib.base import base_test_result
 from pylib.base import test_run
+from pylib.constants import keyevent
+from pylib.device import device_errors
 from pylib.local.device import local_device_test_run
 
 
@@ -27,16 +30,36 @@
 def DidPackageCrashOnDevice(package_name, device):
   # Dismiss any error dialogs. Limit the number in case we have an error
   # loop or we are failing to dismiss.
-  for _ in xrange(10):
-    package = device.old_interface.DismissCrashDialogIfNeeded()
-    if not package:
-      return False
-    # Assume test package convention of ".test" suffix
-    if package in package_name:
-      return True
+  try:
+    for _ in xrange(10):
+      package = _DismissCrashDialog(device)
+      if not package:
+        return False
+      # Assume test package convention of ".test" suffix
+      if package in package_name:
+        return True
+  except device_errors.CommandFailedError:
+    logging.exception('Error while attempting to dismiss crash dialog.')
   return False
 
 
+_CURRENT_FOCUS_CRASH_RE = re.compile(
+    r'\s*mCurrentFocus.*Application (Error|Not Responding): (\S+)}')
+
+
+def _DismissCrashDialog(device):
+  for l in device.RunShellCommand(
+      ['dumpsys', 'window', 'windows'], check_return=True):
+    m = re.match(_CURRENT_FOCUS_CRASH_RE, l)
+    if m:
+      device.SendKeyEvent(keyevent.KEYCODE_DPAD_RIGHT)
+      device.SendKeyEvent(keyevent.KEYCODE_DPAD_RIGHT)
+      device.SendKeyEvent(keyevent.KEYCODE_ENTER)
+      return m.group(2)
+
+  return None
+
+
 class LocalDeviceInstrumentationTestRun(
     local_device_test_run.LocalDeviceTestRun):
   def __init__(self, env, test_instance):
diff --git a/build/android/pylib/monkey/test_runner.py b/build/android/pylib/monkey/test_runner.py
index 19dd339..3fd1797 100644
--- a/build/android/pylib/monkey/test_runner.py
+++ b/build/android/pylib/monkey/test_runner.py
@@ -10,8 +10,11 @@
 from pylib import constants
 from pylib.base import base_test_result
 from pylib.base import base_test_runner
+from pylib.device import device_errors
 from pylib.device import intent
 
+_CHROME_PACKAGE = constants.PACKAGE_INFO['chrome'].package
+
 class TestRunner(base_test_runner.BaseTestRunner):
   """A TestRunner instance runs a monkey test on a single device."""
 
@@ -87,9 +90,17 @@
           test_name, base_test_result.ResultType.FAIL, log=output)
       if 'chrome' in self._options.package:
         logging.warning('Starting MinidumpUploadService...')
+        # TODO(jbudorick): Update this after upstreaming.
+        minidump_intent = intent.Intent(
+            action='%s.crash.ACTION_FIND_ALL' % _CHROME_PACKAGE,
+            package=self._package,
+            activity='%s.crash.MinidumpUploadService' % _CHROME_PACKAGE)
         try:
-          self.device.old_interface.StartCrashUploadService(self._package)
-        except AssertionError as e:
-          logging.error('Failed to start MinidumpUploadService: %s', e)
+          self.device.RunShellCommand(
+              ['am', 'startservice'] + minidump_intent.am_args,
+              as_root=True, check_return=True)
+        except device_errors.CommandFailedError:
+          logging.exception('Failed to start MinidumpUploadService')
+
     results.AddResult(result)
     return results, False
diff --git a/build/android/pylib/remote/device/appurify_constants.py b/build/android/pylib/remote/device/appurify_constants.py
new file mode 100644
index 0000000..93431782
--- /dev/null
+++ b/build/android/pylib/remote/device/appurify_constants.py
@@ -0,0 +1,57 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Defines a set of constants specific to appurify."""
+
+# Appurify network config constants.
+class NETWORK(object):
+  WIFI_1_BAR = 1
+  SPRINT_4G_LTE_4_BARS = 2
+  SPRINT_3G_5_BARS = 3
+  SPRINT_3G_4_BARS = 4
+  SPRINT_3G_3_BARS = 5
+  SPRINT_3G_2_BARS = 6
+  SPRINT_3G_1_BAR = 7
+  SPRING_4G_1_BAR = 8
+  VERIZON_3G_5_BARS = 9
+  VERIZON_3G_4_BARS = 10
+  VERIZON_3G_3_BARS = 11
+  VERIZON_3G_2_BARS = 12
+  VERIZON_3G_1_BAR = 13
+  VERIZON_4G_1_BAR = 14
+  ATANDT_3G_5_BARS = 15
+  ATANDT_3G_4_BARS = 16
+  ATANDT_3G_3_BARS = 17
+  ATANDT_3G_2_BARS = 18
+  ATANDT_3G_1_BAR = 19
+  GENERIC_2G_4_BARS = 20
+  GENERIC_2G_3_BARS = 21
+  GENERIC_EVOLVED_EDGE = 22
+  GENERIC_GPRS = 23
+  GENERIC_ENHANCED_GPRS = 24
+  GENERIC_LTE = 25
+  GENERIC_HIGH_LATENCY_DNS = 26
+  GENERIC_100_PERCENT_PACKET_LOSS = 27
+  ATANDT_HSPA_PLUS = 28
+  ATANDT_4G_LTE_4_BARS = 29
+  VERIZON_4G_LTE_4_BARS = 30
+  GENERIC_DIGITAL_SUBSCRIBE_LINE = 31
+  WIFI_STARBUCKS_3_BARS = 32
+  WIFI_STARBUCKS_4_BARS = 33
+  WIFI_STARBUCKS_HIGH_TRAFFIC = 34
+  WIFI_TARGET_1_BAR = 35
+  WIFI_TARGET_3_BARS = 36
+  WIFI_TARGET_4_BARS = 37
+  PUBLIC_WIFI_MCDONALDS_5_BARS = 38
+  PUBLIC_WIFI_MCDONALDS_4_BARS = 39
+  PUBLIC_WIFI_MCDONALDS_2_BARS = 40
+  PUBLIC_WIFI_MCDONALDS_1_BAR = 41
+  PUBLIC_WIFI_KOHLS_5_BARS = 42
+  PUBLIC_WIFI_KOHLS_4_BARS = 43
+  PUBLIC_WIFI_KOHLS_2_BARS = 44
+  PUBLIC_WIFI_ATANDT_5_BARS = 45
+  PUBLIC_WIFI_ATANDT_4_BARS = 46
+  PUBLIC_WIFI_ATANDT_2_BARS = 47
+  PUBLIC_WIFI_ATANDT_1_BAR = 48
+  BOINGO = 49
\ No newline at end of file
diff --git a/build/android/pylib/remote/device/remote_device_environment.py b/build/android/pylib/remote/device/remote_device_environment.py
index 8875096c..b69c7b2e 100644
--- a/build/android/pylib/remote/device/remote_device_environment.py
+++ b/build/android/pylib/remote/device/remote_device_environment.py
@@ -73,6 +73,7 @@
     self._api_secret = device_json.get('api_secret', None)
     self._device_oem = device_json.get('device_oem', None)
     self._device_type = device_json.get('device_type', 'Android')
+    self._network_config = device_json.get('network_config', None)
     self._remote_device = device_json.get('remote_device', None)
     self._remote_device_minimum_os = device_json.get(
         'remote_device_minimum_os', None)
@@ -81,9 +82,7 @@
     self._results_path = device_json.get('results_path', None)
     self._runner_package = device_json.get('runner_package', None)
     self._runner_type = device_json.get('runner_type', None)
-    if 'timeouts' in device_json:
-      for key in device_json['timeouts']:
-        self._timeouts[key] = device_json['timeouts'][key]
+    self._timeouts.update(device_json.get('timeouts', {}))
 
     def command_line_override(
         file_value, cmd_line_value, desc, print_value=True):
@@ -107,6 +106,8 @@
         self._device_oem, args.device_oem, 'device_oem')
     self._device_type = command_line_override(
         self._device_type, args.device_type, 'device_type')
+    self._network_config = command_line_override(
+        self._network_config, args.network_config, 'network_config')
     self._remote_device = command_line_override(
         self._remote_device, args.remote_device, 'remote_device')
     self._remote_device_minimum_os = command_line_override(
@@ -325,6 +326,10 @@
     return self._device['device_type_id']
 
   @property
+  def network_config(self):
+    return self._network_config
+
+  @property
   def only_output_failures(self):
     # TODO(jbudorick): Remove this once b/18981674 is fixed.
     return True
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py
index 4a155acc1..7aa91ae 100644
--- a/build/android/pylib/remote/device/remote_device_test_run.py
+++ b/build/android/pylib/remote/device/remote_device_test_run.py
@@ -14,6 +14,7 @@
 
 from pylib import constants
 from pylib.base import test_run
+from pylib.remote.device import appurify_constants
 from pylib.remote.device import appurify_sanitized
 from pylib.remote.device import remote_device_helper
 from pylib.utils import zip_utils
@@ -230,7 +231,10 @@
       self._test_id = self._UploadTestToDevice('robotium', test_path)
 
     logging.info('Setting config: %s' % config)
-    self._SetTestConfig('robotium', config)
+    appurify_configs = {}
+    if self._env.network_config:
+      appurify_configs['network'] = self._env.network_config
+    self._SetTestConfig('robotium', config, **appurify_configs)
 
   def _UploadAppToDevice(self, app_path):
     """Upload app to device."""
@@ -259,21 +263,32 @@
           'Unable to upload %s.' % test_path)
       return upload_results.json()['response']['test_id']
 
-  def _SetTestConfig(self, runner_type, body):
+  def _SetTestConfig(self, runner_type, runner_configs,
+                     network=appurify_constants.NETWORK.WIFI_1_BAR,
+                     pcap=0, profiler=0, videocapture=0):
     """Generates and uploads config file for test.
     Args:
-      extras: Extra arguments to set in the config file.
+      runner_configs: Configs specific to the runner you are using.
+      network: Config to specify the network environment the devices running
+          the tests will be in.
+      pcap: Option to set the recording the of network traffic from the device.
+      profiler: Option to set the recording of CPU, memory, and network
+          transfer usage in the tests.
+      videocapture: Option to set video capture during the tests.
+
     """
     logging.info('Generating config file for test.')
     with tempfile.TemporaryFile() as config:
       config_data = [
-        '[appurify]',
-        'pcap=0',
-        'profiler=0',
-        'videocapture=0',
-        '[%s]' % runner_type
+          '[appurify]',
+          'network=%s' % network,
+          'pcap=%s' % pcap,
+          'profiler=%s' % profiler,
+          'videocapture=%s' % videocapture,
+          '[%s]' % runner_type
       ]
-      config_data.extend('%s=%s' % (k, v) for k, v in body.iteritems())
+      config_data.extend(
+          '%s=%s' % (k, v) for k, v in runner_configs.iteritems())
       config.write(''.join('%s\n' % l for l in config_data))
       config.flush()
       config.seek(0)
@@ -282,4 +297,4 @@
         config_response = appurify_sanitized.api.config_upload(
             self._env.token, config, self._test_id)
       remote_device_helper.TestHttpResponse(
-          config_response, 'Unable to upload test config.')
+          config_response, 'Unable to upload test config.')
\ No newline at end of file
diff --git a/build/android/pylib/utils/emulator.py b/build/android/pylib/utils/emulator.py
index 81b9c98..26b9109 100644
--- a/build/android/pylib/utils/emulator.py
+++ b/build/android/pylib/utils/emulator.py
@@ -19,6 +19,7 @@
 from pylib import cmd_helper
 from pylib import constants
 from pylib import pexpect
+from pylib.device import device_errors
 from pylib.device import device_utils
 from pylib.utils import time_profile
 
@@ -394,33 +395,30 @@
     """
     seconds_waited = 0
     number_of_waits = 2  # Make sure we can wfd twice
-    # TODO(jbudorick) Un-handroll this in the implementation switch.
-    adb_cmd = "adb -s %s %s" % (self.device_serial, 'wait-for-device')
+
+    device = device_utils.DeviceUtils(self.device_serial)
     while seconds_waited < self._LAUNCH_TIMEOUT:
       try:
-        run_command.RunCommand(adb_cmd,
-                               timeout_time=self._WAITFORDEVICE_TIMEOUT,
-                               retry_count=1)
+        device.adb.WaitForDevice(
+            timeout=self._WAITFORDEVICE_TIMEOUT, retries=1)
         number_of_waits -= 1
         if not number_of_waits:
           break
-      except errors.WaitForResponseTimedOutError:
+      except device_errors.CommandTimeoutError:
         seconds_waited += self._WAITFORDEVICE_TIMEOUT
-        adb_cmd = "adb -s %s %s" % (self.device_serial, 'kill-server')
-        run_command.RunCommand(adb_cmd)
+        device.adb.KillServer()
       self.popen.poll()
       if self.popen.returncode != None:
         raise EmulatorLaunchException('EMULATOR DIED')
+
     if seconds_waited >= self._LAUNCH_TIMEOUT:
       raise EmulatorLaunchException('TIMEOUT with wait-for-device')
+
     logging.info('Seconds waited on wait-for-device: %d', seconds_waited)
     if wait_for_boot:
       # Now that we checked for obvious problems, wait for a boot complete.
       # Waiting for the package manager is sometimes problematic.
-      # TODO(jbudorick) Convert this once waiting for the package manager and
-      #                 the external storage is no longer problematic.
-      d = device_utils.DeviceUtils(self.device_serial)
-      d.old_interface.WaitForSystemBootCompleted(self._WAITFORBOOT_TIMEOUT)
+      device.WaitUntilFullyBooted(timeout=self._WAITFORBOOT_TIMEOUT)
 
   def Shutdown(self):
     """Shuts down the process started by launch."""
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 23d46b71..c54ed28d 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -152,6 +152,9 @@
                            'Overrides all other flags.'))
   group.add_argument('--remote-device-timeout', type=int,
                      help='Times to retry finding remote device')
+  group.add_argument('--network-config', type=int,
+                     help='Integer that specifies the network environment '
+                          'that the tests will be run in.')
 
   device_os_group = group.add_mutually_exclusive_group()
   device_os_group.add_argument('--remote-device-minimum-os',
diff --git a/build/build_config.h b/build/build_config.h
index 7137b4be..d8c3db6 100644
--- a/build/build_config.h
+++ b/build/build_config.h
@@ -61,11 +61,8 @@
 #error Please add support for your platform in build/build_config.h
 #endif
 
-#if defined(USE_OPENSSL) && defined(USE_NSS_CERTS)
-// TODO(davidben): This constraint compares somewhat orthogonal things and will
-// be fixed when BoringSSL with NSS for certificates is added as a build
-// configuration. See https://crbug.com/462040.
-#error Cannot use both OpenSSL and NSS
+#if defined(USE_OPENSSL_CERTS) && defined(USE_NSS_CERTS)
+#error Cannot use both OpenSSL and NSS for certificates
 #endif
 
 // For access to standard BSD features, use OS_BSD instead of a
diff --git a/build/common.gypi b/build/common.gypi
index c5a8e73..e43adfd 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -70,7 +70,10 @@
           # certificates, use_openssl_certs must be set.
           'use_openssl%': 0,
 
-          # Typedef X509Certificate::OSCertHandle to OpenSSL's struct X509*.
+          # Use OpenSSL for representing certificates. When targeting Android,
+          # the platform certificate library is used for certificate
+          # verification. On other targets, this flag also enables OpenSSL for
+          # certificate verification, but this configuration is unsupported.
           'use_openssl_certs%': 0,
 
           # Disable viewport meta tag by default.
@@ -681,20 +684,12 @@
         }],
 
         # NSS usage.
-        ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_openssl==0', {
+        ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris")', {
           'use_nss_certs%': 1,
         }, {
           'use_nss_certs%': 0,
         }],
 
-        # When OpenSSL is used for SSL and crypto on Unix-like systems, use
-        # OpenSSL's certificate definition.
-        ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_openssl==1', {
-          'use_openssl_certs%': 1,
-        }, {
-          'use_openssl_certs%': 0,
-        }],
-
         # libudev usage.  This currently only affects the content layer.
         ['OS=="linux" and embedded==0', {
           'use_udev%': 1,
@@ -5213,6 +5208,15 @@
                         }, {  # asan != 0
                           'STRIPFLAGS': '-S',
                         }],
+                        ['branding=="Chrome" and buildtype=="Official"', {
+                          'OTHER_CFLAGS': [
+                            # The Google Chrome Framework dSYM generated by
+                            # dsymutil has grown larger than 4GB, which
+                            # dsymutil can't handle. Reduce the amount of debug
+                            # symbols.
+                            '-gline-tables-only',  # See http://crbug.com/479841
+                          ]
+                        }],
                       ],
                     },  # xcode_settings
                   },  # configuration "Release"
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 471994d..22cb45a 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -122,10 +122,11 @@
   }
   if (use_openssl) {
     defines += [ "USE_OPENSSL=1" ]
-    if (use_openssl_certs) {
-      defines += [ "USE_OPENSSL_CERTS=1" ]
-    }
-  } else if (use_nss_certs) {
+  }
+  if (use_openssl_certs) {
+    defines += [ "USE_OPENSSL_CERTS=1" ]
+  }
+  if (use_nss_certs) {
     defines += [ "USE_NSS_CERTS=1" ]
   }
   if (use_ozone) {
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 679213f..a093879c 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -226,7 +226,8 @@
       dep_name = get_label_info(d, "name")
       possible_deps_configs += [ "$dep_gen_dir/$dep_name.build_config" ]
     }
-    rebase_possible_deps_configs = rebase_path(possible_deps_configs)
+    rebase_possible_deps_configs =
+        rebase_path(possible_deps_configs, root_build_dir)
 
     outputs = [
       depfile,
@@ -288,6 +289,19 @@
       args += [ "--bypass-platform-checks" ]
     }
 
+    if (defined(invoker.apk_under_test)) {
+      deps += [ invoker.apk_under_test ]
+      apk_under_test_gen_dir =
+          get_label_info(invoker.apk_under_test, "target_gen_dir")
+      apk_under_test_name = get_label_info(invoker.apk_under_test, "name")
+      apk_under_test_config =
+          "$apk_under_test_gen_dir/$apk_under_test_name.build_config"
+      args += [
+        "--tested-apk-config",
+        rebase_path(apk_under_test_config, root_build_dir),
+      ]
+    }
+
     if (is_android_resources || is_apk) {
       assert(defined(invoker.resources_zip))
       args += [
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 5c3bc24..7a49a5e 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1161,6 +1161,8 @@
 #   native_libs: List paths of native libraries to include in this apk. If these
 #     libraries depend on other shared_library targets, those dependencies will
 #     also be included in the apk.
+#   apk_under_test: For an instrumentation test apk, this is the target of the
+#     tested apk.
 #   testonly: Marks this target as "test-only".
 #
 #   DEPRECATED_java_in_dir: Directory containing java files. All .java files in
@@ -1194,7 +1196,7 @@
   assert(defined(invoker.final_apk_path) || defined(invoker.apk_name))
   gen_dir = "$target_gen_dir/$target_name"
   base_path = "$gen_dir/$target_name"
-  _build_config = "$base_path.build_config"
+  _build_config = "$target_gen_dir/$target_name.build_config"
   resources_zip_path = "$base_path.resources.zip"
   all_resources_zip_path = "$base_path.resources.all.zip"
   jar_path = "$base_path.jar"
@@ -1289,6 +1291,10 @@
       deps = invoker.deps
     }
 
+    if (defined(invoker.apk_under_test)) {
+      apk_under_test = invoker.apk_under_test
+    }
+
     native_libs = _native_libs
   }
 
diff --git a/build/config/crypto.gni b/build/config/crypto.gni
index ee23569..7f090b7 100644
--- a/build/config/crypto.gni
+++ b/build/config/crypto.gni
@@ -14,10 +14,13 @@
   use_openssl = is_android || is_mac || is_nacl || is_win
 }
 
-# True when we're using OpenSSL for certificate verification and storage. We
-# only do this when we're using OpenSSL on desktop Linux systems. For other
-# systems (Mac/Win/Android) we use the system certificate features.
-use_openssl_certs = use_openssl && (is_linux || is_android)
+# True when we're using OpenSSL for representing certificates. When targeting
+# Android, the platform certificate library is used for certificate
+# verification. On other targets, this flag also enables OpenSSL for certificate
+# verification, but this configuration is unsupported.
+use_openssl_certs = is_android
 
-# Same meaning as use_openssl_certs but for NSS.
-use_nss_certs = !use_openssl && is_linux
+# True if NSS is used for certificate verification. Note that this is
+# independent from use_openssl. It is possible to use OpenSSL for the crypto
+# library, but NSS for the platform certificate library.
+use_nss_certs = is_linux
diff --git a/build/config/features.gni b/build/config/features.gni
index 7ed7034..dd7b081 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -80,6 +80,10 @@
 
   # Enable hole punching for the protected video.
   enable_video_hole = is_android
+
+  # Enables browser side Content Decryption Modules. Required for embedders
+  # (e.g. Android and ChromeCast) that use a browser side CDM.
+  enable_browser_cdms = is_android
 }
 
 # Additional dependent variables -----------------------------------------------
@@ -102,8 +106,6 @@
 
 enable_pepper_cdms = enable_plugins && (is_linux || is_mac || is_win)
 
-enable_browser_cdms = is_android
-
 # Enable basic printing support and UI.
 enable_basic_printing = !is_chromeos
 
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index a34b9ca..76d3b59a 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -52,7 +52,6 @@
         '../chrome/chrome.gyp:interactive_ui_tests',
         '../chrome/chrome.gyp:load_library_perf_tests',
         '../chrome/chrome.gyp:performance_browser_tests',
-        '../chrome/chrome.gyp:service_discovery_sniffer',
         '../chrome/chrome.gyp:sync_integration_tests',
         '../chrome/chrome.gyp:sync_performance_tests',
         '../chrome/chrome.gyp:unit_tests',
@@ -199,7 +198,6 @@
         '../ui/display/display.gyp:display_unittests',
         '../ui/events/events.gyp:events_unittests',
         '../ui/gfx/gfx_tests.gyp:gfx_unittests',
-        '../ui/keyboard/keyboard.gyp:keyboard_unittests',
         '../ui/message_center/message_center.gyp:message_center_unittests',
         '../ui/snapshot/snapshot.gyp:snapshot_unittests',
         '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
@@ -225,6 +223,11 @@
             '../extensions/shell/app_shell.gyp:app_shell_unittests',
           ],
         }],
+        ['enable_mdns==1', {
+          'dependencies': [
+            '../chrome/chrome.gyp:service_discovery_sniffer',
+          ]
+        }],
         ['remoting==1', {
           'dependencies': [
             '../remoting/remoting_all.gyp:remoting_all',
@@ -259,6 +262,7 @@
             '../ui/aura/aura.gyp:aura_bench',
             '../ui/aura/aura.gyp:aura_demo',
             '../ui/aura/aura.gyp:aura_unittests',
+            '../ui/keyboard/keyboard.gyp:keyboard_unittests',
             '../ui/wm/wm.gyp:wm_unittests',
           ],
         }],
@@ -365,6 +369,16 @@
             '../rlz/rlz.gyp:rlz_unittests',
           ],
         }],
+        ['OS=="android" or OS=="linux" or os_bsd==1', {
+          'dependencies': [
+            '../breakpad/breakpad.gyp:core-2-minidump',
+            '../breakpad/breakpad.gyp:microdump_stackwalk',
+            '../breakpad/breakpad.gyp:minidump_dump',
+            '../breakpad/breakpad.gyp:minidump_stackwalk',
+            '../breakpad/breakpad.gyp:symupload',
+            '../third_party/codesighs/codesighs.gyp:nm2tsv',
+          ],
+        }],
         ['OS=="linux"', {
           'dependencies': [
             '../breakpad/breakpad.gyp:breakpad_unittests',
@@ -463,15 +477,6 @@
             '../third_party/pdfium/samples/samples.gyp:pdfium_diff',
             '../win8/win8.gyp:metro_viewer',
           ],
-        }, {
-          'dependencies': [
-            '../breakpad/breakpad.gyp:core-2-minidump',
-            '../breakpad/breakpad.gyp:microdump_stackwalk',
-            '../breakpad/breakpad.gyp:minidump_dump',
-            '../breakpad/breakpad.gyp:minidump_stackwalk',
-            '../breakpad/breakpad.gyp:symupload',
-            '../third_party/codesighs/codesighs.gyp:nm2tsv',
-          ],
         }],
       ],
     },
@@ -669,7 +674,6 @@
       'type': 'none',
       'dependencies': [
         'All',
-        'aura_builder',
         'blink_tests',
         'chromium_builder_asan',
         'chromium_builder_chromedriver',
@@ -680,6 +684,11 @@
         'chromium_gpu_debug_builder',
       ],
       'conditions': [
+        ['use_aura==1', {
+          'dependencies': [
+            'aura_builder',
+          ]
+        }],
         ['OS=="win"', {
           'dependencies': [
             'chromium_builder',
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index 5333798..cc6e81b 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -1180,8 +1180,7 @@
               'dependencies': [
                 '../../third_party/boringssl/boringssl.gyp:boringssl',
               ],
-            }],
-            ['use_openssl==0', {
+            }, {
               'dependencies': [
                 '../../net/third_party/nss/ssl.gyp:libssl',
               ],
@@ -1191,6 +1190,13 @@
                   # before other includes, as we are shadowing system headers.
                   '<(DEPTH)/net/third_party/nss/ssl',
                 ],
+              },
+            }],
+            # Link in the system NSS if it is used for either the internal
+            # crypto library (use_openssl==0) or platform certificate
+            # library (use_nss_certs==1).
+            ['use_openssl==0 or use_nss_certs==1', {
+              'direct_dependent_settings': {
                 'cflags': [
                   '<!@(<(pkg-config) --cflags nss)',
                 ],
@@ -1203,15 +1209,17 @@
                   '<!@(<(pkg-config) --libs-only-l nss | sed -e "s/-lssl3//")',
                 ],
               },
-            }],
-            ['use_openssl==0 and clang==1', {
-              'direct_dependent_settings': {
-                'cflags': [
-                  # There is a broken header guard in /usr/include/nss/secmod.h:
-                  # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
-                  '-Wno-header-guard',
-                ],
-              },
+              'conditions': [
+                ['clang==1', {
+                  'direct_dependent_settings': {
+                    'cflags': [
+                      # There is a broken header guard in /usr/include/nss/secmod.h:
+                      # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
+                      '-Wno-header-guard',
+                    ],
+                  },
+                }],
+              ],
             }],
           ]
         }],
diff --git a/build/linux/unbundle/libvpx.gyp b/build/linux/unbundle/libvpx.gyp
index cdcf6fa..75671c5 100644
--- a/build/linux/unbundle/libvpx.gyp
+++ b/build/linux/unbundle/libvpx.gyp
@@ -14,16 +14,17 @@
       'variables': {
         'headers_root_path': 'source/libvpx',
         'header_filenames': [
-          'vpx/vpx_codec_impl_bottom.h',
-          'vpx/vpx_image.h',
-          'vpx/vpx_decoder.h',
           'vpx/vp8.h',
-          'vpx/vpx_codec.h',
-          'vpx/vpx_codec_impl_top.h',
           'vpx/vp8cx.h',
-          'vpx/vpx_integer.h',
           'vpx/vp8dx.h',
+          'vpx/vpx_codec.h',
+          'vpx/vpx_codec_impl_bottom.h',
+          'vpx/vpx_codec_impl_top.h',
+          'vpx/vpx_decoder.h',
           'vpx/vpx_encoder.h',
+          'vpx/vpx_frame_buffer.h',
+          'vpx/vpx_image.h',
+          'vpx/vpx_integer.h',
         ],
       },
       'includes': [
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index f7aa1667..352b41f 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -122,6 +122,9 @@
 "race:base::PowerMonitor::RemoveObserver\n"
 "race:base::PowerMonitor::IsOnBatteryPower\n"
 
+// http://crbug.com/258935
+"race:base::Thread::StopSoon\n"
+
 // http://crbug.com/268941
 "race:tracked_objects::ThreadData::tls_index_\n"
 
@@ -292,6 +295,9 @@
 // https://crbug.com/430533
 "race:TileTaskGraphRunner::Run\n"
 
+// https://crbug.com/437044
+"race:SkEventTracer\n"
+
 // https://crbug.com/448203
 "race:blink::RemoteFrame::detach\n"
 
diff --git a/build/util/lastchange.py b/build/util/lastchange.py
index d1c33e8..1a7f519 100755
--- a/build/util/lastchange.py
+++ b/build/util/lastchange.py
@@ -115,6 +115,7 @@
       for line in reversed(output.splitlines()):
         if line.startswith('Cr-Commit-Position:'):
           pos = line.rsplit()[-1].strip()
+          break
   if not pos:
     return VersionInfo('git', hsh)
   return VersionInfo('git', '%s-%s' % (hsh, pos))
diff --git a/cc/OWNERS b/cc/OWNERS
index 5692349..b0bce1d 100644
--- a/cc/OWNERS
+++ b/cc/OWNERS
@@ -28,6 +28,7 @@
 brianderson@chromium.org
 skyostil@chromium.org
 mithro@mithis.com
+sunnyps@chromium.org
 
 # texture uploading
 brianderson@chromium.org
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc
index 3c688a6..8bad92a0 100644
--- a/cc/blink/web_layer_impl.cc
+++ b/cc/blink/web_layer_impl.cc
@@ -365,12 +365,27 @@
     const WebVector<std::pair<int64_t, WebRect>>& requests) {
   std::vector<cc::FrameTimingRequest> frame_timing_requests(requests.size());
   for (size_t i = 0; i < requests.size(); ++i) {
-    frame_timing_requests.push_back(cc::FrameTimingRequest(
-        requests[i].first, gfx::Rect(requests[i].second)));
+    frame_timing_requests[i] = cc::FrameTimingRequest(
+        requests[i].first, gfx::Rect(requests[i].second));
   }
   layer_->SetFrameTimingRequests(frame_timing_requests);
 }
 
+WebVector<std::pair<int64_t, WebRect>> WebLayerImpl::frameTimingRequests()
+    const {
+  const std::vector<cc::FrameTimingRequest>& frame_timing_requests =
+      layer_->FrameTimingRequests();
+
+  size_t num_requests = frame_timing_requests.size();
+
+  WebVector<std::pair<int64_t, WebRect>> result(num_requests);
+  for (size_t i = 0; i < num_requests; ++i) {
+    result[i] = std::make_pair(frame_timing_requests[i].id(),
+                               frame_timing_requests[i].rect());
+  }
+  return result;
+}
+
 void WebLayerImpl::setTouchEventHandlerRegion(const WebVector<WebRect>& rects) {
   cc::Region region;
   for (size_t i = 0; i < rects.size(); ++i)
diff --git a/cc/blink/web_layer_impl.h b/cc/blink/web_layer_impl.h
index 0560bed..beaf3b51 100644
--- a/cc/blink/web_layer_impl.h
+++ b/cc/blink/web_layer_impl.h
@@ -128,6 +128,8 @@
   virtual blink::WebScrollBlocksOn scrollBlocksOn() const;
   virtual void setFrameTimingRequests(
       const blink::WebVector<std::pair<int64_t, blink::WebRect>>& requests);
+  virtual blink::WebVector<std::pair<int64_t, blink::WebRect>>
+  frameTimingRequests() const;
   virtual void setIsContainerForFixedPositionLayers(bool is_container);
   virtual bool isContainerForFixedPositionLayers() const;
   virtual void setPositionConstraint(
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index d16c673..56b8c739 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -360,6 +360,7 @@
           clip_tree_index())) {
     if (clip_node->owner_id == id()) {
       clip_node->data.clip.set_size(size);
+      layer_tree_host_->property_trees()->clip_tree.set_needs_update(true);
     }
   }
 
@@ -614,6 +615,7 @@
       transform_node->data.update_post_local_transform(position,
                                                        transform_origin());
       transform_node->data.needs_local_transform_update = true;
+      layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
       SetNeedsCommitNoRebuild();
       return;
     }
@@ -663,6 +665,8 @@
             Are2dAxisAligned(transform_, transform, &invertible);
         transform_node->data.local = transform;
         transform_node->data.needs_local_transform_update = true;
+        layer_tree_host_->property_trees()->transform_tree.set_needs_update(
+            true);
         if (preserves_2d_axis_alignment)
           SetNeedsCommitNoRebuild();
         else
@@ -693,9 +697,11 @@
           layer_tree_host_->property_trees()->transform_tree.Node(
               transform_tree_index())) {
     if (transform_node->owner_id == id()) {
+      transform_node->data.update_pre_local_transform(transform_origin);
       transform_node->data.update_post_local_transform(position(),
                                                        transform_origin);
       transform_node->data.needs_local_transform_update = true;
+      layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
       SetNeedsCommitNoRebuild();
       return;
     }
@@ -789,6 +795,7 @@
       transform_node->data.scroll_offset =
           gfx::ScrollOffsetToVector2dF(CurrentScrollOffset());
       transform_node->data.needs_local_transform_update = true;
+      layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
       SetNeedsCommitNoRebuild();
       return;
     }
@@ -828,6 +835,7 @@
       transform_node->data.scroll_offset =
           gfx::ScrollOffsetToVector2dF(CurrentScrollOffset());
       transform_node->data.needs_local_transform_update = true;
+      layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
       needs_rebuild = false;
     }
   }
@@ -1319,6 +1327,8 @@
         node->data.local = transform;
         node->data.needs_local_transform_update = true;
         node->data.is_animated = true;
+        layer_tree_host_->property_trees()->transform_tree.set_needs_update(
+            true);
       }
     }
   }
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index dd554389..6f10725b 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -546,6 +546,11 @@
   // Sets new frame timing requests for this layer.
   void SetFrameTimingRequests(const std::vector<FrameTimingRequest>& requests);
 
+  // Accessor for unit tests
+  const std::vector<FrameTimingRequest>& FrameTimingRequests() const {
+    return frame_timing_requests_;
+  }
+
   void DidBeginTracing();
 
  protected:
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index e9188ec6..3fb0256 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -706,6 +706,7 @@
     int viewport_width = gpu_raster_max_texture_size_.width();
     int viewport_height = gpu_raster_max_texture_size_.height();
     default_tile_width = viewport_width;
+
     // Also, increase the height proportionally as the width decreases, and
     // pad by our border texels to make the tiles exactly match the viewport.
     int divisor = 4;
@@ -714,7 +715,11 @@
     if (content_bounds.width() <= viewport_width / 4)
       divisor = 1;
     default_tile_height = RoundUp(viewport_height, divisor) / divisor;
+
+    // Grow default sizes to account for overlapping border texels.
+    default_tile_width += 2 * PictureLayerTiling::kBorderTexels;
     default_tile_height += 2 * PictureLayerTiling::kBorderTexels;
+
     default_tile_height =
         std::max(default_tile_height, kMinHeightForGpuRasteredTile);
   } else {
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 966186f..2d2e330 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -299,6 +299,16 @@
     EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
   }
 
+  size_t NumberOfTilesRequired(PictureLayerTiling* tiling) {
+    size_t num_required = 0;
+    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
+    for (size_t i = 0; i < tiles.size(); ++i) {
+      if (tiles[i]->required_for_activation())
+        num_required++;
+    }
+    return num_required;
+  }
+
   void AssertAllTilesRequired(PictureLayerTiling* tiling) {
     std::vector<Tile*> tiles = tiling->AllTilesForTesting();
     for (size_t i = 0; i < tiles.size(); ++i)
@@ -2510,6 +2520,30 @@
   EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
 }
 
+TEST_F(PictureLayerImplTest, RequiredTilesWithGpuRasterization) {
+  host_impl_.SetUseGpuRasterization(true);
+
+  gfx::Size viewport_size(1000, 1000);
+  host_impl_.SetViewportSize(viewport_size);
+
+  gfx::Size layer_bounds(4000, 4000);
+  SetupDefaultTrees(layer_bounds);
+  EXPECT_TRUE(host_impl_.use_gpu_rasterization());
+
+  // Should only have the high-res tiling.
+  EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
+
+  active_layer_->SetAllTilesReady();
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  // High res tiling should have 64 tiles (4x16 tile grid).
+  EXPECT_EQ(64u, pending_layer_->HighResTiling()->AllTilesForTesting().size());
+
+  // Visible viewport should be covered by 4 tiles.  No other
+  // tiles should be required for activation.
+  EXPECT_EQ(4u, NumberOfTilesRequired(pending_layer_->HighResTiling()));
+}
+
 TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) {
   // Set up layers with tilings.
   SetupDefaultTrees(gfx::Size(10, 10));
@@ -4877,7 +4911,7 @@
 
   layer->set_gpu_raster_max_texture_size(host_impl_.device_viewport_size());
   result = layer->CalculateTileSize(gfx::Size(10000, 10000));
-  EXPECT_EQ(result.width(), 2000);
+  EXPECT_EQ(result.width(), 2000 + 2 * PictureLayerTiling::kBorderTexels);
   EXPECT_EQ(result.height(), 500 + 2);
 
   // Clamp and round-up, when smaller than viewport.
diff --git a/cc/quads/list_container.cc b/cc/quads/list_container.cc
index c5cbf87fa..d3442d4 100644
--- a/cc/quads/list_container.cc
+++ b/cc/quads/list_container.cc
@@ -138,6 +138,26 @@
     return storage_[id];
   }
 
+  size_t FirstInnerListId() const {
+    // |size_| > 0 means that at least one vector in |storage_| will be
+    // non-empty.
+    DCHECK_GT(size_, 0u);
+    size_t id = 0;
+    while (storage_[id]->size == 0)
+      ++id;
+    return id;
+  }
+
+  size_t LastInnerListId() const {
+    // |size_| > 0 means that at least one vector in |storage_| will be
+    // non-empty.
+    DCHECK_GT(size_, 0u);
+    size_t id = list_count_ - 1;
+    while (storage_[id]->size == 0)
+      --id;
+    return id;
+  }
+
   void AllocateNewList(size_t list_size) {
     ++list_count_;
     scoped_ptr<InnerList> new_list(new InnerList);
@@ -210,12 +230,16 @@
   typename ListContainerCharAllocator::InnerList* list =
       ptr_to_container->InnerListById(vector_index);
   if (item_iterator == list->LastElement()) {
-    if (vector_index < ptr_to_container->list_count() - 1) {
+    ++vector_index;
+    while (vector_index < ptr_to_container->list_count()) {
+      if (ptr_to_container->InnerListById(vector_index)->size != 0)
+        break;
       ++vector_index;
-      item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
-    } else {
-      item_iterator = NULL;
     }
+    if (vector_index < ptr_to_container->list_count())
+      item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
+    else
+      item_iterator = NULL;
   } else {
     item_iterator += list->step;
   }
@@ -229,8 +253,16 @@
   typename ListContainerCharAllocator::InnerList* list =
       ptr_to_container->InnerListById(vector_index);
   if (item_iterator == list->Begin()) {
-    if (vector_index > 0) {
+    --vector_index;
+    // Since |vector_index| is unsigned, we compare < list_count() instead of
+    // comparing >= 0, as the variable will wrap around when it goes out of
+    // range (below 0).
+    while (vector_index < ptr_to_container->list_count()) {
+      if (ptr_to_container->InnerListById(vector_index)->size != 0)
+        break;
       --vector_index;
+    }
+    if (vector_index < ptr_to_container->list_count()) {
       item_iterator =
           ptr_to_container->InnerListById(vector_index)->LastElement();
     } else {
@@ -281,17 +313,18 @@
 typename ListContainer<BaseElementType>::ConstReverseIterator
 ListContainer<BaseElementType>::crbegin() const {
   if (data_->IsEmpty())
-    return ConstReverseIterator(data_.get(), 0, NULL, 0);
+    return crend();
 
-  size_t last_id = data_->list_count() - 1;
-  return ConstReverseIterator(
-      data_.get(), last_id, data_->InnerListById(last_id)->LastElement(), 0);
+  size_t id = data_->LastInnerListId();
+  return ConstReverseIterator(data_.get(), id,
+                              data_->InnerListById(id)->LastElement(), 0);
 }
 
 template <typename BaseElementType>
 typename ListContainer<BaseElementType>::ConstReverseIterator
 ListContainer<BaseElementType>::crend() const {
-  return ConstReverseIterator(data_.get(), 0, NULL, size());
+  return ConstReverseIterator(data_.get(), static_cast<size_t>(-1), NULL,
+                              size());
 }
 
 template <typename BaseElementType>
@@ -310,26 +343,27 @@
 typename ListContainer<BaseElementType>::ReverseIterator
 ListContainer<BaseElementType>::rbegin() {
   if (data_->IsEmpty())
-    return ReverseIterator(data_.get(), 0, NULL, 0);
+    return rend();
 
-  size_t last_id = data_->list_count() - 1;
-  return ReverseIterator(
-      data_.get(), last_id, data_->InnerListById(last_id)->LastElement(), 0);
+  size_t id = data_->LastInnerListId();
+  return ReverseIterator(data_.get(), id,
+                         data_->InnerListById(id)->LastElement(), 0);
 }
 
 template <typename BaseElementType>
 typename ListContainer<BaseElementType>::ReverseIterator
 ListContainer<BaseElementType>::rend() {
-  return ReverseIterator(data_.get(), 0, NULL, size());
+  return ReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, size());
 }
 
 template <typename BaseElementType>
 typename ListContainer<BaseElementType>::ConstIterator
 ListContainer<BaseElementType>::cbegin() const {
   if (data_->IsEmpty())
-    return ConstIterator(data_.get(), 0, NULL, 0);
+    return cend();
 
-  return ConstIterator(data_.get(), 0, data_->InnerListById(0)->Begin(), 0);
+  size_t id = data_->FirstInnerListId();
+  return ConstIterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
 }
 
 template <typename BaseElementType>
@@ -338,8 +372,8 @@
   if (data_->IsEmpty())
     return ConstIterator(data_.get(), 0, NULL, size());
 
-  size_t last_id = data_->list_count() - 1;
-  return ConstIterator(data_.get(), last_id, NULL, size());
+  size_t id = data_->list_count();
+  return ConstIterator(data_.get(), id, NULL, size());
 }
 
 template <typename BaseElementType>
@@ -358,9 +392,10 @@
 typename ListContainer<BaseElementType>::Iterator
 ListContainer<BaseElementType>::begin() {
   if (data_->IsEmpty())
-    return Iterator(data_.get(), 0, NULL, 0);
+    return end();
 
-  return Iterator(data_.get(), 0, data_->InnerListById(0)->Begin(), 0);
+  size_t id = data_->FirstInnerListId();
+  return Iterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
 }
 
 template <typename BaseElementType>
@@ -369,8 +404,8 @@
   if (data_->IsEmpty())
     return Iterator(data_.get(), 0, NULL, size());
 
-  size_t last_id = data_->list_count() - 1;
-  return Iterator(data_.get(), last_id, NULL, size());
+  size_t id = data_->list_count();
+  return Iterator(data_.get(), id, NULL, size());
 }
 
 template <typename BaseElementType>
diff --git a/cc/quads/list_container_unittest.cc b/cc/quads/list_container_unittest.cc
index 68e6061..5de1ddd 100644
--- a/cc/quads/list_container_unittest.cc
+++ b/cc/quads/list_container_unittest.cc
@@ -487,6 +487,87 @@
   }
 }
 
+TEST(ListContainerTest, DeletionAllInAllocation) {
+  const size_t kReserve = 10;
+  ListContainer<DrawQuad> list(kLargestQuadSize, kReserve);
+  std::vector<SimpleDrawQuad*> sdq_list;
+  // Add enough quads to cause another allocation.
+  for (size_t i = 0; i < kReserve + 1; ++i) {
+    sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
+    sdq_list.back()->set_value(static_cast<int>(i));
+  }
+  EXPECT_EQ(kReserve + 1, list.size());
+
+  // Remove everything in the first allocation.
+  for (size_t i = 0; i < kReserve; ++i)
+    list.EraseAndInvalidateAllPointers(list.begin());
+  EXPECT_EQ(1u, list.size());
+
+  // The last quad is left.
+  SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*list.begin());
+  EXPECT_EQ(static_cast<int>(kReserve), quad->get_value());
+
+  // Remove the quad from the 2nd allocation.
+  list.EraseAndInvalidateAllPointers(list.begin());
+  EXPECT_EQ(0u, list.size());
+}
+
+TEST(ListContainerTest, DeletionAllInAllocationReversed) {
+  const size_t kReserve = 10;
+  ListContainer<DrawQuad> list(kLargestQuadSize, kReserve);
+  std::vector<SimpleDrawQuad*> sdq_list;
+  // Add enough quads to cause another allocation.
+  for (size_t i = 0; i < kReserve + 1; ++i) {
+    sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
+    sdq_list.back()->set_value(static_cast<int>(i));
+  }
+  EXPECT_EQ(kReserve + 1, list.size());
+
+  // Remove everything in the 2nd allocation.
+  auto it = list.begin();
+  for (size_t i = 0; i < kReserve; ++i)
+    ++it;
+  list.EraseAndInvalidateAllPointers(it);
+
+  // The 2nd-last quad is next, and the rest of the quads exist.
+  size_t i = kReserve - 1;
+  for (auto it = list.rbegin(); it != list.rend(); ++it) {
+    SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
+    EXPECT_EQ(static_cast<int>(i), quad->get_value());
+    --i;
+  }
+
+  // Can forward iterate too.
+  i = 0;
+  for (auto it = list.begin(); it != list.end(); ++it) {
+    SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
+    EXPECT_EQ(static_cast<int>(i), quad->get_value());
+    ++i;
+  }
+
+  // Remove the last thing from the 1st allocation.
+  it = list.begin();
+  for (size_t i = 0; i < kReserve - 1; ++i)
+    ++it;
+  list.EraseAndInvalidateAllPointers(it);
+
+  // The 2nd-last quad is next, and the rest of the quads exist.
+  i = kReserve - 2;
+  for (auto it = list.rbegin(); it != list.rend(); ++it) {
+    SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
+    EXPECT_EQ(static_cast<int>(i), quad->get_value());
+    --i;
+  }
+
+  // Can forward iterate too.
+  i = 0;
+  for (auto it = list.begin(); it != list.end(); ++it) {
+    SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
+    EXPECT_EQ(static_cast<int>(i), quad->get_value());
+    ++i;
+  }
+}
+
 TEST(ListContainerTest, SimpleIterationAndManipulation) {
   ListContainer<DrawQuad> list(kLargestQuadSize);
   std::vector<SimpleDrawQuad*> sdq_list;
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 9295d1aa..83b91f4 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -258,6 +258,8 @@
 }  // namespace
 
 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) {
+  if (!clip_tree->needs_update())
+    return;
   for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) {
     ClipNode* clip_node = clip_tree->Node(i);
 
@@ -339,17 +341,23 @@
 
     clip_node->data.combined_clip.Intersect(clip_node->data.clip);
   }
+  clip_tree->set_needs_update(false);
 }
 
 void ComputeTransforms(TransformTree* transform_tree) {
+  if (!transform_tree->needs_update())
+    return;
   for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i)
     transform_tree->UpdateTransforms(i);
+  transform_tree->set_needs_update(false);
 }
 
 template <typename LayerType>
 void ComputeVisibleRectsUsingPropertyTreesInternal(
     LayerType* root_layer,
     PropertyTrees* property_trees) {
+  if (property_trees->transform_tree.needs_update())
+    property_trees->clip_tree.set_needs_update(true);
   ComputeTransforms(&property_trees->transform_tree);
   ComputeClips(&property_trees->clip_tree, property_trees->transform_tree);
 
diff --git a/cc/trees/latency_info_swap_promise_monitor.cc b/cc/trees/latency_info_swap_promise_monitor.cc
index 83f5999..2b56f68c 100644
--- a/cc/trees/latency_info_swap_promise_monitor.cc
+++ b/cc/trees/latency_info_swap_promise_monitor.cc
@@ -82,10 +82,9 @@
     if (!new_sequence_number)
       return;
     ui::LatencyInfo new_latency;
-    new_latency.AddLatencyNumber(
+    new_latency.AddLatencyNumberWithTraceName(
         ui::INPUT_EVENT_LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT, 0,
-        new_sequence_number);
-    new_latency.TraceEventType("ScrollUpdate");
+        new_sequence_number, "ScrollUpdate");
     new_latency.CopyLatencyFrom(
         *latency_,
         ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT);
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 8683490..31f64d6 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -2557,25 +2557,27 @@
   PreCalculateMetaInformationRecursiveData recursive_data;
   PreCalculateMetaInformation(inputs->root_layer, &recursive_data);
 
-  if (!inputs->verify_property_trees) {
-    std::vector<AccumulatedSurfaceState<LayerType>> accumulated_surface_state;
-    CalculateDrawPropertiesInternal<LayerType>(
-        inputs->root_layer, globals, data_for_recursion,
-        inputs->render_surface_layer_list, &dummy_layer_list,
-        &accumulated_surface_state,
-        inputs->current_render_surface_layer_list_id);
-  } else {
-    {
-      TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
-                   "LayerTreeHostCommon::CalculateDrawProperties");
-      std::vector<AccumulatedSurfaceState<LayerType>> accumulated_surface_state;
-      CalculateDrawPropertiesInternal<LayerType>(
-          inputs->root_layer, globals, data_for_recursion,
-          inputs->render_surface_layer_list, &dummy_layer_list,
-          &accumulated_surface_state,
-          inputs->current_render_surface_layer_list_id);
-    }
+  const bool should_measure_property_tree_performance =
+      inputs->verify_property_trees &&
+      (property_tree_option == BUILD_PROPERTY_TREES_IF_NEEDED);
 
+  if (should_measure_property_tree_performance) {
+    TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+                       "LayerTreeHostCommon::CalculateDrawProperties");
+  }
+
+  std::vector<AccumulatedSurfaceState<LayerType>> accumulated_surface_state;
+  CalculateDrawPropertiesInternal<LayerType>(
+      inputs->root_layer, globals, data_for_recursion,
+      inputs->render_surface_layer_list, &dummy_layer_list,
+      &accumulated_surface_state, inputs->current_render_surface_layer_list_id);
+
+  if (should_measure_property_tree_performance) {
+    TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+                     "LayerTreeHostCommon::CalculateDrawProperties");
+  }
+
+  if (inputs->verify_property_trees) {
     // For testing purposes, sometimes property trees need to be built on the
     // compositor thread, so this can't just switch on Layer vs LayerImpl,
     // even though in practice only the main thread builds property trees.
@@ -2584,14 +2586,24 @@
         // The translation from layer to property trees is an intermediate
         // state. We will eventually get these data passed directly to the
         // compositor.
-        TRACE_EVENT0(
-            TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
-            "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
+        if (should_measure_property_tree_performance) {
+          TRACE_EVENT_BEGIN0(
+              TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+              "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
+        }
+
         BuildPropertyTreesAndComputeVisibleRects(
             inputs->root_layer, inputs->page_scale_application_layer,
             inputs->page_scale_factor, inputs->device_scale_factor,
             gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
             inputs->property_trees);
+
+        if (should_measure_property_tree_performance) {
+          TRACE_EVENT_END0(
+              TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+              "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
+        }
+
         break;
       }
       case DONT_BUILD_PROPERTY_TREES: {
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 3efac5b..e484b42 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -9195,5 +9195,31 @@
   EXPECT_TRUE(host->property_trees()->needs_rebuild);
 }
 
+TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) {
+  scoped_refptr<Layer> root = Layer::Create();
+  scoped_refptr<LayerWithForcedDrawsContent> child =
+      make_scoped_refptr(new LayerWithForcedDrawsContent());
+  root->AddChild(child);
+
+  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
+  host->SetRootLayer(root);
+
+  gfx::Transform identity_matrix;
+  gfx::Transform scale_matrix;
+  scale_matrix.Scale(2.f, 2.f);
+  SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
+                               gfx::PointF(), gfx::Size(100, 100), true, false);
+  SetLayerPropertiesForTesting(child.get(), scale_matrix, gfx::Point3F(),
+                               gfx::PointF(), gfx::Size(10, 10), true, false);
+
+  ExecuteCalculateDrawProperties(root.get());
+  EXPECT_EQ(gfx::Rect(10, 10), child->visible_rect_from_property_trees());
+
+  child->SetTransformOrigin(gfx::Point3F(10.f, 10.f, 10.f));
+
+  ExecuteCalculateDrawProperties(root.get());
+  EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_rect_from_property_trees());
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index b26e884..7f384456 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -12,7 +12,8 @@
 namespace cc {
 
 template <typename T>
-PropertyTree<T>::PropertyTree() {
+PropertyTree<T>::PropertyTree()
+    : needs_update_(false) {
   nodes_.push_back(T());
   back()->id = 0;
   back()->parent_id = -1;
@@ -62,6 +63,13 @@
 TransformNodeData::~TransformNodeData() {
 }
 
+void TransformNodeData::update_pre_local_transform(
+    const gfx::Point3F& transform_origin) {
+  pre_local.MakeIdentity();
+  pre_local.Translate3d(-transform_origin.x(), -transform_origin.y(),
+                        -transform_origin.z());
+}
+
 void TransformNodeData::update_post_local_transform(
     const gfx::PointF& position,
     const gfx::Point3F& transform_origin) {
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index fc8f5a2..42e2e169 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -105,6 +105,8 @@
     is_invertible = to_parent.IsInvertible();
   }
 
+  void update_pre_local_transform(const gfx::Point3F& transform_origin);
+
   void update_post_local_transform(const gfx::PointF& position,
                                    const gfx::Point3F& transform_origin);
 };
@@ -146,9 +148,14 @@
   void clear();
   size_t size() const { return nodes_.size(); }
 
+  void set_needs_update(bool needs_update) { needs_update_ = needs_update; }
+  bool needs_update() const { return needs_update_; }
+
  private:
   // Copy and assign are permitted. This is how we do tree sync.
   std::vector<T> nodes_;
+
+  bool needs_update_;
 };
 
 class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index 62f6313..269a71e 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -287,9 +287,7 @@
   }
 
   node->data.local = layer->transform();
-  node->data.pre_local.Translate3d(-layer->transform_origin().x(),
-                                   -layer->transform_origin().y(),
-                                   -layer->transform_origin().z());
+  node->data.update_pre_local_transform(layer->transform_origin());
 
   node->data.needs_local_transform_update = true;
   data_from_ancestor.transform_tree->UpdateTransforms(node->id);
@@ -414,6 +412,12 @@
       data_for_recursion.clip_tree->Insert(root_clip, 0);
   BuildPropertyTreesInternal(root_layer, data_for_recursion);
   property_trees->needs_rebuild = false;
+
+  // The transform tree is kept up-to-date as it is built, but the
+  // combined_clips stored in the clip tree aren't computed during tree
+  // building.
+  property_trees->transform_tree.set_needs_update(false);
+  property_trees->clip_tree.set_needs_update(true);
 }
 
 void PropertyTreeBuilder::BuildPropertyTrees(
diff --git a/cc/trees/property_tree_unittest.cc b/cc/trees/property_tree_unittest.cc
index 37fd523..d8ee10e 100644
--- a/cc/trees/property_tree_unittest.cc
+++ b/cc/trees/property_tree_unittest.cc
@@ -109,6 +109,7 @@
   tree.Node(grand_child)->data.flattens_inherited_transform = true;
   tree.Node(grand_child)->data.local = rotation_about_x;
 
+  tree.set_needs_update(true);
   ComputeTransforms(&tree);
 
   gfx::Transform flattened_rotation_about_x = rotation_about_x;
@@ -136,6 +137,7 @@
 
   // Remove flattening at grand_child, and recompute transforms.
   tree.Node(grand_child)->data.flattens_inherited_transform = false;
+  tree.set_needs_update(true);
   ComputeTransforms(&tree);
 
   EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x * rotation_about_x,
@@ -341,6 +343,7 @@
   tree.Node(grand_child)->data.target_id = grand_child;
   tree.Node(grand_child)->data.flattens_inherited_transform = true;
 
+  tree.set_needs_update(true);
   ComputeTransforms(&tree);
 
   gfx::Transform flattened_rotation_about_x = rotation_about_x;
diff --git a/chrome/VERSION b/chrome/VERSION
index abcd34d..721243e 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=44
 MINOR=0
-BUILD=2377
+BUILD=2379
 PATCH=0
diff --git a/chrome/android/java/res/layout/fre_spinner_dropdown.xml b/chrome/android/java/res/layout/fre_spinner_dropdown.xml
index 0358e79..ba06f4ee 100644
--- a/chrome/android/java/res/layout/fre_spinner_dropdown.xml
+++ b/chrome/android/java/res/layout/fre_spinner_dropdown.xml
@@ -14,4 +14,4 @@
     android:layout_height="wrap_content"
     android:textColor="@color/fre_text_color"
     android:textSize="@dimen/fre_normal_text_size"
-    android:padding="@dimen/fre_button_padding" />
\ No newline at end of file
+    android:padding="12dp" />
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/fre_spinner_text.xml b/chrome/android/java/res/layout/fre_spinner_text.xml
index c64afaa1..cb14ff1 100644
--- a/chrome/android/java/res/layout/fre_spinner_text.xml
+++ b/chrome/android/java/res/layout/fre_spinner_text.xml
@@ -10,7 +10,6 @@
     android:layout_height="wrap_content"
     android:maxWidth="216dp"
     android:layoutDirection="locale"
-    android:padding="@dimen/fre_button_padding"
     android:paddingBottom="16dp"
     android:paddingEnd="12dp"
     android:paddingStart="12dp"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 04eab23f..739e71b 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -113,7 +113,6 @@
     <dimen name="fre_margin">24dp</dimen>
     <dimen name="fre_title_text_size">24sp</dimen>
     <dimen name="fre_button_text_size">14sp</dimen>
-    <dimen name="fre_button_padding">12dp</dimen>
     <dimen name="fre_normal_text_size">14sp</dimen>
     <dimen name="fre_image_carousel_width">260dp</dimen>
     <dimen name="fre_image_carousel_height">130dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeContentViewClient.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeContentViewClient.java
deleted file mode 100644
index 569fc724..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeContentViewClient.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser;
-
-import org.chromium.chrome.browser.preferences.PrefServiceBridge;
-import org.chromium.content.browser.ContentViewClient;
-
-/**
- * The default {@link ContentViewClient} implementation for the chrome layer embedders.
- */
-public class ChromeContentViewClient extends ContentViewClient {
-
-    @Override
-    public boolean isJavascriptEnabled() {
-        return PrefServiceBridge.getInstance().javaScriptEnabled();
-    }
-
-}
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 1cec7a3..db202ccd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
@@ -476,7 +476,7 @@
      * ContentViewClient that provides basic tab functionality and is meant to be extended
      * by child classes.
      */
-    protected class TabContentViewClient extends ChromeContentViewClient {
+    protected class TabContentViewClient extends ContentViewClient {
         @Override
         public void onUpdateTitle(String title) {
             updateTitle(title);
@@ -1488,10 +1488,6 @@
         updateTitle();
         removeSadTabIfPresent();
 
-        if (getContentViewCore() != null) {
-            getContentViewCore().stopCurrentAccessibilityNotifications();
-        }
-
         clearHungRendererState();
 
         for (TabObserver observer : mObservers) observer.onPageLoadStarted(this);
@@ -1547,7 +1543,7 @@
      */
     protected void initContentViewCore(WebContents webContents) {
         ContentViewCore cvc = new ContentViewCore(mContext);
-        ContentView cv = ContentView.newInstance(mContext, cvc);
+        ContentView cv = new ContentView(mContext, cvc);
         cv.setContentDescription(mContext.getResources().getString(
                 R.string.accessibility_content_view));
         cvc.initialize(cv, cv, webContents, getWindowAndroid());
@@ -2165,7 +2161,7 @@
     private void swapWebContents(
             WebContents webContents, boolean didStartLoad, boolean didFinishLoad) {
         ContentViewCore cvc = new ContentViewCore(mContext);
-        ContentView cv = ContentView.newInstance(mContext, cvc);
+        ContentView cv = new ContentView(mContext, cvc);
         cv.setContentDescription(mContext.getResources().getString(
                 R.string.accessibility_content_view));
         cvc.initialize(cv, cv, webContents, getWindowAndroid());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
index 7e6a556..f7c8731 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
@@ -99,11 +99,9 @@
                                           Context context) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             return new LollipopTtsPlatformImpl(nativeTtsPlatformImplAndroid, context);
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
+        } else {
             return new TtsPlatformImpl(nativeTtsPlatformImplAndroid, context);
         }
-
-        return null;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentMetricIds.java b/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentMetricIds.java
index 9ede832..ca5c6d9c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentMetricIds.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentMetricIds.java
@@ -34,6 +34,7 @@
     public static final int STARTED_BY_EXTERNAL_APP_NEWS = 408;
     public static final int STARTED_BY_EXTERNAL_APP_LINE = 409;
     public static final int STARTED_BY_EXTERNAL_APP_WHATSAPP = 410;
+    public static final int STARTED_BY_EXTERNAL_APP_GSA = 411;
     public static final int STARTED_BY_CONTEXTUAL_SEARCH = 500;
 
     // DocumentActivity.OptOutDecision (enumerated)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
index c76adbd..df8d40a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
@@ -4,11 +4,8 @@
 
 package org.chromium.chrome.browser.download;
 
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Environment;
@@ -31,7 +28,6 @@
 import org.chromium.content_public.browser.WebContents;
 
 import java.io.File;
-import java.util.List;
 
 /**
  * Chrome implementation of the ContentViewDownloadDelegate interface.
@@ -131,45 +127,10 @@
             // Query the package manager to see if there's a registered handler that matches.
             Intent intent = new Intent(Intent.ACTION_VIEW);
             intent.setDataAndType(Uri.parse(downloadInfo.getUrl()), downloadInfo.getMimeType());
-            ResolveInfo info = mContext.getPackageManager().resolveActivity(intent,
-                    PackageManager.MATCH_DEFAULT_ONLY);
-            boolean activityResolved = false;
-            if (info != null) {
-                final String packageName = mContext.getPackageName();
-                if (info.match != 0) {
-                    // If we resolved to ourselves, we don't want to attempt to load the url only to
-                    // try and download it again.
-                    if (!packageName.equals(info.activityInfo.packageName)) {
-                        // Someone (other than us) knows how to handle this mime type with this
-                        // scheme, don't download.
-                        activityResolved = true;
-                    }
-                } else {
-                    // If we resolved to ResolverActivity, we should check if Chrome can be one of
-                    // options. If so, we don't want to show an intent picker.
-                    List<ResolveInfo> handlers = mContext.getPackageManager().queryIntentActivities(
-                            intent, PackageManager.MATCH_DEFAULT_ONLY);
-                    if (handlers != null && !handlers.isEmpty()) {
-                        activityResolved = true;
-                        for (ResolveInfo resolveInfo : handlers) {
-                            if (packageName.equals(resolveInfo.activityInfo.packageName)) {
-                                activityResolved = false;
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                if (activityResolved) {
-                    try {
-                        mContext.startActivity(intent);
-                        return;
-                    } catch (ActivityNotFoundException ex) {
-                        Log.d(LOGTAG, "activity not found for " + downloadInfo.getMimeType()
-                                + " over " + Uri.parse(downloadInfo.getUrl()).getScheme(), ex);
-                        // Best behavior is to fall back to a download in this case.
-                    }
-                }
+            // If the intent is resolved to ourselves, we don't want to attempt to load the url
+            // only to try and download it again.
+            if (DownloadManagerService.openIntent(mContext, intent, false)) {
+                return;
             }
         }
         onDownloadStartNoStream(downloadInfo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
index 75e1f05b..ffcd4d5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -11,6 +11,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -31,6 +33,7 @@
 
 import java.io.File;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -46,6 +49,7 @@
     private static final String DOWNLOAD_NOTIFICATION_IDS = "DownloadNotificationIds";
     private static final String DOWNLOAD_DIRECTORY = "Download";
     protected static final String PENDING_OMA_DOWNLOADS = "PendingOMADownloads";
+    private static final String PDF_VIEWER = "com.google.android.apps.docs";
     private static final long UPDATE_DELAY_MILLIS = 1000;
 
     private static DownloadManagerService sDownloadManagerService;
@@ -536,26 +540,20 @@
                 DownloadInfo info = mPendingAutoOpenDownloads.get(downloadId);
                 switch (status) {
                     case DownloadManager.STATUS_SUCCESSFUL:
-                        try {
-                            mPendingAutoOpenDownloads.remove(downloadId);
-                            if (OMADownloadHandler.OMA_DOWNLOAD_DESCRIPTOR_MIME.equalsIgnoreCase(
-                                    info.getMimeType())) {
-                                mOMADownloadHandler.handleOMADownload(
-                                        info, downloadId);
-                                manager.remove(downloadId);
-                                break;
-                            }
-                            Uri uri = manager.getUriForDownloadedFile(downloadId);
-                            Intent launchIntent = new Intent(Intent.ACTION_VIEW);
-
-                            launchIntent.setDataAndType(
-                                    uri, manager.getMimeTypeForDownloadedFile(downloadId));
-                            launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-                            mContext.startActivity(launchIntent);
-                        } catch (ActivityNotFoundException e) {
-                            Log.w(TAG, "Activity not found.");
+                        mPendingAutoOpenDownloads.remove(downloadId);
+                        if (OMADownloadHandler.OMA_DOWNLOAD_DESCRIPTOR_MIME.equalsIgnoreCase(
+                                info.getMimeType())) {
+                            mOMADownloadHandler.handleOMADownload(
+                                    info, downloadId);
+                            manager.remove(downloadId);
+                            break;
                         }
+                        Uri uri = manager.getUriForDownloadedFile(downloadId);
+                        Intent launchIntent = new Intent(Intent.ACTION_VIEW);
+                        launchIntent.setDataAndType(
+                                uri, manager.getMimeTypeForDownloadedFile(downloadId));
+                        launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        openIntent(mContext, launchIntent, true);
                         break;
                     case DownloadManager.STATUS_FAILED:
                         mPendingAutoOpenDownloads.remove(downloadId);
@@ -729,4 +727,63 @@
         return contentDisposition != null
                 && contentDisposition.regionMatches(true, 0, "attachment", 0, 10);
     }
+
+    /**
+     * Launch the best activity for the given intent. If a default activity is provided,
+     * choose the default one. Otherwise, return the Intent picker if there are more than one
+     * capable activities. If the intent is pdf type, return the platform pdf viewer if
+     * it is available so user don't need to choose it from Intent picker.
+     *
+     * @param context Context of the app.
+     * @param intent Intent to open.
+     * @param allowSelfOpen Whether chrome itself is allowed to open the intent.
+     * @return true if an Intent is launched, or false otherwise.
+     */
+    public static boolean openIntent(Context context, Intent intent, boolean allowSelfOpen) {
+        boolean activityResolved = false;
+        ResolveInfo info = context.getPackageManager().resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        if (info != null) {
+            final String packageName = context.getPackageName();
+            if (info.match != 0) {
+                if (allowSelfOpen || !packageName.equals(info.activityInfo.packageName)) {
+                    activityResolved = true;
+                }
+            } else {
+                // If we resolved to ResolverActivity, we should check if Chrome can be one of
+                // options. If so, we don't want to show an intent picker in case |allowSelfOpen|
+                // is false, unless plaform pdf viewer is one of the option.
+                List<ResolveInfo> handlers = context.getPackageManager().queryIntentActivities(
+                        intent, PackageManager.MATCH_DEFAULT_ONLY);
+                if (handlers != null && !handlers.isEmpty()) {
+                    activityResolved = true;
+                    boolean canSelfOpen = false;
+                    boolean hasPdfViewer = false;
+                    for (ResolveInfo resolveInfo : handlers) {
+                        String pName = resolveInfo.activityInfo.packageName;
+                        if (packageName.equals(pName)) {
+                            canSelfOpen = true;
+                        } else if (PDF_VIEWER.equals(pName)) {
+                            intent.setClassName(pName, resolveInfo.activityInfo.name);
+                            hasPdfViewer = true;
+                            break;
+                        }
+                    }
+                    if ((canSelfOpen && !allowSelfOpen) && !hasPdfViewer) {
+                        activityResolved = false;
+                    }
+                }
+            }
+        }
+        if (activityResolved) {
+            try {
+                context.startActivity(intent);
+                return true;
+            } catch (ActivityNotFoundException ex) {
+                Log.d(TAG, "activity not found for " + intent.getType()
+                        + " over " + intent.getData().getScheme(), ex);
+            }
+        }
+        return false;
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
index a4a940c..e03416e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -4,13 +4,11 @@
 
 package org.chromium.chrome.browser.externalnav;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.net.Uri;
-import android.os.Build;
 import android.provider.Browser;
 import android.util.Log;
 import android.webkit.WebView;
@@ -106,7 +104,6 @@
         return result;
     }
 
-    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
     private OverrideUrlLoadingResult shouldOverrideUrlLoadingInternal(
             ExternalNavigationParams params, Intent intent, boolean hasBrowserFallbackUrl,
             String browserFallbackUrl) {
@@ -254,13 +251,12 @@
         // security (only access to BROWSABLE activities).
         intent.addCategory(Intent.CATEGORY_BROWSABLE);
         intent.setComponent(null);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
-            Intent selector = intent.getSelector();
-            if (selector != null) {
-                selector.addCategory(Intent.CATEGORY_BROWSABLE);
-                selector.setComponent(null);
-            }
+        Intent selector = intent.getSelector();
+        if (selector != null) {
+            selector.addCategory(Intent.CATEGORY_BROWSABLE);
+            selector.setComponent(null);
         }
+
         // Set the Browser application ID to us in case the user chooses Chrome
         // as the app.  This will make sure the link is opened in the same tab
         // instead of making a new one.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/TransportControl.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/TransportControl.java
index 7cdf6373..77b74ec 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/TransportControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/TransportControl.java
@@ -32,7 +32,9 @@
         void onStop();
     }
 
-    private final Set<Listener> mListeners = new CopyOnWriteArraySet<Listener>();
+    // Initialized lazily to simplify testing. Should only ever be accessed through getListeners to
+    // ensure correct initialization.
+    private Set<Listener> mListeners;
     private String mScreenName;
     private String mError;
     protected RemoteVideoInfo mVideoInfo;
@@ -49,11 +51,11 @@
      * Sets the name to display for the device on the TransportControl.
      */
     public final void setScreenName(String screenName) {
-        if (TextUtils.equals(this.mScreenName, screenName)) {
+        if (TextUtils.equals(mScreenName, screenName)) {
             return;
         }
 
-        this.mScreenName = screenName;
+        mScreenName = screenName;
         onScreenNameChanged();
     }
 
@@ -71,11 +73,12 @@
      * {@link #clearError()}
      */
     public final void setError(String message) {
-        if (TextUtils.equals(mError, message)) {
+        String newError = TextUtils.isEmpty(message) ? null : message;
+        if (TextUtils.equals(mError, newError)) {
             return;
         }
 
-        mError = TextUtils.isEmpty(message) ? null : message;
+        mError = newError;
         onErrorChanged();
     }
 
@@ -107,11 +110,11 @@
      * @param videoInfo the video information to use.
      */
     public final void setVideoInfo(RemoteVideoInfo videoInfo) {
-        if (equal(this.mVideoInfo, videoInfo)) {
+        if (equal(mVideoInfo, videoInfo)) {
             return;
         }
 
-        this.mVideoInfo = videoInfo;
+        mVideoInfo = videoInfo;
         onVideoInfoChanged();
     }
 
@@ -127,11 +130,13 @@
      * Sets the poster bitmap to display on the TransportControl.
      */
     public final void setPosterBitmap(Bitmap posterBitmap) {
-        if (equal(this.mPosterBitmap, posterBitmap)) {
+        // Note that equality of bitmaps is simply an object comparison, so a copy will be treated
+        // as a new bitmap
+        if (equal(mPosterBitmap, posterBitmap)) {
             return;
         }
 
-        this.mPosterBitmap = posterBitmap;
+        mPosterBitmap = posterBitmap;
         onPosterBitmapChanged();
     }
 
@@ -140,7 +145,7 @@
      * @param listener the Listener to be registered.
      */
     public void addListener(Listener listener) {
-        mListeners.add(listener);
+        getListeners().add(listener);
     }
 
     /**
@@ -148,7 +153,7 @@
      * @param listener the Listener to be removed.
      */
     public void removeListener(Listener listener) {
-        mListeners.remove(listener);
+        getListeners().remove(listener);
     }
 
     /**
@@ -171,6 +176,7 @@
      * @return the current list of listeners.
      */
     protected final Set<Listener> getListeners() {
+        if (mListeners == null) mListeners = new CopyOnWriteArraySet<Listener>();
         return mListeners;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
index 476649c..602d354 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
@@ -15,7 +15,10 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.v4.app.NotificationCompat;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
+import android.text.style.StyleSpan;
 import android.util.Log;
 
 import org.chromium.base.CalledByNative;
@@ -345,6 +348,7 @@
                 .addAction(R.drawable.settings_cog,
                            res.getString(R.string.page_info_site_settings_button),
                            pendingSettingsIntent)
+                .setTicker(createTickerText(title, body))
                 .setSubText(origin);
 
         // Use the system's default ringtone, vibration and indicator lights unless the notification
@@ -356,6 +360,28 @@
     }
 
     /**
+     * Creates the ticker text for a notification having |title| and |body|. The notification's
+     * title will be printed in bold, followed by the text of the body.
+     *
+     * @param title Title of the notification.
+     * @param body Textual contents of the notification.
+     * @return A character sequence containing the ticker's text.
+     */
+    private CharSequence createTickerText(String title, String body) {
+        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
+
+        spannableStringBuilder.append(title);
+        spannableStringBuilder.append("\n");
+        spannableStringBuilder.append(body);
+
+        // Mark the title of the notification as being bold.
+        spannableStringBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
+                0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+
+        return spannableStringBuilder;
+    }
+
+    /**
      * Ensures the existance of an icon generator, which is created lazily.
      *
      * @return The icon generator which can be used.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TransitionPageHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TransitionPageHelper.java
index 4f124de8..e97f8b5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TransitionPageHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TransitionPageHelper.java
@@ -24,11 +24,11 @@
 import org.chromium.base.ApplicationStatus.ActivityStateListener;
 import org.chromium.base.CalledByNative;
 import org.chromium.base.FieldTrialList;
-import org.chromium.chrome.browser.ChromeContentViewClient;
 import org.chromium.chrome.browser.ContentViewUtil;
 import org.chromium.chrome.browser.EmptyTabObserver;
 import org.chromium.chrome.browser.Tab;
 import org.chromium.content.browser.ContentView;
+import org.chromium.content.browser.ContentViewClient;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.JavaScriptCallback;
 import org.chromium.content_public.browser.LoadUrlParams;
@@ -600,7 +600,7 @@
         if (mNativeTransitionPageHelperPtr == 0) return;
 
         mTransitionContentViewCore = new ContentViewCore(mContext);
-        ContentView cv = ContentView.newInstance(mContext, mTransitionContentViewCore);
+        ContentView cv = new ContentView(mContext, mTransitionContentViewCore);
         mTransitionContentViewCore.initialize(cv, cv,
                 ContentViewUtil.createWebContentsWithSharedSiteInstance(mSourceContentViewCore),
                 mWindowAndroid);
@@ -617,7 +617,7 @@
         nativeSetWebContents(mNativeTransitionPageHelperPtr, mTransitionContentViewCore);
         setTransitionOpacity(0.0f);
 
-        mTransitionContentViewCore.setContentViewClient(new ChromeContentViewClient() {
+        mTransitionContentViewCore.setContentViewClient(new ContentViewClient() {
             @Override
             public void onOffsetsForFullscreenChanged(
                     float topControlsOffsetYPix,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/InterceptNavigationDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/InterceptNavigationDelegateTest.java
index 7d77bec..7980c4d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/InterceptNavigationDelegateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/InterceptNavigationDelegateTest.java
@@ -34,6 +34,8 @@
             BASE_URL + "navigation_from_xhr_callback_and_short_timeout.html";
     private static final String NAVIGATION_FROM_XHR_CALLBACK_AND_LONG_TIMEOUT_PAGE =
             BASE_URL + "navigation_from_xhr_callback_and_long_timeout.html";
+    private static final String NAVIGATION_FROM_IMAGE_ONLOAD_PAGE =
+            BASE_URL + "navigation_from_image_onload.html";
 
     private static final long DEFAULT_MAX_TIME_TO_WAIT_IN_MS = 3000;
     private static final long LONG_MAX_TIME_TO_WAIT_IN_MS = 20000;
@@ -136,4 +138,15 @@
         assertEquals(false, mHistory.get(1).hasUserGesture);
         assertEquals(false, mHistory.get(1).hasUserGestureCarryover);
     }
+
+    @SmallTest
+    public void testNavigationFromImageOnLoad() throws InterruptedException {
+        loadUrlWithSanitization(TestHttpServerClient.getUrl(NAVIGATION_FROM_IMAGE_ONLOAD_PAGE));
+        assertEquals(1, mHistory.size());
+
+        TouchCommon.singleClickView(mActivity.getActiveTab().getView(), 25, 25);
+        waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
+        assertEquals(false, mHistory.get(1).hasUserGesture);
+        assertEquals(true, mHistory.get(1).hasUserGestureCarryover);
+    }
 }
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
index 42426a60..c44b6c8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.externalnav;
 
-import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -12,7 +11,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
-import android.os.Build;
 import android.os.SystemClock;
 import android.provider.Browser;
 import android.test.InstrumentationTestCase;
@@ -983,7 +981,6 @@
                 intent.getComponent());
     }
 
-    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
     public void check(String url,
                       String referrerUrl,
                       boolean isIncognito,
@@ -1015,11 +1012,9 @@
 
         if (startActivityCalled && expectSaneIntent) {
             checkIntentSanity(mDelegate.startActivityIntent, "Intent");
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
-                if (mDelegate.startActivityIntent.getSelector() != null) {
-                    checkIntentSanity(mDelegate.startActivityIntent.getSelector(),
-                            "Intent's selector");
-                }
+            if (mDelegate.startActivityIntent.getSelector() != null) {
+                checkIntentSanity(mDelegate.startActivityIntent.getSelector(),
+                        "Intent's selector");
             }
         }
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
index 306b11c..2989bfd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
@@ -77,7 +77,7 @@
                 WindowAndroid windowAndroid = new ActivityWindowAndroid(getActivity());
 
                 ContentViewCore contentViewCore = new ContentViewCore(getActivity());
-                ContentView cv = ContentView.newInstance(getActivity(), contentViewCore);
+                ContentView cv = new ContentView(getActivity(), contentViewCore);
                 contentViewCore.initialize(cv, cv, webContents, windowAndroid);
                 contentViewCore.destroy();
             }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
index 39b2634..7e14a0c5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.notifications;
 
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
 import android.app.Notification;
 import android.graphics.Bitmap;
 import android.os.Build;
@@ -39,6 +41,12 @@
     private static final String NOTIFICATION_TEST_PAGE =
             TestHttpServerClient.getUrl("chrome/test/data/notifications/android_test.html");
 
+    /** The maximum time to wait for a criteria to become valid. */
+    private static final long MAX_TIME_TO_POLL_MS = scaleTimeout(6000);
+
+    /** The polling interval to wait between checking for a satisfied criteria. */
+    private static final long POLLING_INTERVAL_MS = 50;
+
     private MockNotificationManagerProxy mMockNotificationManager;
 
     /**
@@ -117,7 +125,7 @@
             public boolean isSatisfied() {
                 return mMockNotificationManager.getMutationCountAndDecrement() > 0;
             }
-        });
+        }, MAX_TIME_TO_POLL_MS, POLLING_INTERVAL_MS);
     }
 
     @Override
@@ -154,6 +162,12 @@
         assertEquals("Hello", notification.extras.getString(Notification.EXTRA_TEXT));
         assertEquals(getOrigin(), notification.extras.getString(Notification.EXTRA_SUB_TEXT));
 
+        // Verify that the ticker text contains the notification's title and body.
+        String tickerText = notification.tickerText.toString();
+
+        assertTrue(tickerText.contains("MyNotification"));
+        assertTrue(tickerText.contains("Hello"));
+
         // Validate the appearance style of the notification. The EXTRA_TEMPLATE was inroduced
         // in Android Lollipop, we cannot verify this in earlier versions.
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java
deleted file mode 100644
index 6ad87a99..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java
+++ /dev/null
@@ -1,362 +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.omaha;
-
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Xml;
-
-import org.chromium.base.test.util.Feature;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-/**
- * Unit tests for the Omaha ResponseParser.
- */
-public class ResponseParserTest extends InstrumentationTestCase {
-    // Note that the Omaha server appends "/" to the end of the URL codebase.
-    private static final String STRIPPED_URL =
-            "https://play.google.com/store/apps/details?id=com.google.android.apps.chrome";
-    private static final String URL = STRIPPED_URL + "/";
-    private static final String NEXT_VERSION = "1.2.3.4";
-
-    private static final String APP_STATUS_OK = "ok";
-    private static final String APP_STATUS_RESTRICTED = "restricted";
-    private static final String APP_STATUS_ERROR = "error-whatever-else";
-
-    private static final String UPDATE_STATUS_OK = "ok";
-    private static final String UPDATE_STATUS_NOUPDATE = "noupdate";
-    private static final String UPDATE_STATUS_ERROR = "error-osnotsupported";
-    private static final String UPDATE_STATUS_WTF = "omgwtfbbq";
-
-    /**
-     * Create XML for testing.
-     * @param xmlProtocol Version number of the protocol.  Expected to be "3.0" for valid XML.
-     * @param elapsedSeconds Number of seconds since server midnight.
-     * @param appStatus Status to use for the <app> element.
-     * @param addInstall Whether or not to add an install event.
-     * @param addPing Whether or not to add a ping event.
-     * @param updateStatus Status to use for the <updatecheck> element.
-     * @return The completed XML.
-     */
-    private static String createTestXML(String xmlProtocol, String elapsedSeconds,
-            String appStatus, boolean addInstall, boolean addPing, String updateStatus,
-            String updateUrl) {
-        StringWriter writer = new StringWriter();
-        try {
-            XmlSerializer serializer = Xml.newSerializer();
-            serializer.setOutput(writer);
-            serializer.startDocument("UTF-8", true);
-
-            // Set up <response ...>
-            serializer.startTag(null, "response");
-            serializer.attribute(null, "server", "prod");
-            if (xmlProtocol != null) {
-                serializer.attribute(null, "protocol", xmlProtocol);
-            }
-
-            // Create <daystart> element.
-            if (elapsedSeconds != null) {
-                serializer.startTag(null, "daystart");
-                serializer.attribute(null, "elapsed_seconds", elapsedSeconds);
-                serializer.endTag(null, "daystart");
-            }
-
-            // Create <app> element with unused attribute.
-            serializer.startTag(null, "app");
-            serializer.attribute(null, "appid", "{APP_ID}");
-            serializer.attribute(null, "status", appStatus);
-            serializer.attribute(null, "unused", "attribute");
-
-            if (addInstall) {
-                serializer.startTag(null, "event");
-                serializer.attribute(null, "status", "ok");
-                serializer.endTag(null, "event");
-            }
-
-            if (addPing) {
-                serializer.startTag(null, "ping");
-                serializer.attribute(null, "status", "ok");
-                serializer.endTag(null, "ping");
-            }
-
-            if (updateStatus != null) {
-                serializer.startTag(null, "updatecheck");
-                serializer.attribute(null, "status", updateStatus);
-                if (UPDATE_STATUS_OK.equals(updateStatus)) {
-                    createUpdateXML(serializer, updateUrl);
-                }
-                serializer.endTag(null, "updatecheck");
-            }
-            serializer.endTag(null, "app");
-
-            // Create extraneous tag.
-            serializer.startTag(null, "extraneous");
-            serializer.attribute(null, "useless", "yes");
-            serializer.endTag(null, "extraneous");
-
-            serializer.endTag(null, "response");
-            serializer.endDocument();
-        } catch (IOException e) {
-            fail("Caught an IOException creating the XML: " + e);
-        } catch (IllegalArgumentException e) {
-            fail("Caught an IllegalArgumentException creating the XML: " + e);
-        } catch (IllegalStateException e) {
-            fail("Caught an IllegalStateException creating the XML: " + e);
-        }
-
-        return writer.toString();
-    }
-
-    private static void createUpdateXML(XmlSerializer serializer, String updateUrl)
-            throws IOException {
-        // End result should look something like:
-        // <updatecheck status="ok">
-        //  <urls>
-        //    <url codebase="URL" />
-        //  </urls>
-        //  <manifest garbage="attribute" version="NEXT_VERSION">
-        //    <packages>
-        //      <package hash="0" name="dummy.apk" required="true" size="0" />
-        //    </packages>
-        //    <actions>
-        //      <action event="install" run="dummy.apk" />
-        //      <action event="postinstall" />
-        //    </actions>
-        //  </manifest>
-        //  <better be="ignored" />
-        //</updatecheck>
-
-        // Create <urls> and its descendants.
-        serializer.startTag(null, "urls");
-        if (updateUrl != null) {
-            serializer.startTag(null, "url");
-            serializer.attribute(null, "codebase", updateUrl);
-            serializer.endTag(null, "url");
-        }
-        serializer.endTag(null, "urls");
-
-        // Create <manifest> and its descendants.
-        serializer.startTag(null, "manifest");
-        serializer.attribute(null, "garbage", "attribute");
-        serializer.attribute(null, "version", NEXT_VERSION);
-
-        // Create <packages> and its children.
-        serializer.startTag(null, "packages");
-        serializer.startTag(null, "package");
-        serializer.attribute(null, "hash", "0");
-        serializer.attribute(null, "name", "dummy.apk");
-        serializer.attribute(null, "required", "true");
-        serializer.attribute(null, "size", "0");
-        serializer.endTag(null, "package");
-        serializer.endTag(null, "packages");
-
-        // Create <actions> and its children.
-        serializer.startTag(null, "actions");
-        serializer.startTag(null, "action");
-        serializer.attribute(null, "event", "install");
-        serializer.attribute(null, "run", "dummy.apk");
-        serializer.endTag(null, "action");
-
-        serializer.startTag(null, "action");
-        serializer.attribute(null, "event", "postinstall");
-        serializer.endTag(null, "action");
-        serializer.endTag(null, "actions");
-        serializer.endTag(null, "manifest");
-
-        // Create a dummy element for testing to make sure it's ignored.
-        serializer.startTag(null, "dummy");
-        serializer.attribute(null, "hopefully", "ignored");
-        serializer.endTag(null, "dummy");
-    }
-
-    /**
-     * Runs a test that is expected to pass.
-     * @param appStatus Status to use for the <app> element.
-     * @param addInstall Whether or not to add an install event.
-     * @param addPing Whether or not to add a ping.
-     * @param updateStatus Status to use for the <updatecheck> element.
-     * @throws RequestFailureException Thrown if the test fails.
-     */
-    private static void runSuccessTest(String appStatus, boolean addInstall, boolean addPing,
-            String updateStatus) throws RequestFailureException {
-        String xml =
-                createTestXML("3.0", "12345", appStatus, addInstall, addPing, updateStatus, URL);
-        ResponseParser parser =
-                new ResponseParser(true, "{APP_ID}", addInstall, addPing, updateStatus != null);
-        parser.parseResponse(xml);
-
-        assertEquals("elapsed_seconds doesn't match.", 12345, parser.getDaystartSeconds());
-        assertEquals("<app> status doesn't match.", appStatus, parser.getAppStatus());
-        assertEquals("<updatecheck> status doesn't match.", updateStatus, parser.getUpdateStatus());
-        if (UPDATE_STATUS_OK.equals(updateStatus)) {
-            assertEquals("Version number doesn't match.", "1.2.3.4", parser.getNewVersion());
-            assertEquals("Market URL doesn't match.", STRIPPED_URL, parser.getURL());
-        } else {
-            assertEquals("Version number doesn't match.", null, parser.getNewVersion());
-            assertEquals("Market URL doesn't match.", null, parser.getURL());
-        }
-    }
-
-    /**
-     * Runs a test that is expected to fail in a particular way.
-     * @param xml XML to parse.
-     * @param expectedErrorCode Expected error code.
-     * @param expectInstall Whether or not the parser should expect an install event.
-     * @param expectPing Whether or not the parser should expect a ping element.
-     * @param expectUpdate Whether or not the parser should expect an update check.
-     */
-    private static void runFailureTest(String xml, int expectedErrorCode,
-            boolean expectInstall, boolean expectPing, boolean expectUpdate) {
-        ResponseParser parser =
-                new ResponseParser(true, "{APP_ID}", expectInstall, expectPing, expectUpdate);
-
-        try {
-            parser.parseResponse(xml);
-        } catch (RequestFailureException e) {
-            assertEquals("Incorrect error code received.", expectedErrorCode, e.errorCode);
-            return;
-        }
-
-        fail("Failed to throw RequestFailureException for bad XML.");
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidAllTypes() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, true, true, UPDATE_STATUS_OK);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidNoInstall() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, false, true, UPDATE_STATUS_OK);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidNoPing() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, true, false, UPDATE_STATUS_OK);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidNoUpdatecheck() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, true, true, null);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidUpdatecheckNoUpdate() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_NOUPDATE);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidUpdatecheckError() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_ERROR);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidUpdatecheckUnknown() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_WTF);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testValidAppStatusRestricted() throws RequestFailureException {
-        runSuccessTest(APP_STATUS_RESTRICTED, false, false, null);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testFailBogusResponse() {
-        String xml = "Bogus";
-        runFailureTest(xml, RequestFailureException.ERROR_MALFORMED_XML, false, false, false);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testBadResponseProtocol() {
-        String xml =
-                createTestXML("2.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_RESPONSE, false, false, false);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testFailMissingDaystart() {
-        String xml =
-                createTestXML("3.0", null, APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_DAYSTART, false, false, true);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagMissingUpdatecheck() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_OK, true, false, null, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_UPDATECHECK, true, false, true);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagUnexpectedUpdatecheck() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_OK, true, false, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_UPDATECHECK, true, false, false);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagMissingPing() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_PING, false, true, true);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagUnexpectedPing() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_OK, false, true, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_PING, false, false, true);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagMissingInstall() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_EVENT, true, false, true);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagUnexpectedInstall() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_OK, true, false, UPDATE_STATUS_OK, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_EVENT, false, false, true);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testAppTagStatusError() {
-        String xml =
-                createTestXML("3.0", "12345", APP_STATUS_ERROR, false, false, null, URL);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_APP, false, false, false);
-    }
-
-    @SmallTest
-    @Feature({"Omaha"})
-    public void testUpdatecheckMissingUrl() {
-        String xml = createTestXML(
-                "3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, null);
-        runFailureTest(xml, RequestFailureException.ERROR_PARSE_URLS, false, false, true);
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/TransportControlTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/TransportControlTest.java
new file mode 100644
index 0000000..d47a1c8
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/TransportControlTest.java
@@ -0,0 +1,198 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+package org.chromium.chrome.browser.media.remote;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.annotation.Config;
+
+/**
+ * Robolectric tests of TransportControl class
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class TransportControlTest {
+
+    TransportControl mTransportControl;
+
+    @Before
+    public void setUp() {
+        mTransportControl = Mockito.mock(TransportControl.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    /**
+     * Test method for {@link TransportControl#setScreenName} .
+     */
+    @Test
+    @Feature("MediaRemote")
+    public void testSetScreenName() {
+        mTransportControl.setScreenName("Name1");
+        assertThat("getScreenName should return the last screen name set",
+                mTransportControl.getScreenName(), equalTo("Name1"));
+        // Check that onScreenNameChanged is called precisely once
+        verify(mTransportControl).onScreenNameChanged();
+        // Try setting the same screen name again
+        mTransportControl.setScreenName("Name1");
+        // There should still have only been one call to onScreenNameChanged
+        verify(mTransportControl).onScreenNameChanged();
+        // And try a different screen name
+        mTransportControl.setScreenName("Name2");
+        assertThat("getScreenName should return the last screen name set",
+                mTransportControl.getScreenName(), equalTo("Name2"));
+        // Now there should have been two calls
+        verify(mTransportControl, times(2)).onScreenNameChanged();
+    }
+
+    /**
+     * Test method for {@link TransportControl#setError} .
+     */
+    @Test
+    @Feature("MediaRemote")
+    public void testSetError() {
+        mTransportControl.setError("Error1");
+        assertThat("getError should return the last error set", mTransportControl.getError(),
+                equalTo("Error1"));
+        // Check that onErrorChanged is called precisely once
+        verify(mTransportControl).onErrorChanged();
+        // Try setting the same error again
+        mTransportControl.setError("Error1");
+        // There should still have only been one call to onErrorChanged
+        verify(mTransportControl).onErrorChanged();
+        // And try a different error message
+        mTransportControl.setError("Error2");
+        assertThat("getError should return the last screen name set", mTransportControl.getError(),
+                equalTo("Error2"));
+        // Now there should have been two calls
+        verify(mTransportControl, times(2)).onErrorChanged();
+        // Now try with an empty string
+        mTransportControl.setError("");
+        assertThat("empty error string should set error to null", mTransportControl.getError(),
+                nullValue());
+        verify(mTransportControl, times(3)).onErrorChanged();
+        // Try setting the empty string a second time, should not call onErrorChanged
+        mTransportControl.setError("");
+        verify(mTransportControl, times(3)).onErrorChanged();
+        // Also try null, which should be equivalent to an empty string
+        mTransportControl.setError(null);
+        verify(mTransportControl, times(3)).onErrorChanged();
+    }
+
+    /**
+     * Test method for {@link TransportControl#setVideoInfo} .
+     */
+    @Test
+    @Feature("MediaRemote")
+    public void testSetVideoInfo() {
+        RemoteVideoInfo videoInfo1 = new RemoteVideoInfo("Title1", 10,
+                RemoteVideoInfo.PlayerState.STOPPED, 5, "Error1");
+        RemoteVideoInfo videoInfo2 = new RemoteVideoInfo("Title1", 10,
+                RemoteVideoInfo.PlayerState.STOPPED, 5, "Error1");
+        RemoteVideoInfo videoInfo3 = new RemoteVideoInfo("Title3", 10,
+                RemoteVideoInfo.PlayerState.STOPPED, 5, "Error1");
+        mTransportControl.setVideoInfo(videoInfo1);
+        assertThat("getVideoInfo should return the videoInfo that was set",
+                mTransportControl.getVideoInfo(), equalTo(videoInfo1));
+        // Check that onVideoInfoChanged is called precisely once
+        verify(mTransportControl).onVideoInfoChanged();
+        // Try setting the same video info again
+        mTransportControl.setVideoInfo(videoInfo1);
+        // There should still have only been one call to onVideoInfoChanged
+        verify(mTransportControl).onVideoInfoChanged();
+        // Set the video info to a copy of the original video info
+        mTransportControl.setVideoInfo(videoInfo2);
+        // There should still have only been one call to onVideoInfoChanged
+        verify(mTransportControl).onVideoInfoChanged();
+        // And try a different video info
+        mTransportControl.setVideoInfo(videoInfo3);
+        assertThat("getVideoInfo should return the last videoInfo set",
+                mTransportControl.getVideoInfo(), equalTo(videoInfo3));
+        // Now there should have been two calls
+        verify(mTransportControl, times(2)).onVideoInfoChanged();
+
+    }
+
+    /**
+     * Test method for {@link TransportControl#setPosterBitmap} .
+     */
+    @Test
+    @Feature("MediaRemote")
+    public void testSetPosterBitmap() {
+        Bitmap.Config conf = Bitmap.Config.ARGB_8888;
+        int c[] = new int[] {Color.RED};
+        Bitmap bmp1 = Bitmap.createBitmap(c, 1, 1, conf);
+        mTransportControl.setPosterBitmap(bmp1);
+        assertThat("getPosterBitmap gets the last set poster", mTransportControl.getPosterBitmap(),
+                equalTo(bmp1));
+        // onPosterBitmapChanged should have been called precisely once
+        verify(mTransportControl).onPosterBitmapChanged();
+        // Try setting the same poster again
+        mTransportControl.setPosterBitmap(bmp1);
+        // there should still have been precisely one call to onPosterBitmapChanged
+        verify(mTransportControl).onPosterBitmapChanged();
+        // TODO(aberent) Cannot test changing the bitmap, because of a bug in Robolectric bitmap
+        // comparison (https://github.com/robolectric/robolectric/issues/1684).
+    }
+
+    /**
+     * Test method for {@link TransportControl#addListener} Also tests getListener
+     */
+    @Test
+    @Feature("MediaRemote")
+    public void testAddListener() {
+        assertThat("The listener set is empty", mTransportControl.getListeners().size(),
+                equalTo(0));
+        TransportControl.Listener listener1 = Mockito.mock(TransportControl.Listener.class);
+        mTransportControl.addListener(listener1);
+        assertThat("The listener set contains one item", mTransportControl.getListeners().size(),
+                equalTo(1));
+        // TODO(aberent): Change to CoreMatchers.hasItems when Hamcrest has been upgraded to a more
+        // modern version
+        assertThat("An added listener is returned",
+                mTransportControl.getListeners().contains(listener1), equalTo(true));
+        // Add a second listener
+        TransportControl.Listener listener2 = Mockito.mock(TransportControl.Listener.class);
+        mTransportControl.addListener(listener2);
+        assertThat("The listener set contains two items", mTransportControl.getListeners().size(),
+                equalTo(2));
+        // TODO(aberent): Change to CoreMatchers.hasItems when Hamcrest has been upgraded to a more
+        // modern version
+        assertThat("Adding a listener does not remove the old listener",
+                mTransportControl.getListeners().contains(listener1), equalTo(true));
+        assertThat("The second added listener is returned",
+                mTransportControl.getListeners().contains(listener2), equalTo(true));
+    }
+
+    /**
+     * Test method for {@link TransportControl#removeListener} .
+     */
+    @Test
+    @Feature("MediaRemote")
+    public void testRemoveListener() {
+        TransportControl.Listener listener1 = Mockito.mock(TransportControl.Listener.class);
+        mTransportControl.addListener(listener1);
+        TransportControl.Listener listener2 = Mockito.mock(TransportControl.Listener.class);
+        mTransportControl.addListener(listener2);
+        mTransportControl.removeListener(listener1);
+        assertThat("The listener set contains one item", mTransportControl.getListeners().size(),
+                equalTo(1));
+        assertThat("The removed listner is no longer in the list",
+                mTransportControl.getListeners().contains(listener1), equalTo(false));
+    }
+
+}
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellTabModelSelector.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellTabModelSelector.java
index 2042d70..03067ad 100644
--- a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellTabModelSelector.java
+++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellTabModelSelector.java
@@ -6,7 +6,6 @@
 
 import android.content.Context;
 
-import org.chromium.chrome.browser.ChromeContentViewClient;
 import org.chromium.chrome.browser.Tab;
 import org.chromium.chrome.browser.tabmodel.EmptyTabModel;
 import org.chromium.chrome.browser.tabmodel.TabModel;
@@ -86,7 +85,7 @@
     public Tab openNewTab(LoadUrlParams loadUrlParams, TabLaunchType type, Tab parent,
             boolean incognito) {
         assert !incognito;
-        ContentViewClient client = new ChromeContentViewClient() {
+        ContentViewClient client = new ContentViewClient() {
             @Override
             public ContentVideoViewClient getContentVideoViewClient() {
                 return mContentVideoViewClient;
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 2e3bebd..3b458688 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1962,7 +1962,7 @@
     Connected
   </message>
   <message name="IDS_CHROMEOS_NETWORK_STATE_CONNECTING" desc="Displayed state for a network when connecting">
-    Not Connected
+    Connecting
   </message>
 
   <message name="IDS_OPTIONS_SETTINGS_NETWORK_DISABLED" desc="Message displayed when a type of network connection is disabled">
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 2fbc79a..0c3901e 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6706,6 +6706,12 @@
       <message name="IDS_FLAGS_ENABLE_PERMISSIONS_BUBBLES_DESCRIPTION" desc="Description for the flag to enable showing permissions requests in bubbles.">
         Show content permission requests (e.g. notifications, quota, camera use, microphone use) in bubbles instead of info bars.
       </message>
+      <message name="IDS_FLAGS_ENABLE_SITE_ENGAGEMENT_SERVICE_NAME" desc="Title for the flag to enable the site engagement service.">
+        Enable Site Engagement Service
+      </message>
+      <message name="IDS_FLAGS_ENABLE_SITE_ENGAGEMENT_SERVICE_DESCRIPTION" desc="Description for the flag to enable the site engagement service.">
+        Enables the Site Engagement Service, which records interaction with sites and allocates resources accordingly.
+      </message>
       <message name="IDS_FLAGS_OUT_OF_PROCESS_PDF_NAME" desc="Title for the flag to enable out of process PDF.">
         Enable out of process PDF.
       </message>
@@ -6787,6 +6793,12 @@
       <message name="IDS_FLAGS_ENABLE_TAB_AUDIO_MUTING_DESCRIPTION" desc="Description of the flag that enables the tab audio muting UI experiment in chrome://extensions.">
         When enabled, the audio indicators in the tab strip double as tab audio mute controls.  This also adds commands in the tab context menu for quickly muting multiple selected tabs.
       </message>
+      <message name="IDS_FLAGS_ENABLE_EASY_UNLOCK_BLUETOOTH_LOW_ENERGY_DISCOVERY_NAME" desc="Title for the flag to enable Smart Lock to discover phones over Bluetooth Low Energy in order to unlock the Chromebook.">
+        Enable Smart Lock Bluetooth Low Energy Discovery.
+      </message>
+      <message name="IDS_FLAGS_ENABLE_EASY_UNLOCK_BLUETOOTH_LOW_ENERGY_DISCOVERY_DESCRIPTION" desc="Description for the flag to enable Smart Lock to discover phones over Bluetooth Low Energy in order to unlock the Chromebook.">
+        Enables a Smart Lock setting that allows Chromebook to discover phones over Bleutooth Low Energy in order to unlock the Chromebook when the phone is in its proximity.
+      </message>
       <message name="IDS_FLAGS_ENABLE_EASY_UNLOCK_PROXIMITY_DETECTION_NAME" desc="Title for the flag to enable Smart Lock to require close proximity between the phone and the Chromebook in order to unlock the Chromebook.">
         Enable Smart Lock proximity detection.
       </message>
@@ -9199,9 +9211,9 @@
         from accessing the network.
       </message>
       <message name="IDS_ERRORPAGES_SUMMARY_ICANN_NAME_COLLISION" desc="Summary in the error page when a dns look up fails due to having contained 127.0.53.53.">
-        This site is using a 
+        This site is using a
         <ph name="BEGIN_LINK">&lt;a href="https://support.google.com/chrome/?p=top_level_domain&amp;hl=[GRITLANGCODE]"&gt;</ph>new generic top-level domain<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>
-        (gTLD). If you have used 
+        (gTLD). If you have used
         <ph name="HOST_NAME">&lt;strong jscontent="hostName"&gt;&lt;/strong&gt;<ex>www.whatever.com</ex></ph>
         to access an internal site in the past, contact your network
         administrator.
@@ -15105,14 +15117,30 @@
 
       <!-- Reader mode experiment flags -->
       <if expr="is_android">
+        <message name="IDS_FLAGS_READER_MODE_HEURISTICS_NAME" desc="A name of an about:flags experiment for controlling when to show the reader mode button">
+          Reader Mode triggering
+        </message>
+        <message name="IDS_FLAGS_READER_MODE_HEURISTICS_DESCRIPTION" desc="Describes about:flags experiment options for controlling when to show the reader mode button">
+          Determines what pages the Reader Mode button is shown on.
+        </message>
+        <message name="IDS_FLAGS_READER_MODE_HEURISTICS_MARKUP" desc="A choice in dropdown dialog on about:flags page to show the reader mode button with article structured markup">
+          Show the Reader Mode button on pages with article structured markup
+        </message>
+        <message name="IDS_FLAGS_READER_MODE_HEURISTICS_ADABOOST" desc="A choice in dropdown dialog on about:flags page to show the reader mode button on pages that appear to be long form content">
+          Show the Reader Mode button on pages that appear to be long form content
+        </message>
+        <message name="IDS_FLAGS_READER_MODE_HEURISTICS_ALWAYS_OFF" desc="A choice in dropdown dialog on about:flags page to never show the reader mode button">
+          Never show Reader Mode button
+        </message>
+        <message name="IDS_FLAGS_READER_MODE_HEURISTICS_ALWAYS_ON" desc="A choice in dropdown dialog on about:flags page to show the reader mode button on all pages">
+          Show Reader Mode button on all pages
+        </message>
         <message name="IDS_FLAGS_READER_MODE_EXPERIMENT_NAME" desc="An about:flags experiment for reading mode UI">
           Enable Reader Mode Toolbar Icon
         </message>
         <message name="IDS_FLAGS_READER_MODE_EXPERIMENT_DESCRIPTION" desc="Describes about:flags experiment options for reading mode UI">
           Adds a button to the toolbar for viewing a more readable version of the current page.
         </message>
-      </if>
-      <if expr="is_android">
         <message name="IDS_FLAGS_READER_MODE_BUTTON_ANIMATION" desc="Title for flag enabling the reader mode button animation">
           Enable Reader Mode Button Animation
         </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index adb4c14..c6925c3 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -185,6 +185,9 @@
     sources += rebase_path(gypi_values.chrome_browser_content_settings_sources,
                            ".",
                            "//chrome")
+    sources += rebase_path(gypi_values.chrome_browser_engagement_sources,
+                           ".",
+                           "//chrome")
     sources +=
         rebase_path(gypi_values.chrome_browser_favicon_sources, ".", "//chrome")
     sources +=
@@ -332,6 +335,7 @@
       "//chrome/browser/sync_file_system/drive_backend:sync_file_system_drive_proto",
       "//chrome/common/extensions/api",
       "//chrome/common/extensions/api:api_registration",
+      "//components/proximity_auth/ble",
       "//components/proximity_auth/cryptauth",
       "//extensions/components/javascript_dialog_extensions_client",
       "//media/cast:net",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 767afd80..f8e446e 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -26,6 +26,7 @@
 #include "chrome/grit/google_chrome_strings.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/cloud_devices/common/cloud_devices_switches.h"
+#include "components/dom_distiller/core/dom_distiller_switches.h"
 #include "components/metrics/metrics_hashes.h"
 #include "components/nacl/common/nacl_switches.h"
 #include "components/omnibox/omnibox_switches.h"
@@ -290,6 +291,22 @@
   { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED,
     switches::kDisableZeroSuggest, ""}
 };
+
+const Experiment::Choice kReaderModeHeuristicsChoices[] = {
+    { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""},
+    { IDS_FLAGS_READER_MODE_HEURISTICS_MARKUP,
+      switches::kReaderModeHeuristics,
+      switches::reader_mode_heuristics::kOGArticle },
+    { IDS_FLAGS_READER_MODE_HEURISTICS_ADABOOST,
+      switches::kReaderModeHeuristics,
+      switches::reader_mode_heuristics::kAdaBoost },
+    { IDS_FLAGS_READER_MODE_HEURISTICS_ALWAYS_ON,
+      switches::kReaderModeHeuristics,
+      switches::reader_mode_heuristics::kAlwaysTrue },
+    { IDS_FLAGS_READER_MODE_HEURISTICS_ALWAYS_OFF,
+      switches::kReaderModeHeuristics,
+      switches::reader_mode_heuristics::kNone },
+};
 #endif
 
 const Experiment::Choice kNumRasterThreadsChoices[] = {
@@ -938,6 +955,14 @@
     kOsCrOS,
     SINGLE_VALUE_TYPE(proximity_auth::switches::kEnableProximityDetection)
   },
+  {
+    "enable-easy-unlock-bluetooth-low-energy-detection",
+    IDS_FLAGS_ENABLE_EASY_UNLOCK_BLUETOOTH_LOW_ENERGY_DISCOVERY_NAME,
+    IDS_FLAGS_ENABLE_EASY_UNLOCK_BLUETOOTH_LOW_ENERGY_DISCOVERY_DESCRIPTION,
+    kOsCrOS,
+    SINGLE_VALUE_TYPE(
+        proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery)
+  },
 #endif
 #if defined(USE_ASH)
   {
@@ -1733,6 +1758,13 @@
     MULTI_VALUE_TYPE(kZeroSuggestExperimentsChoices)
   },
   {
+    "reader-mode-heuristics",
+    IDS_FLAGS_READER_MODE_HEURISTICS_NAME,
+    IDS_FLAGS_READER_MODE_HEURISTICS_DESCRIPTION,
+    kOsAndroid,
+    MULTI_VALUE_TYPE(kReaderModeHeuristicsChoices)
+  },
+  {
     "enable-reader-mode-toolbar-icon",
     IDS_FLAGS_READER_MODE_EXPERIMENT_NAME,
     IDS_FLAGS_READER_MODE_EXPERIMENT_DESCRIPTION,
@@ -1772,6 +1804,14 @@
                               switches::kDisablePermissionsBubbles)
   },
   {
+    "enable-site-engagement-service",
+    IDS_FLAGS_ENABLE_SITE_ENGAGEMENT_SERVICE_NAME,
+    IDS_FLAGS_ENABLE_SITE_ENGAGEMENT_SERVICE_DESCRIPTION,
+    kOsAll,
+    ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSiteEngagementService,
+                              switches::kDisableSiteEngagementService)
+  },
+  {
     "enable-session-crashed-bubble",
     IDS_FLAGS_ENABLE_SESSION_CRASHED_BUBBLE_NAME,
     IDS_FLAGS_ENABLE_SESSION_CRASHED_BUBBLE_DESCRIPTION,
diff --git a/chrome/browser/android/banners/app_banner_manager_android.cc b/chrome/browser/android/banners/app_banner_manager_android.cc
index ff2c8b3..829b0b0 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.cc
+++ b/chrome/browser/android/banners/app_banner_manager_android.cc
@@ -21,7 +21,7 @@
 using base::android::ConvertUTF16ToJavaString;
 
 namespace {
-const char kBannerTag[] = "google-play-id";
+const char kPlayPlatform[] = "play";
 }  // anonymous namespace
 
 namespace banners {
@@ -48,26 +48,26 @@
   AppBannerManager::ReplaceWebContents(web_contents);
 }
 
-bool AppBannerManagerAndroid::OnMessageReceived(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(AppBannerManagerAndroid, message)
-    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidRetrieveMetaTagContent,
-                        OnDidRetrieveMetaTagContent)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-bool AppBannerManagerAndroid::OnInvalidManifest(AppBannerDataFetcher* fetcher) {
-  DCHECK(data_fetcher() == fetcher);
-  if (web_contents()->IsBeingDestroyed()) {
+bool AppBannerManagerAndroid::HandleNonWebApp(const std::string& platform,
+                                              const GURL& url,
+                                              const std::string& id) {
+  if (platform != kPlayPlatform || id.empty())
     return false;
-  }
 
-  Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(),
-                                                fetcher->validated_url(),
-                                                kBannerTag));
+  banners::TrackDisplayEvent(DISPLAY_EVENT_BANNER_REQUESTED);
+
+  // Send the info to the Java side to get info about the app.
+  JNIEnv* env = base::android::AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env);
+  if (jobj.is_null())
+    return false;
+
+  ScopedJavaLocalRef<jstring> jurl(
+      ConvertUTF8ToJavaString(env, data_fetcher()->validated_url().spec()));
+  ScopedJavaLocalRef<jstring> jpackage(
+      ConvertUTF8ToJavaString(env, id));
+  Java_AppBannerManager_fetchAppDetails(
+      env, jobj.obj(), jurl.obj(), jpackage.obj(), ideal_icon_size());
   return true;
 }
 
@@ -78,36 +78,6 @@
                                          ideal_icon_size);
 }
 
-void AppBannerManagerAndroid::OnDidRetrieveMetaTagContent(
-    bool success,
-    const std::string& tag_name,
-    const std::string& tag_content,
-    const GURL& expected_url) {
-  DCHECK(web_contents());
-  if (!success
-      || tag_name != kBannerTag
-      || !data_fetcher()
-      || data_fetcher()->validated_url() != expected_url
-      || tag_content.size() >= chrome::kMaxMetaTagAttributeLength) {
-    return;
-  }
-
-  banners::TrackDisplayEvent(DISPLAY_EVENT_BANNER_REQUESTED);
-
-  // Send the info to the Java side to get info about the app.
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env);
-  if (jobj.is_null())
-    return;
-
-  ScopedJavaLocalRef<jstring> jurl(
-      ConvertUTF8ToJavaString(env, expected_url.spec()));
-  ScopedJavaLocalRef<jstring> jpackage(
-      ConvertUTF8ToJavaString(env, tag_content));
-  Java_AppBannerManager_fetchAppDetails(
-      env, jobj.obj(), jurl.obj(), jpackage.obj(), ideal_icon_size());
-}
-
 bool AppBannerManagerAndroid::OnAppDetailsRetrieved(JNIEnv* env,
                                                     jobject obj,
                                                     jobject japp_data,
diff --git a/chrome/browser/android/banners/app_banner_manager_android.h b/chrome/browser/android/banners/app_banner_manager_android.h
index f63b556..f93a1b7 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.h
+++ b/chrome/browser/android/banners/app_banner_manager_android.h
@@ -47,26 +47,16 @@
                              jstring japp_package,
                              jstring jicon_url);
 
-  // WebContentsObserver overrides.
-  bool OnMessageReceived(const IPC::Message& message) override;
-
-  // AppBannerDataFetcher::Delegate overrides.
-  bool OnInvalidManifest(AppBannerDataFetcher* fetcher) override;
-
  protected:
   AppBannerDataFetcher* CreateAppBannerDataFetcher(
       base::WeakPtr<AppBannerDataFetcher::Delegate> weak_delegate,
       const int ideal_icon_size) override;
 
  private:
-  // Called when the renderer has returned information about the meta tag.
-  // If there is some metadata for the play store tag, this kicks off the
-  // process of showing a banner for the package designated by |tag_content| on
-  // the page at the |expected_url|.
-  void OnDidRetrieveMetaTagContent(bool success,
-                                   const std::string& tag_name,
-                                   const std::string& tag_content,
-                                   const GURL& expected_url);
+  // AppBannerDataFetcher::Delegate overrides.
+  bool HandleNonWebApp(const std::string& platform,
+                       const GURL& url,
+                       const std::string& id) override;
 
   // AppBannerManager on the Java side.
   JavaObjectWeakGlobalRef weak_java_banner_view_manager_;
diff --git a/chrome/browser/android/chromium_application.cc b/chrome/browser/android/chromium_application.cc
index 7b5a5a6..8b98d43 100644
--- a/chrome/browser/android/chromium_application.cc
+++ b/chrome/browser/android/chromium_application.cc
@@ -29,7 +29,7 @@
 
 void FlushCookiesOnIOThread(
     scoped_refptr<net::URLRequestContextGetter> getter) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   getter->GetURLRequestContext()
       ->cookie_store()
       ->GetCookieMonster()
@@ -50,7 +50,7 @@
 
 void RemoveSessionCookiesOnIOThread(
     scoped_refptr<net::URLRequestContextGetter> getter) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   getter->GetURLRequestContext()->cookie_store()->DeleteSessionCookiesAsync(
       net::CookieStore::DeleteCallback());
 }
@@ -64,7 +64,7 @@
 
 void ChangeAppStatusOnIOThread(SafeBrowsingService* sb_service,
                                jboolean foreground) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   SafeBrowsingProtocolManager* proto_manager = sb_service->protocol_manager();
   if (proto_manager)
     proto_manager->SetAppInForeground(foreground);
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc
index 4a8691b0..0340aac 100644
--- a/chrome/browser/android/compositor/tab_content_manager.cc
+++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -142,14 +142,14 @@
       disk_cache_path_str, (size_t)default_cache_size,
       (size_t)approximation_cache_size, (size_t)compression_queue_max_size,
       (size_t)write_queue_max_size, use_approximation_thumbnail));
-  thumbnail_cache_->AddThumbnailStoreObserver(this);
+  thumbnail_cache_->AddThumbnailCacheObserver(this);
 }
 
 TabContentManager::~TabContentManager() {
 }
 
 void TabContentManager::Destroy(JNIEnv* env, jobject obj) {
-  thumbnail_cache_->RemoveThumbnailStoreObserver(this);
+  thumbnail_cache_->RemoveThumbnailCacheObserver(this);
   delete this;
 }
 
diff --git a/chrome/browser/android/compositor/tab_content_manager.h b/chrome/browser/android/compositor/tab_content_manager.h
index f09366b..10e4910 100644
--- a/chrome/browser/android/compositor/tab_content_manager.h
+++ b/chrome/browser/android/compositor/tab_content_manager.h
@@ -13,7 +13,7 @@
 #include "base/containers/scoped_ptr_hash_map.h"
 #include "base/memory/weak_ptr.h"
 #include "cc/layers/ui_resource_layer.h"
-#include "chrome/browser/android/thumbnail/thumbnail_store.h"
+#include "chrome/browser/android/thumbnail/thumbnail_cache.h"
 
 using base::android::ScopedJavaLocalRef;
 
@@ -32,7 +32,7 @@
 class ThumbnailLayer;
 
 // A native component of the Java TabContentManager class.
-class TabContentManager : public ThumbnailStoreObserver {
+class TabContentManager : public ThumbnailCacheObserver {
  public:
   static TabContentManager* FromJavaObject(jobject jobj);
 
@@ -92,7 +92,7 @@
                                               jint min_forbidden_id);
   void GetDecompressedThumbnail(JNIEnv* env, jobject obj, jint tab_id);
 
-  // ThumbnailStoreObserver implementation;
+  // ThumbnailCacheObserver implementation;
   void OnFinishedThumbnailRead(TabId tab_id) override;
 
  private:
@@ -101,11 +101,6 @@
   typedef base::hash_map<int, scoped_refptr<ThumbnailLayer>> ThumbnailLayerMap;
   typedef base::ScopedPtrHashMap<int, TabReadbackRequest> TabReadbackRequestMap;
 
-  // TODO(): The upstream ThumbnailCache class was temporarily renamed to
-  // ThumbnailStore to avoid conflict with downstream.  Please rename the
-  // upstream to ThumbnailCache once the downstream is in a good state.
-  typedef ThumbnailStore ThumbnailCache;
-
   void PutThumbnailIntoCache(int tab_id,
                              float thumbnail_scale,
                              const SkBitmap& bitmap);
diff --git a/chrome/browser/android/cookies/cookies_fetcher.cc b/chrome/browser/android/cookies/cookies_fetcher.cc
index 25f55e7f..8197f37 100644
--- a/chrome/browser/android/cookies/cookies_fetcher.cc
+++ b/chrome/browser/android/cookies/cookies_fetcher.cc
@@ -49,7 +49,7 @@
 
 void CookiesFetcher::PersistCookiesInternal(
     net::URLRequestContextGetter* getter) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   net::CookieStore* store = getter->GetURLRequestContext()->cookie_store();
 
@@ -142,7 +142,7 @@
 void CookiesFetcher::RestoreToCookieJarInternal(
     net::URLRequestContextGetter* getter,
     const net::CanonicalCookie& cookie) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   net::CookieStore* store = getter->GetURLRequestContext()->cookie_store();
 
diff --git a/chrome/browser/android/download/chrome_download_manager_overwrite_infobar_delegate.cc b/chrome/browser/android/download/chrome_download_manager_overwrite_infobar_delegate.cc
index f4002b4..d4c0cf8c 100644
--- a/chrome/browser/android/download/chrome_download_manager_overwrite_infobar_delegate.cc
+++ b/chrome/browser/android/download/chrome_download_manager_overwrite_infobar_delegate.cc
@@ -73,7 +73,7 @@
 void ChromeDownloadManagerOverwriteInfoBarDelegate::CreateNewFileInternal(
     const base::FilePath& suggested_download_path,
     const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   int uniquifier = base::GetUniquePathNumber(suggested_download_path,
                                              base::FilePath::StringType());
   base::FilePath new_path = suggested_download_path;
diff --git a/chrome/browser/android/logo_service.cc b/chrome/browser/android/logo_service.cc
index c71cefd..fc113ff7 100644
--- a/chrome/browser/android/logo_service.cc
+++ b/chrome/browser/android/logo_service.cc
@@ -40,8 +40,7 @@
  public:
   LogoDecoderDelegate(
       const base::Callback<void(const SkBitmap&)>& image_decoded_callback)
-      : ImageRequest(base::MessageLoopProxy::current()),
-        image_decoded_callback_(image_decoded_callback),
+      : image_decoded_callback_(image_decoded_callback),
         weak_ptr_factory_(this) {
     // If the ImageDecoder crashes or otherwise never completes, call
     // OnImageDecodeTimedOut() eventually to ensure that image_decoded_callback_
diff --git a/chrome/browser/android/provider/blocking_ui_thread_async_request.cc b/chrome/browser/android/provider/blocking_ui_thread_async_request.cc
index 7267e583..4eb9811e 100644
--- a/chrome/browser/android/provider/blocking_ui_thread_async_request.cc
+++ b/chrome/browser/android/provider/blocking_ui_thread_async_request.cc
@@ -12,6 +12,6 @@
   // Currently all our use cases receive their request response in the UI
   // thread (the same thread that made the request). However this is not
   // a design constraint and can be changed if ever needed.
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   request_completed_.Signal();
 }
diff --git a/chrome/browser/android/provider/run_on_ui_thread_blocking.h b/chrome/browser/android/provider/run_on_ui_thread_blocking.h
index 04ea537..b43410e1 100644
--- a/chrome/browser/android/provider/run_on_ui_thread_blocking.h
+++ b/chrome/browser/android/provider/run_on_ui_thread_blocking.h
@@ -30,7 +30,7 @@
   template <typename Signature>
   static void RunOnUIThread(base::Callback<Signature> runnable,
                             base::WaitableEvent* finished) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     runnable.Run();
     finished->Signal();
   }
diff --git a/chrome/browser/android/seccomp_support_detector.cc b/chrome/browser/android/seccomp_support_detector.cc
index 632cde2..d53911b 100644
--- a/chrome/browser/android/seccomp_support_detector.cc
+++ b/chrome/browser/android/seccomp_support_detector.cc
@@ -36,7 +36,7 @@
       base::Bind(&SeccompSupportDetector::DetectKernelVersion, detector));
 }
 
-SeccompSupportDetector::SeccompSupportDetector() : prctl_detected_(false) {
+SeccompSupportDetector::SeccompSupportDetector() {
 }
 
 SeccompSupportDetector::~SeccompSupportDetector() {
@@ -64,8 +64,6 @@
 #else
   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
       base::Bind(&SeccompSupportDetector::OnDetectPrctl, this, false));
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-      base::Bind(&SeccompSupportDetector::OnDetectSyscall, this, false));
 #endif
 }
 
@@ -82,17 +80,9 @@
 
 void SeccompSupportDetector::OnProcessCrashed(int exit_code) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  // The process crashed. Since prctl detection happens first, report which
-  // probe failed.
-  if (prctl_detected_) {
-    UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Syscall",
-                              DETECTION_FAILED,
-                              LAST_STATUS);
-  } else {
-    UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Prctl",
-                              DETECTION_FAILED,
-                              LAST_STATUS);
-  }
+  UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Prctl",
+                            DETECTION_FAILED,
+                            LAST_STATUS);
 }
 
 bool SeccompSupportDetector::OnMessageReceived(const IPC::Message& message) {
@@ -100,8 +90,6 @@
   IPC_BEGIN_MESSAGE_MAP(SeccompSupportDetector, message)
     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl,
                         OnDetectPrctl)
-    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall,
-                        OnDetectSyscall)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -109,22 +97,10 @@
 
 void SeccompSupportDetector::OnDetectPrctl(bool prctl_supported) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(!prctl_detected_);
-
-  prctl_detected_ = true;
 
   UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Prctl",
                             prctl_supported ? SUPPORTED : NOT_SUPPORTED,
                             LAST_STATUS);
-}
-
-void SeccompSupportDetector::OnDetectSyscall(bool syscall_supported) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(prctl_detected_);
-
-  UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Syscall",
-                            syscall_supported ? SUPPORTED : NOT_SUPPORTED,
-                            LAST_STATUS);
 
   // The utility process will shutdown after this, and this object will
   // be deleted when the UtilityProcessHost releases its reference.
diff --git a/chrome/browser/android/seccomp_support_detector.h b/chrome/browser/android/seccomp_support_detector.h
index f038d51..58d66bd 100644
--- a/chrome/browser/android/seccomp_support_detector.h
+++ b/chrome/browser/android/seccomp_support_detector.h
@@ -33,12 +33,7 @@
   void OnProcessCrashed(int exit_code) override;
   bool OnMessageReceived(const IPC::Message& message) override;
 
-  // OnDetectPrctl is always received before OnDetectSyscall.
   void OnDetectPrctl(bool prctl_supported);
-  void OnDetectSyscall(bool syscall_supported);
-
-  // Whether OnDetectPrctl was received.
-  bool prctl_detected_;
 
   DISALLOW_COPY_AND_ASSIGN(SeccompSupportDetector);
 };
diff --git a/chrome/browser/android/thumbnail/thumbnail_store.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc
similarity index 90%
rename from chrome/browser/android/thumbnail/thumbnail_store.cc
rename to chrome/browser/android/thumbnail/thumbnail_cache.cc
index 4fe4472..130385d 100644
--- a/chrome/browser/android/thumbnail/thumbnail_store.cc
+++ b/chrome/browser/android/thumbnail/thumbnail_cache.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 "chrome/browser/android/thumbnail/thumbnail_store.h"
+#include "chrome/browser/android/thumbnail/thumbnail_cache.h"
 
 #include <algorithm>
 #include <cmath>
@@ -111,7 +111,7 @@
 
 }  // anonymous namespace
 
-ThumbnailStore::ThumbnailStore(const std::string& disk_cache_path_str,
+ThumbnailCache::ThumbnailCache(const std::string& disk_cache_path_str,
                                size_t default_cache_size,
                                size_t approximation_cache_size,
                                size_t compression_queue_max_size,
@@ -128,14 +128,14 @@
       approximation_cache_(approximation_cache_size),
       ui_resource_provider_(NULL),
       weak_factory_(this) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 }
 
-ThumbnailStore::~ThumbnailStore() {
+ThumbnailCache::~ThumbnailCache() {
   SetUIResourceProvider(NULL);
 }
 
-void ThumbnailStore::SetUIResourceProvider(
+void ThumbnailCache::SetUIResourceProvider(
     ui::UIResourceProvider* ui_resource_provider) {
   if (ui_resource_provider_ == ui_resource_provider)
     return;
@@ -146,19 +146,19 @@
   ui_resource_provider_ = ui_resource_provider;
 }
 
-void ThumbnailStore::AddThumbnailStoreObserver(
-    ThumbnailStoreObserver* observer) {
+void ThumbnailCache::AddThumbnailCacheObserver(
+    ThumbnailCacheObserver* observer) {
   if (!observers_.HasObserver(observer))
     observers_.AddObserver(observer);
 }
 
-void ThumbnailStore::RemoveThumbnailStoreObserver(
-    ThumbnailStoreObserver* observer) {
+void ThumbnailCache::RemoveThumbnailCacheObserver(
+    ThumbnailCacheObserver* observer) {
   if (observers_.HasObserver(observer))
     observers_.RemoveObserver(observer);
 }
 
-void ThumbnailStore::Put(TabId tab_id,
+void ThumbnailCache::Put(TabId tab_id,
                          const SkBitmap& bitmap,
                          float thumbnail_scale) {
   if (!ui_resource_provider_ || bitmap.empty() || thumbnail_scale <= 0)
@@ -186,7 +186,7 @@
   CompressThumbnailIfNecessary(tab_id, time_stamp, bitmap, thumbnail_scale);
 }
 
-void ThumbnailStore::Remove(TabId tab_id) {
+void ThumbnailCache::Remove(TabId tab_id) {
   cache_.Remove(tab_id);
   approximation_cache_.Remove(tab_id);
   thumbnail_meta_data_.erase(tab_id);
@@ -194,7 +194,7 @@
   RemoveFromReadQueue(tab_id);
 }
 
-Thumbnail* ThumbnailStore::Get(TabId tab_id,
+Thumbnail* ThumbnailCache::Get(TabId tab_id,
                                bool force_disk_read,
                                bool allow_approximation) {
   Thumbnail* thumbnail = cache_.Get(tab_id);
@@ -223,16 +223,16 @@
   return NULL;
 }
 
-void ThumbnailStore::RemoveFromDiskAtAndAboveId(TabId min_id) {
+void ThumbnailCache::RemoveFromDiskAtAndAboveId(TabId min_id) {
   base::Closure remove_task =
-      base::Bind(&ThumbnailStore::RemoveFromDiskAtAndAboveIdTask,
+      base::Bind(&ThumbnailCache::RemoveFromDiskAtAndAboveIdTask,
                  disk_cache_path_,
                  min_id);
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE, FROM_HERE, remove_task);
 }
 
-void ThumbnailStore::InvalidateThumbnailIfChanged(TabId tab_id,
+void ThumbnailCache::InvalidateThumbnailIfChanged(TabId tab_id,
                                                   const GURL& url) {
   ThumbnailMetaDataMap::iterator meta_data_iter =
       thumbnail_meta_data_.find(tab_id);
@@ -243,7 +243,7 @@
   }
 }
 
-bool ThumbnailStore::CheckAndUpdateThumbnailMetaData(TabId tab_id,
+bool ThumbnailCache::CheckAndUpdateThumbnailMetaData(TabId tab_id,
                                                      const GURL& url) {
   base::Time current_time = base::Time::Now();
   ThumbnailMetaDataMap::iterator meta_data_iter =
@@ -259,7 +259,7 @@
   return true;
 }
 
-void ThumbnailStore::UpdateVisibleIds(const TabIdList& priority) {
+void ThumbnailCache::UpdateVisibleIds(const TabIdList& priority) {
   if (priority.empty()) {
     visible_ids_.clear();
     return;
@@ -305,7 +305,7 @@
   ReadNextThumbnail();
 }
 
-void ThumbnailStore::DecompressThumbnailFromFile(
+void ThumbnailCache::DecompressThumbnailFromFile(
     TabId tab_id,
     const base::Callback<void(bool, SkBitmap)>&
         post_decompress_callback) {
@@ -313,28 +313,28 @@
 
   base::Callback<void(skia::RefPtr<SkPixelRef>, float, const gfx::Size&)>
       decompress_task = base::Bind(
-          &ThumbnailStore::DecompressionTask, post_decompress_callback);
+          &ThumbnailCache::DecompressionTask, post_decompress_callback);
 
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE,
       FROM_HERE,
-      base::Bind(&ThumbnailStore::ReadTask, true, file_path, decompress_task));
+      base::Bind(&ThumbnailCache::ReadTask, true, file_path, decompress_task));
 }
 
-void ThumbnailStore::RemoveFromDisk(TabId tab_id) {
+void ThumbnailCache::RemoveFromDisk(TabId tab_id) {
   base::FilePath file_path = GetFilePath(tab_id);
   base::Closure task =
-      base::Bind(&ThumbnailStore::RemoveFromDiskTask, file_path);
+      base::Bind(&ThumbnailCache::RemoveFromDiskTask, file_path);
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE, FROM_HERE, task);
 }
 
-void ThumbnailStore::RemoveFromDiskTask(const base::FilePath& file_path) {
+void ThumbnailCache::RemoveFromDiskTask(const base::FilePath& file_path) {
   if (base::PathExists(file_path))
     base::DeleteFile(file_path, false);
 }
 
-void ThumbnailStore::RemoveFromDiskAtAndAboveIdTask(
+void ThumbnailCache::RemoveFromDiskAtAndAboveIdTask(
     const base::FilePath& dir_path,
     TabId min_id) {
   base::FileEnumerator enumerator(dir_path, false, base::FileEnumerator::FILES);
@@ -350,7 +350,7 @@
   }
 }
 
-void ThumbnailStore::WriteThumbnailIfNecessary(
+void ThumbnailCache::WriteThumbnailIfNecessary(
     TabId tab_id,
     skia::RefPtr<SkPixelRef> compressed_data,
     float scale,
@@ -361,10 +361,10 @@
   write_tasks_count_++;
 
   base::Callback<void()> post_write_task =
-      base::Bind(&ThumbnailStore::PostWriteTask, weak_factory_.GetWeakPtr());
+      base::Bind(&ThumbnailCache::PostWriteTask, weak_factory_.GetWeakPtr());
   content::BrowserThread::PostTask(content::BrowserThread::FILE,
                                    FROM_HERE,
-                                   base::Bind(&ThumbnailStore::WriteTask,
+                                   base::Bind(&ThumbnailCache::WriteTask,
                                               GetFilePath(tab_id),
                                               compressed_data,
                                               scale,
@@ -372,7 +372,7 @@
                                               post_write_task));
 }
 
-void ThumbnailStore::CompressThumbnailIfNecessary(
+void ThumbnailCache::CompressThumbnailIfNecessary(
     TabId tab_id,
     const base::Time& time_stamp,
     const SkBitmap& bitmap,
@@ -385,7 +385,7 @@
   compression_tasks_count_++;
 
   base::Callback<void(skia::RefPtr<SkPixelRef>, const gfx::Size&)>
-      post_compression_task = base::Bind(&ThumbnailStore::PostCompressionTask,
+      post_compression_task = base::Bind(&ThumbnailCache::PostCompressionTask,
                                          weak_factory_.GetWeakPtr(),
                                          tab_id,
                                          time_stamp,
@@ -396,14 +396,14 @@
       raw_data_size, ui_resource_provider_->SupportsETC1NonPowerOfTwo());
 
   base::WorkerPool::PostTask(FROM_HERE,
-                             base::Bind(&ThumbnailStore::CompressionTask,
+                             base::Bind(&ThumbnailCache::CompressionTask,
                                         bitmap,
                                         encoded_size,
                                         post_compression_task),
                              true);
 }
 
-void ThumbnailStore::ReadNextThumbnail() {
+void ThumbnailCache::ReadNextThumbnail() {
   if (read_queue_.empty() || read_in_progress_)
     return;
 
@@ -414,15 +414,15 @@
 
   base::Callback<void(skia::RefPtr<SkPixelRef>, float, const gfx::Size&)>
       post_read_task = base::Bind(
-          &ThumbnailStore::PostReadTask, weak_factory_.GetWeakPtr(), tab_id);
+          &ThumbnailCache::PostReadTask, weak_factory_.GetWeakPtr(), tab_id);
 
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE,
       FROM_HERE,
-      base::Bind(&ThumbnailStore::ReadTask, false, file_path, post_read_task));
+      base::Bind(&ThumbnailCache::ReadTask, false, file_path, post_read_task));
 }
 
-void ThumbnailStore::MakeSpaceForNewItemIfNecessary(TabId tab_id) {
+void ThumbnailCache::MakeSpaceForNewItemIfNecessary(TabId tab_id) {
   if (cache_.Get(tab_id) ||
       std::find(visible_ids_.begin(), visible_ids_.end(), tab_id) ==
           visible_ids_.end() ||
@@ -462,14 +462,14 @@
     cache_.Remove(key_to_remove);
 }
 
-void ThumbnailStore::RemoveFromReadQueue(TabId tab_id) {
+void ThumbnailCache::RemoveFromReadQueue(TabId tab_id) {
   TabIdList::iterator read_iter =
       std::find(read_queue_.begin(), read_queue_.end(), tab_id);
   if (read_iter != read_queue_.end())
     read_queue_.erase(read_iter);
 }
 
-void ThumbnailStore::InvalidateCachedThumbnail(Thumbnail* thumbnail) {
+void ThumbnailCache::InvalidateCachedThumbnail(Thumbnail* thumbnail) {
   DCHECK(thumbnail);
   TabId tab_id = thumbnail->tab_id();
   cc::UIResourceId uid = thumbnail->ui_resource_id();
@@ -483,7 +483,7 @@
     approximation_cache_.Remove(tab_id);
 }
 
-base::FilePath ThumbnailStore::GetFilePath(TabId tab_id) const {
+base::FilePath ThumbnailCache::GetFilePath(TabId tab_id) const {
   return disk_cache_path_.Append(base::IntToString(tab_id));
 }
 
@@ -540,7 +540,7 @@
 
 }  // anonymous namespace
 
-void ThumbnailStore::WriteTask(const base::FilePath& file_path,
+void ThumbnailCache::WriteTask(const base::FilePath& file_path,
                                skia::RefPtr<SkPixelRef> compressed_data,
                                float scale,
                                const gfx::Size& content_size,
@@ -564,11 +564,11 @@
       content::BrowserThread::UI, FROM_HERE, post_write_task);
 }
 
-void ThumbnailStore::PostWriteTask() {
+void ThumbnailCache::PostWriteTask() {
   write_tasks_count_--;
 }
 
-void ThumbnailStore::CompressionTask(
+void ThumbnailCache::CompressionTask(
     SkBitmap raw_data,
     gfx::Size encoded_size,
     const base::Callback<void(skia::RefPtr<SkPixelRef>, const gfx::Size&)>&
@@ -618,7 +618,7 @@
       base::Bind(post_compression_task, compressed_data, content_size));
 }
 
-void ThumbnailStore::PostCompressionTask(
+void ThumbnailCache::PostCompressionTask(
     TabId tab_id,
     const base::Time& time_stamp,
     float scale,
@@ -744,7 +744,7 @@
 
 }// anonymous namespace
 
-void ThumbnailStore::ReadTask(
+void ThumbnailCache::ReadTask(
     bool decompress,
     const base::FilePath& file_path,
     const base::Callback<
@@ -785,7 +785,7 @@
   }
 }
 
-void ThumbnailStore::PostReadTask(TabId tab_id,
+void ThumbnailCache::PostReadTask(TabId tab_id,
                                   skia::RefPtr<SkPixelRef> compressed_data,
                                   float scale,
                                   const gfx::Size& content_size) {
@@ -822,12 +822,12 @@
   ReadNextThumbnail();
 }
 
-void ThumbnailStore::NotifyObserversOfThumbnailRead(TabId tab_id) {
+void ThumbnailCache::NotifyObserversOfThumbnailRead(TabId tab_id) {
   FOR_EACH_OBSERVER(
-      ThumbnailStoreObserver, observers_, OnFinishedThumbnailRead(tab_id));
+      ThumbnailCacheObserver, observers_, OnFinishedThumbnailRead(tab_id));
 }
 
-void ThumbnailStore::RemoveOnMatchedTimeStamp(TabId tab_id,
+void ThumbnailCache::RemoveOnMatchedTimeStamp(TabId tab_id,
                                               const base::Time& time_stamp) {
   // We remove the cached version if it matches the tab_id and the time_stamp.
   Thumbnail* thumbnail = cache_.Get(tab_id);
@@ -839,7 +839,7 @@
   return;
 }
 
-void ThumbnailStore::DecompressionTask(
+void ThumbnailCache::DecompressionTask(
     const base::Callback<void(bool, SkBitmap)>&
         post_decompression_callback,
     skia::RefPtr<SkPixelRef> compressed_data,
@@ -894,16 +894,16 @@
       base::Bind(post_decompression_callback, success, raw_data_small));
 }
 
-ThumbnailStore::ThumbnailMetaData::ThumbnailMetaData() {
+ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData() {
 }
 
-ThumbnailStore::ThumbnailMetaData::ThumbnailMetaData(
+ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData(
     const base::Time& current_time,
     const GURL& url)
     : capture_time_(current_time), url_(url) {
 }
 
-std::pair<SkBitmap, float> ThumbnailStore::CreateApproximation(
+std::pair<SkBitmap, float> ThumbnailCache::CreateApproximation(
     const SkBitmap& bitmap,
     float scale) {
   DCHECK(!bitmap.empty());
diff --git a/chrome/browser/android/thumbnail/thumbnail_store.h b/chrome/browser/android/thumbnail/thumbnail_cache.h
similarity index 89%
rename from chrome/browser/android/thumbnail/thumbnail_store.h
rename to chrome/browser/android/thumbnail/thumbnail_cache.h
index 8ad0c1a..098c190 100644
--- a/chrome/browser/android/thumbnail/thumbnail_store.h
+++ b/chrome/browser/android/thumbnail/thumbnail_cache.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ANDROID_THUMBNAIL_THUMBNAIL_STORE_H_
-#define CHROME_BROWSER_ANDROID_THUMBNAIL_THUMBNAIL_STORE_H_
+#ifndef CHROME_BROWSER_ANDROID_THUMBNAIL_THUMBNAIL_CACHE_H_
+#define CHROME_BROWSER_ANDROID_THUMBNAIL_THUMBNAIL_CACHE_H_
 
 #include <list>
 #include <set>
@@ -36,27 +36,27 @@
 
 typedef std::list<TabId> TabIdList;
 
-class ThumbnailStoreObserver {
+class ThumbnailCacheObserver {
  public:
   virtual void OnFinishedThumbnailRead(TabId tab_id) = 0;
 };
 
-class ThumbnailStore : ThumbnailDelegate {
+class ThumbnailCache : ThumbnailDelegate {
  public:
-  ThumbnailStore(const std::string& disk_cache_path_str,
+  ThumbnailCache(const std::string& disk_cache_path_str,
                  size_t default_cache_size,
                  size_t approximation_cache_size,
                  size_t compression_queue_max_size,
                  size_t write_queue_max_size,
                  bool use_approximation_thumbnail);
 
-  ~ThumbnailStore() override;
+  ~ThumbnailCache() override;
 
   void SetUIResourceProvider(ui::UIResourceProvider* ui_resource_provider);
 
-  void AddThumbnailStoreObserver(ThumbnailStoreObserver* observer);
-  void RemoveThumbnailStoreObserver(
-      ThumbnailStoreObserver* observer);
+  void AddThumbnailCacheObserver(ThumbnailCacheObserver* observer);
+  void RemoveThumbnailCacheObserver(
+      ThumbnailCacheObserver* observer);
 
   void Put(TabId tab_id, const SkBitmap& bitmap, float thumbnail_scale);
   void Remove(TabId tab_id);
@@ -154,16 +154,16 @@
 
   ExpiringThumbnailCache cache_;
   ExpiringThumbnailCache approximation_cache_;
-  ObserverList<ThumbnailStoreObserver> observers_;
+  ObserverList<ThumbnailCacheObserver> observers_;
   ThumbnailMetaDataMap thumbnail_meta_data_;
   TabIdList read_queue_;
   TabIdList visible_ids_;
 
   ui::UIResourceProvider* ui_resource_provider_;
 
-  base::WeakPtrFactory<ThumbnailStore> weak_factory_;
+  base::WeakPtrFactory<ThumbnailCache> weak_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(ThumbnailStore);
+  DISALLOW_COPY_AND_ASSIGN(ThumbnailCache);
 };
 
-#endif  // CHROME_BROWSER_ANDROID_THUMBNAIL_THUMBNAIL_STORE_H_
+#endif  // CHROME_BROWSER_ANDROID_THUMBNAIL_THUMBNAIL_CACHE_H_
diff --git a/chrome/browser/android/webapps/single_tab_mode_tab_helper.cc b/chrome/browser/android/webapps/single_tab_mode_tab_helper.cc
index 786075e..56db44f 100644
--- a/chrome/browser/android/webapps/single_tab_mode_tab_helper.cc
+++ b/chrome/browser/android/webapps/single_tab_mode_tab_helper.cc
@@ -20,13 +20,13 @@
 base::LazyInstance<SingleTabIDSet> g_blocked_ids = LAZY_INSTANCE_INITIALIZER;
 
 void AddPairOnIOThread(int32 process_id, int32 routing_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   RenderWidgetHostID single_tab_pair(process_id, routing_id);
   g_blocked_ids.Get().insert(single_tab_pair);
 }
 
 void RemovePairOnIOThread(int32 process_id, int32 routing_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   RenderWidgetHostID single_tab_pair(process_id, routing_id);
   SingleTabIDSet::iterator itr = g_blocked_ids.Get().find(single_tab_pair);
   DCHECK(itr != g_blocked_ids.Get().end());
@@ -87,7 +87,7 @@
 
 bool SingleTabModeTabHelper::IsRegistered(int32 process_id,
                                           int32 routing_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   RenderWidgetHostID single_tab_pair(process_id, routing_id);
   SingleTabIDSet::iterator itr = g_blocked_ids.Get().find(single_tab_pair);
   return itr != g_blocked_ids.Get().end();
diff --git a/chrome/browser/app_icon_win.cc b/chrome/browser/app_icon_win.cc
index d8b3628..6f1424e 100644
--- a/chrome/browser/app_icon_win.cc
+++ b/chrome/browser/app_icon_win.cc
@@ -29,16 +29,18 @@
 
 HICON GetAppIcon() {
   const int icon_id = GetAppIconResourceId();
+  // HICON returned from LoadIcon do not leak and do not have to be destroyed.
   return LoadIcon(GetModuleHandle(chrome::kBrowserResourcesDll),
                   MAKEINTRESOURCE(icon_id));
 }
 
 HICON GetSmallAppIcon() {
   const int icon_id = GetAppIconResourceId();
+  // HICON returned from LoadImage must be released using DestroyIcon.
   return static_cast<HICON>(LoadImage(
       GetModuleHandle(chrome::kBrowserResourcesDll), MAKEINTRESOURCE(icon_id),
       IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
-      LR_DEFAULTCOLOR));
+      LR_DEFAULTCOLOR | LR_SHARED));
 }
 
 scoped_ptr<SkBitmap> GetAppIconForSize(int size) {
diff --git a/chrome/browser/apps/app_shim/app_shim_host_manager_mac.mm b/chrome/browser/apps/app_shim/app_shim_host_manager_mac.mm
index 5d61239..0e3465d 100644
--- a/chrome/browser/apps/app_shim/app_shim_host_manager_mac.mm
+++ b/chrome/browser/apps/app_shim/app_shim_host_manager_mac.mm
@@ -59,7 +59,7 @@
     : did_init_(false) {}
 
 void AppShimHostManager::Init() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!did_init_);
   did_init_ = true;
   apps::AppShimHandler::SetDefaultHandler(&extension_app_shim_handler_);
@@ -90,7 +90,7 @@
 }
 
 void AppShimHostManager::InitOnFileThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   base::FilePath user_data_dir;
   if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
     return;
@@ -144,7 +144,7 @@
 }
 
 void AppShimHostManager::ListenOnIOThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!acceptor_->Listen()) {
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
@@ -154,7 +154,7 @@
 
 void AppShimHostManager::OnClientConnected(
     const IPC::ChannelHandle& handle) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&CreateAppShimHost, handle));
diff --git a/chrome/browser/apps/app_url_redirector.cc b/chrome/browser/apps/app_url_redirector.cc
index 623a7d0..cf15169 100644
--- a/chrome/browser/apps/app_url_redirector.cc
+++ b/chrome/browser/apps/app_url_redirector.cc
@@ -37,7 +37,7 @@
     const std::string& handler_id,
     content::WebContents* source,
     const navigation_interception::NavigationParams& params) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Redirect top-level navigations only. This excludes iframes and webviews
   // in particular.
diff --git a/chrome/browser/apps/drive/drive_app_converter.cc b/chrome/browser/apps/drive/drive_app_converter.cc
index 7752c86..581b67c5 100644
--- a/chrome/browser/apps/drive/drive_app_converter.cc
+++ b/chrome/browser/apps/drive/drive_app_converter.cc
@@ -37,9 +37,7 @@
   IconFetcher(DriveAppConverter* converter,
               const GURL& icon_url,
               int expected_size)
-      : ImageRequest(
-            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
-        converter_(converter),
+      : converter_(converter),
         icon_url_(icon_url),
         expected_size_(expected_size) {}
   ~IconFetcher() override {}
diff --git a/chrome/browser/apps/ephemeral_app_throttle.cc b/chrome/browser/apps/ephemeral_app_throttle.cc
index 1ebd54f..6260c51d 100644
--- a/chrome/browser/apps/ephemeral_app_throttle.cc
+++ b/chrome/browser/apps/ephemeral_app_throttle.cc
@@ -30,7 +30,7 @@
     const std::string& app_id,
     content::WebContents* source,
     const navigation_interception::NavigationParams& params) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Redirect top-level navigations only.
   if (source->IsSubframe())
diff --git a/chrome/browser/banners/app_banner_data_fetcher.cc b/chrome/browser/banners/app_banner_data_fetcher.cc
index a32ba76..1897e81 100644
--- a/chrome/browser/banners/app_banner_data_fetcher.cc
+++ b/chrome/browser/banners/app_banner_data_fetcher.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/banners/app_banner_metrics.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
@@ -231,14 +232,23 @@
 void AppBannerDataFetcher::OnDidGetManifest(
     const content::Manifest& manifest) {
   content::WebContents* web_contents = GetWebContents();
-  if (!is_active_ || !web_contents) {
+  if (!is_active_ || !web_contents || manifest.IsEmpty()) {
     Cancel();
     return;
   }
 
-  if (!IsManifestValid(manifest)) {
-    if (!weak_delegate_.get()->OnInvalidManifest(this))
-      Cancel();
+  if (manifest.prefer_related_applications &&
+      manifest.related_applications.size()) {
+    for (const auto& application : manifest.related_applications) {
+      std::string platform = base::UTF16ToUTF8(application.platform.string());
+      std::string id = base::UTF16ToUTF8(application.id.string());
+      if (weak_delegate_->HandleNonWebApp(platform, application.url, id))
+        return;
+    }
+  }
+
+  if (!IsManifestValidForWebApp(manifest)) {
+    Cancel();
     return;
   }
 
@@ -336,7 +346,7 @@
 }
 
 // static
-bool AppBannerDataFetcher::IsManifestValid(
+bool AppBannerDataFetcher::IsManifestValidForWebApp(
     const content::Manifest& manifest) {
   if (manifest.IsEmpty())
     return false;
diff --git a/chrome/browser/banners/app_banner_data_fetcher.h b/chrome/browser/banners/app_banner_data_fetcher.h
index 085e920..ce6d8e30 100644
--- a/chrome/browser/banners/app_banner_data_fetcher.h
+++ b/chrome/browser/banners/app_banner_data_fetcher.h
@@ -43,9 +43,11 @@
 
   class Delegate {
    public:
-    // Called when no valid manifest was found.  Returns |true| if the fetcher
-    // needs to remain active and wait for a callback.
-    virtual bool OnInvalidManifest(AppBannerDataFetcher* fetcher) = 0;
+    // Called to handle a non-web app. Returns |true| if the non-web app can be
+    // handled, and the fetcher needs to remain active and wait for a callback.
+    virtual bool HandleNonWebApp(const std::string& platform,
+                                 const GURL& url,
+                                 const std::string& id) = 0;
   };
 
   // Returns the current time.
@@ -137,7 +139,7 @@
 
   // Returns whether the given Manifest is following the requirements to show
   // a web app banner.
-  static bool IsManifestValid(const content::Manifest& manifest);
+  static bool IsManifestValidForWebApp(const content::Manifest& manifest);
 
   const int ideal_icon_size_;
   const base::WeakPtr<Delegate> weak_delegate_;
diff --git a/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc b/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc
index 0d119c6..c72e861 100644
--- a/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc
+++ b/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc
@@ -54,8 +54,7 @@
 class AppBannerDataFetcherBrowserTest : public InProcessBrowserTest,
                                         public AppBannerDataFetcher::Delegate {
  public:
-  AppBannerDataFetcherBrowserTest() : manifest_was_invalid_(false),
-                                      weak_factory_(this) {
+  AppBannerDataFetcherBrowserTest() : weak_factory_(this) {
   }
 
   void SetUpOnMainThread() override {
@@ -63,9 +62,11 @@
     InProcessBrowserTest::SetUpOnMainThread();
   }
 
-  bool OnInvalidManifest(AppBannerDataFetcher* fetcher) override {
+  bool HandleNonWebApp(const std::string& platform,
+                       const GURL& url,
+                       const std::string& id) override {
     base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
-    manifest_was_invalid_ = true;
+    non_web_platform_ = platform;
     return false;
   }
 
@@ -76,7 +77,7 @@
 
  protected:
   void RunFetcher(const GURL& url,
-                  bool expected_manifest_valid,
+                  const std::string& expected_non_web_platform,
                   bool expected_to_show) {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
@@ -91,7 +92,7 @@
     fetcher->Start(url);
     run_loop.Run();
 
-    EXPECT_EQ(expected_manifest_valid, !manifest_was_invalid_);
+    EXPECT_EQ(expected_non_web_platform, non_web_platform_);
     EXPECT_EQ(expected_to_show, observer->will_show());
     ASSERT_FALSE(fetcher->is_active());
   }
@@ -106,54 +107,69 @@
   }
 
  private:
-  bool manifest_was_invalid_;
+  std::string non_web_platform_;
   base::Closure quit_closure_;
   base::WeakPtrFactory<AppBannerDataFetcherBrowserTest> weak_factory_;
 };
 
 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest, WebAppBannerCreated) {
-  std::string valid_page = "/banners/manifest_test_page.html";
+  std::string valid_page("/banners/manifest_test_page.html");
   GURL test_url = embedded_test_server()->GetURL(valid_page);
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
   LoadURLAndWaitForServiceWorker(test_url);
-  RunFetcher(web_contents->GetURL(), true, false);
+  RunFetcher(web_contents->GetURL(), std::string(), false);
 
   // Advance by a day, then visit the page again to trigger the banner.
   AppBannerDataFetcher::SetTimeDeltaForTesting(1);
   LoadURLAndWaitForServiceWorker(test_url);
-  RunFetcher(web_contents->GetURL(), true, true);
+  RunFetcher(web_contents->GetURL(), std::string(), true);
+}
+
+IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest, PlayAppManifest) {
+  std::string valid_page("/banners/play_app_test_page.html");
+  GURL test_url = embedded_test_server()->GetURL(valid_page);
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Native banners do not require the SW, so we can just load the URL.
+  ui_test_utils::NavigateToURL(browser(), test_url);
+  std::string play_platform("play");
+  RunFetcher(web_contents->GetURL(), play_platform, false);
+
+  // The logic to get the details for a play app banner are only on android
+  // builds, so this test does not check that the banner is shown.
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest, NoManifest) {
-  std::string valid_page = "/banners/no_manifest_test_page.html";
+  std::string valid_page("/banners/no_manifest_test_page.html");
   GURL test_url = embedded_test_server()->GetURL(valid_page);
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
   LoadURLAndWaitForServiceWorker(test_url);
-  RunFetcher(web_contents->GetURL(), false, false);
+  RunFetcher(web_contents->GetURL(), std::string(), false);
 
   // Advance by a day, then visit the page again.  Still shouldn't see a banner.
   AppBannerDataFetcher::SetTimeDeltaForTesting(1);
   LoadURLAndWaitForServiceWorker(test_url);
-  RunFetcher(web_contents->GetURL(), false, false);
+  RunFetcher(web_contents->GetURL(), std::string(), false);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest, CancelBanner) {
-  std::string valid_page = "/banners/cancel_test_page.html";
+  std::string valid_page("/banners/cancel_test_page.html");
   GURL test_url = embedded_test_server()->GetURL(valid_page);
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
   LoadURLAndWaitForServiceWorker(test_url);
-  RunFetcher(web_contents->GetURL(), true, false);
+  RunFetcher(web_contents->GetURL(), std::string(), false);
 
   // Advance by a day, then visit the page again.  Still shouldn't see a banner.
   AppBannerDataFetcher::SetTimeDeltaForTesting(1);
   LoadURLAndWaitForServiceWorker(test_url);
-  RunFetcher(web_contents->GetURL(), true, false);
+  RunFetcher(web_contents->GetURL(), std::string(), false);
 }
 
 }  // namespace banners
diff --git a/chrome/browser/banners/app_banner_data_fetcher_unittest.cc b/chrome/browser/banners/app_banner_data_fetcher_unittest.cc
index d662c80..2254130 100644
--- a/chrome/browser/banners/app_banner_data_fetcher_unittest.cc
+++ b/chrome/browser/banners/app_banner_data_fetcher_unittest.cc
@@ -33,7 +33,7 @@
   }
 
   static bool IsManifestValid(const content::Manifest& manifest) {
-    return AppBannerDataFetcher::IsManifestValid(manifest);
+    return AppBannerDataFetcher::IsManifestValidForWebApp(manifest);
   }
 };
 
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index 67eae4f..6fdd5cf1 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -59,7 +59,9 @@
 }
 
 
-bool AppBannerManager::OnInvalidManifest(AppBannerDataFetcher* fetcher) {
+bool AppBannerManager::HandleNonWebApp(const std::string& platform,
+                                       const GURL& url,
+                                       const std::string& id) {
   return false;
 }
 
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index 020c559..a84be60 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -43,9 +43,6 @@
   void DidFinishLoad(content::RenderFrameHost* render_frame_host,
                      const GURL& validated_url) override;
 
-  // AppBannerDataFetcher::Delegate overrides.
-  bool OnInvalidManifest(AppBannerDataFetcher* fetcher) override;
-
  protected:
   void ReplaceWebContents(content::WebContents* web_contents);
 
@@ -61,6 +58,11 @@
   int ideal_icon_size() { return ideal_icon_size_; }
 
  private:
+  // AppBannerDataFetcher::Delegate overrides.
+  bool HandleNonWebApp(const std::string& platform,
+                       const GURL& url,
+                       const std::string& id) override;
+
   // Called after the manager sends a message to the renderer regarding its
   // intention to show a prompt. The renderer will send a message back with the
   // opportunity to cancel.
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
index e413fa1..e5d189a1 100644
--- a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
+++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
@@ -12,9 +12,7 @@
 namespace chrome {
 
 BitmapFetcher::BitmapFetcher(const GURL& url, BitmapFetcherDelegate* delegate)
-    : ImageRequest(content::BrowserThread::GetMessageLoopProxyForThread(
-          content::BrowserThread::UI)),
-      url_(url),
+    : url_(url),
       delegate_(delegate) {
 }
 
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc
index 73513c8..a63d7d2 100644
--- a/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc
+++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -27,7 +28,10 @@
     target_->OnImageChanged();
   }
 
+ private:
   TestNotificationInterface* target_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestObserver);
 };
 
 class TestService : public BitmapFetcherService {
@@ -48,30 +52,33 @@
 class BitmapFetcherServiceTest : public testing::Test,
                                  public TestNotificationInterface {
  public:
+  BitmapFetcherServiceTest()
+      : url1_(GURL("http://example.org/sample-image-1.png")),
+        url2_(GURL("http://example.org/sample-image-2.png")) {
+  }
+
   void SetUp() override {
     service_.reset(new TestService(&profile_));
-    requestsFinished_ = 0;
-    imagesChanged_ = 0;
-    url1_ = GURL("http://example.org/sample-image-1.png");
-    url2_ = GURL("http://example.org/sample-image-2.png");
+    requests_finished_ = 0;
+    images_changed_ = 0;
   }
 
-  const ScopedVector<BitmapFetcherRequest>& requests() {
+  const ScopedVector<BitmapFetcherRequest>& requests() const {
     return service_->requests_;
   }
-  const ScopedVector<chrome::BitmapFetcher>& active_fetchers() {
+  const ScopedVector<chrome::BitmapFetcher>& active_fetchers() const {
     return service_->active_fetchers_;
   }
-  size_t cache_size() { return service_->cache_.size(); }
+  size_t cache_size() const { return service_->cache_.size(); }
 
-  void OnImageChanged() override { imagesChanged_++; }
+  void OnImageChanged() override { images_changed_++; }
 
-  void OnRequestFinished() override { requestsFinished_++; }
+  void OnRequestFinished() override { requests_finished_++; }
 
   // Simulate finishing a URL fetch and decode for the given fetcher.
   void CompleteFetch(const GURL& url) {
     const chrome::BitmapFetcher* fetcher = service_->FindFetcherForUrl(url);
-    ASSERT_TRUE(NULL != fetcher);
+    ASSERT_TRUE(fetcher);
 
     // Create a non-empty bitmap.
     SkBitmap image;
@@ -83,20 +90,21 @@
 
   void FailFetch(const GURL& url) {
     const chrome::BitmapFetcher* fetcher = service_->FindFetcherForUrl(url);
-    ASSERT_TRUE(NULL != fetcher);
+    ASSERT_TRUE(fetcher);
     const_cast<chrome::BitmapFetcher*>(fetcher)->OnImageDecoded(SkBitmap());
   }
 
  protected:
   scoped_ptr<BitmapFetcherService> service_;
 
-  int imagesChanged_;
-  int requestsFinished_;
+  int images_changed_;
+  int requests_finished_;
 
-  GURL url1_;
-  GURL url2_;
+  const GURL url1_;
+  const GURL url2_;
 
  private:
+  content::TestBrowserThreadBundle thread_bundle_;
   TestingProfile profile_;
 };
 
@@ -135,8 +143,8 @@
   EXPECT_EQ(4U, requests().size());
 
   CompleteFetch(url1_);
-  EXPECT_EQ(4, imagesChanged_);
-  EXPECT_EQ(4, requestsFinished_);
+  EXPECT_EQ(4, images_changed_);
+  EXPECT_EQ(4, requests_finished_);
 }
 
 TEST_F(BitmapFetcherServiceTest, CancelRequest) {
@@ -152,10 +160,10 @@
   EXPECT_EQ(4U, requests().size());
 
   CompleteFetch(url2_);
-  EXPECT_EQ(0, imagesChanged_);
+  EXPECT_EQ(0, images_changed_);
 
   CompleteFetch(url1_);
-  EXPECT_EQ(4, imagesChanged_);
+  EXPECT_EQ(4, images_changed_);
 }
 
 TEST_F(BitmapFetcherServiceTest, FailedRequestsDontEnterCache) {
diff --git a/chrome/browser/captive_portal/captive_portal_tab_helper.cc b/chrome/browser/captive_portal/captive_portal_tab_helper.cc
index 2b63c03..8aa0b309 100644
--- a/chrome/browser/captive_portal/captive_portal_tab_helper.cc
+++ b/chrome/browser/captive_portal/captive_portal_tab_helper.cc
@@ -93,7 +93,7 @@
   provisional_render_view_host_ = render_view_host;
   pending_error_code_ = net::OK;
 
-  tab_reloader_->OnLoadStart(validated_url.SchemeUsesTLS());
+  tab_reloader_->OnLoadStart(validated_url.SchemeIsCryptographic());
 }
 
 void CaptivePortalTabHelper::DidCommitProvisionalLoadForFrame(
@@ -115,7 +115,7 @@
     OnLoadAborted();
 
     // Send information about the new load.
-    tab_reloader_->OnLoadStart(url.SchemeUsesTLS());
+    tab_reloader_->OnLoadStart(url.SchemeIsCryptographic());
     tab_reloader_->OnLoadCommitted(net::OK);
   }
 
@@ -239,7 +239,7 @@
     return;
   }
 
-  tab_reloader_->OnRedirect(new_url.SchemeUsesTLS());
+  tab_reloader_->OnRedirect(new_url.SchemeIsCryptographic());
 }
 
 void CaptivePortalTabHelper::OnCaptivePortalResults(
diff --git a/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc b/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
index eab6ca1..ce0c9c7 100644
--- a/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
+++ b/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
@@ -87,7 +87,8 @@
   // Simulates a successful load of |url|.
   void SimulateSuccess(const GURL& url,
                        content::RenderViewHost* render_view_host) {
-    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeUsesTLS())).Times(1);
+    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeIsCryptographic()))
+        .Times(1);
     tab_helper().DidStartProvisionalLoadForFrame(
         render_view_host->GetMainFrame(), url, false, false);
 
@@ -101,7 +102,8 @@
   // Simulates a connection timeout while requesting |url|.
   void SimulateTimeout(const GURL& url,
                        content::RenderViewHost* render_view_host) {
-    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeUsesTLS())).Times(1);
+    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeIsCryptographic()))
+        .Times(1);
     tab_helper().DidStartProvisionalLoadForFrame(
         render_view_host->GetMainFrame(), url, false, false);
 
@@ -125,7 +127,8 @@
   void SimulateAbort(const GURL& url,
                      content::RenderViewHost* render_view_host,
                      NavigationType navigation_type) {
-    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeUsesTLS())).Times(1);
+    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeIsCryptographic()))
+        .Times(1);
     tab_helper().DidStartProvisionalLoadForFrame(
         render_view_host->GetMainFrame(), url, false, false);
 
@@ -151,7 +154,8 @@
   void SimulateAbortTimeout(const GURL& url,
                             content::RenderViewHost* render_view_host,
                             NavigationType navigation_type) {
-    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeUsesTLS())).Times(1);
+    EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeIsCryptographic()))
+        .Times(1);
     tab_helper().DidStartProvisionalLoadForFrame(
         render_view_host->GetMainFrame(), url, false, false);
 
@@ -334,7 +338,7 @@
 
   // A same-site load for the original RenderViewHost starts.
   EXPECT_CALL(mock_reloader(),
-              OnLoadStart(same_site_url.SchemeUsesTLS())).Times(1);
+              OnLoadStart(same_site_url.SchemeIsCryptographic())).Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame1(), same_site_url, false, false);
 
@@ -343,7 +347,7 @@
   // for the old navigation.
   EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
   EXPECT_CALL(mock_reloader(),
-              OnLoadStart(cross_process_url.SchemeUsesTLS())).Times(1);
+              OnLoadStart(cross_process_url.SchemeIsCryptographic())).Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame2(), cross_process_url, false, false);
 
@@ -378,7 +382,7 @@
 
   // A same-site load for the original RenderViewHost starts.
   EXPECT_CALL(mock_reloader(),
-              OnLoadStart(same_site_url.SchemeUsesTLS())).Times(1);
+              OnLoadStart(same_site_url.SchemeIsCryptographic())).Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame1(), same_site_url, false, false);
 
@@ -387,7 +391,7 @@
   // for the old navigation.
   EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
   EXPECT_CALL(mock_reloader(),
-              OnLoadStart(cross_process_url.SchemeUsesTLS())).Times(1);
+              OnLoadStart(cross_process_url.SchemeIsCryptographic())).Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame2(), cross_process_url, false, false);
 
@@ -400,7 +404,7 @@
   // The same-site navigation succeeds.
   EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
   EXPECT_CALL(mock_reloader(),
-              OnLoadStart(same_site_url.SchemeUsesTLS())).Times(1);
+              OnLoadStart(same_site_url.SchemeIsCryptographic())).Times(1);
   EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK)).Times(1);
   tab_helper().DidCommitProvisionalLoadForFrame(
       main_render_frame1(), same_site_url, ui::PAGE_TRANSITION_LINK);
@@ -450,7 +454,8 @@
           ->AppendChild("subframe");
 
   // Loads start.
-  EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeUsesTLS())).Times(1);
+  EXPECT_CALL(mock_reloader(), OnLoadStart(url.SchemeIsCryptographic()))
+      .Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame1(), url, false, false);
   tab_helper().DidStartProvisionalLoadForFrame(subframe, url, false, false);
@@ -505,13 +510,14 @@
 // Simulates an HTTPS to HTTP redirect.
 TEST_F(CaptivePortalTabHelperTest, HttpsToHttpRedirect) {
   GURL https_url(kHttpsUrl);
-  EXPECT_CALL(mock_reloader(),
-              OnLoadStart(https_url.SchemeUsesTLS())).Times(1);
+  EXPECT_CALL(mock_reloader(), OnLoadStart(https_url.SchemeIsCryptographic()))
+      .Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame1(), https_url, false, false);
 
   GURL http_url(kHttpUrl);
-  EXPECT_CALL(mock_reloader(), OnRedirect(http_url.SchemeUsesTLS())).Times(1);
+  EXPECT_CALL(mock_reloader(), OnRedirect(http_url.SchemeIsCryptographic()))
+      .Times(1);
   OnRedirect(content::RESOURCE_TYPE_MAIN_FRAME, http_url,
              render_view_host1()->GetProcess()->GetID());
 
@@ -523,12 +529,13 @@
 // Simulates an HTTPS to HTTPS redirect.
 TEST_F(CaptivePortalTabHelperTest, HttpToHttpRedirect) {
   GURL http_url(kHttpUrl);
-  EXPECT_CALL(mock_reloader(),
-              OnLoadStart(http_url.SchemeUsesTLS())).Times(1);
+  EXPECT_CALL(mock_reloader(), OnLoadStart(http_url.SchemeIsCryptographic()))
+      .Times(1);
   tab_helper().DidStartProvisionalLoadForFrame(
       main_render_frame1(), http_url, false, false);
 
-  EXPECT_CALL(mock_reloader(), OnRedirect(http_url.SchemeUsesTLS())).Times(1);
+  EXPECT_CALL(mock_reloader(), OnRedirect(http_url.SchemeIsCryptographic()))
+      .Times(1);
   OnRedirect(content::RESOURCE_TYPE_MAIN_FRAME, http_url,
              render_view_host1()->GetProcess()->GetID());
 
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index a76aad9..a8c1b1f 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -553,18 +553,6 @@
   DISALLOW_COPY_AND_ASSIGN(LoadCompleteListener);
 };
 
-base::StackSamplingProfiler::SamplingParams GetStartupSamplingParams() {
-  // Sample at 10Hz for 30 seconds.
-  base::StackSamplingProfiler::SamplingParams params;
-  params.initial_delay = base::TimeDelta::FromMilliseconds(0);
-  params.bursts = 1;
-  params.samples_per_burst = 300;
-  params.sampling_interval = base::TimeDelta::FromMilliseconds(100);
-  params.preserve_sample_ordering = false;
-  params.user_data = metrics::CallStackProfileMetricsProvider::PROCESS_STARTUP;
-  return params;
-}
-
 }  // namespace
 
 namespace chrome_browser {
@@ -593,14 +581,11 @@
       startup_watcher_(new StartupTimeBomb()),
       shutdown_watcher_(new ShutdownWatcherHelper()),
       browser_field_trials_(parameters.command_line),
-      sampling_profiler_(base::PlatformThread::CurrentId(),
-                         GetStartupSamplingParams()),
       profile_(NULL),
       run_message_loop_(true),
       notify_result_(ProcessSingleton::PROCESS_NONE),
       local_state_(NULL),
       restart_last_session_(false) {
-  sampling_profiler_.Start();
   // If we're running tests (ui_task is non-null).
   if (parameters.ui_task)
     browser_defaults::enable_help_app = false;
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index 02e5d58..b0fd85ef 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -8,7 +8,6 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/field_trial.h"
-#include "base/profiler/stack_sampling_profiler.h"
 #include "base/tracked_objects.h"
 #include "chrome/browser/chrome_browser_field_trials.h"
 #include "chrome/browser/chrome_process_singleton.h"
@@ -144,10 +143,6 @@
   // Parts are deleted in the inverse order they are added.
   std::vector<ChromeBrowserMainExtraParts*> chrome_extra_parts_;
 
-  // A profiler that periodically samples stack traces. Used to sample startup
-  // behavior.
-  base::StackSamplingProfiler sampling_profiler_;
-
   // Members initialized after / released before main_message_loop_ ------------
 
   scoped_ptr<BrowserProcessImpl> browser_process_;
diff --git a/chrome/browser/chromeos/app_mode/certificate_manager_dialog.cc b/chrome/browser/chromeos/app_mode/certificate_manager_dialog.cc
index 516f87b9..7546ae3 100644
--- a/chrome/browser/chromeos/app_mode/certificate_manager_dialog.cc
+++ b/chrome/browser/chromeos/app_mode/certificate_manager_dialog.cc
@@ -43,7 +43,7 @@
                      window,
                      base::string16(),
                      GURL(chrome::kChromeUICertificateManagerDialogURL)) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size()));
   SetDialogSize(CalculateSize(screen_bounds.width(),
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index ab182b58..a37df89e 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -23,6 +23,7 @@
 #include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_external_updater.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/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
@@ -183,20 +184,20 @@
   return auto_launch_app_id_;
 }
 
-void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) {
+void KioskAppManager::SetAutoLaunchApp(const std::string& app_id,
+                                       OwnerSettingsServiceChromeOS* service) {
   SetAutoLoginState(AUTOLOGIN_REQUESTED);
   // Clean first, so the proper change callbacks are triggered even
   // if we are only changing AutoLoginState here.
   if (!auto_launch_app_id_.empty()) {
-    CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
-                                   std::string());
+    service->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
+                       std::string());
   }
 
-  CrosSettings::Get()->SetString(
+  service->SetString(
       kAccountsPrefDeviceLocalAccountAutoLoginId,
       app_id.empty() ? std::string() : GenerateKioskAppAccountId(app_id));
-  CrosSettings::Get()->SetInteger(
-      kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0);
+  service->SetInteger(kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0);
 }
 
 void KioskAppManager::SetAppWasAutoLaunchedWithZeroDelay(
@@ -332,7 +333,8 @@
   return GetAutoLoginState() == AUTOLOGIN_APPROVED;
 }
 
-void KioskAppManager::AddApp(const std::string& app_id) {
+void KioskAppManager::AddApp(const std::string& app_id,
+                             OwnerSettingsServiceChromeOS* service) {
   std::vector<policy::DeviceLocalAccount> device_local_accounts =
       policy::GetDeviceLocalAccounts(CrosSettings::Get());
 
@@ -353,13 +355,14 @@
       app_id,
       std::string()));
 
-  policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts);
+  policy::SetDeviceLocalAccounts(service, device_local_accounts);
 }
 
-void KioskAppManager::RemoveApp(const std::string& app_id) {
+void KioskAppManager::RemoveApp(const std::string& app_id,
+                                OwnerSettingsServiceChromeOS* service) {
   // Resets auto launch app if it is the removed app.
   if (auto_launch_app_id_ == app_id)
-    SetAutoLaunchApp(std::string());
+    SetAutoLaunchApp(std::string(), service);
 
   std::vector<policy::DeviceLocalAccount> device_local_accounts =
       policy::GetDeviceLocalAccounts(CrosSettings::Get());
@@ -377,7 +380,7 @@
     }
   }
 
-  policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts);
+  policy::SetDeviceLocalAccounts(service, device_local_accounts);
 }
 
 void KioskAppManager::GetApps(Apps* apps) const {
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
index aff5898..72d511c 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -38,6 +38,7 @@
 class KioskAppExternalLoader;
 class KioskAppManagerObserver;
 class KioskExternalUpdater;
+class OwnerSettingsServiceChromeOS;
 
 // KioskAppManager manages cached app data.
 class KioskAppManager : public KioskAppDataDelegate,
@@ -121,7 +122,8 @@
   std::string GetAutoLaunchApp() const;
 
   // Sets |app_id| as the app to auto launch at start up.
-  void SetAutoLaunchApp(const std::string& app_id);
+  void SetAutoLaunchApp(const std::string& app_id,
+                        OwnerSettingsServiceChromeOS* service);
 
   // Returns true if there is a pending auto-launch request.
   bool IsAutoLaunchRequested() const;
@@ -134,8 +136,9 @@
 
   // Adds/removes a kiosk app by id. When removed, all locally cached data
   // will be removed as well.
-  void AddApp(const std::string& app_id);
-  void RemoveApp(const std::string& app_id);
+  void AddApp(const std::string& app_id, OwnerSettingsServiceChromeOS* service);
+  void RemoveApp(const std::string& app_id,
+                 OwnerSettingsServiceChromeOS* service);
 
   // Gets info of all apps that have no meta data load error.
   void GetApps(Apps* apps) const;
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
index 48498b6..16f85d0 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/path_service.h"
 #include "base/prefs/scoped_user_pref_update.h"
@@ -15,9 +16,10 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/app_mode/fake_cws.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
+#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
@@ -165,7 +167,7 @@
 
 class KioskAppManagerTest : public InProcessBrowserTest {
  public:
-  KioskAppManagerTest() : fake_cws_(new FakeCWS()) {}
+  KioskAppManagerTest() : settings_helper_(false), fake_cws_(new FakeCWS()) {}
   ~KioskAppManagerTest() override {}
 
   // InProcessBrowserTest overrides:
@@ -195,8 +197,14 @@
 
     // Restart the thread as the sandbox host process has already been spawned.
     embedded_test_server()->RestartThreadAndListen();
+
+    settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts);
+    owner_settings_service_ =
+        settings_helper_.CreateOwnerSettingsService(browser()->profile());
   }
 
+  void TearDownOnMainThread() override { settings_helper_.RestoreProvider(); }
+
   void SetUpInProcessBrowserTestFixture() override {
     InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
 
@@ -270,8 +278,8 @@
         kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
         app_id);
     device_local_accounts.Append(entry.release());
-    CrosSettings::Get()->Set(kAccountsPrefDeviceLocalAccounts,
-                             device_local_accounts);
+    owner_settings_service_->Set(kAccountsPrefDeviceLocalAccounts,
+                                 device_local_accounts);
   }
 
   bool GetCachedCrx(const std::string& app_id,
@@ -289,7 +297,7 @@
     fake_cws_->SetUpdateCrx(id, crx_file_name, version);
 
     AppDataLoadWaiter waiter(manager(), 3);
-    manager()->AddApp(id);
+    manager()->AddApp(id, owner_settings_service_.get());
     waiter.Wait();
     EXPECT_TRUE(waiter.loaded());
 
@@ -342,6 +350,10 @@
   KioskAppManager* manager() const { return KioskAppManager::Get(); }
   FakeCWS* fake_cws() { return fake_cws_.get(); }
 
+ protected:
+  ScopedCrosSettingsTestHelper settings_helper_;
+  scoped_ptr<FakeOwnerSettingsService> owner_settings_service_;
+
  private:
   base::ScopedTempDir temp_dir_;
   scoped_ptr<FakeCWS> fake_cws_;
@@ -353,12 +365,12 @@
   // Add a couple of apps. Use "fake_app_x" that do not have data on the test
   // server to avoid pending data loads that could be lingering on tear down and
   // cause DCHECK failure in utility_process_host_impl.cc.
-  manager()->AddApp("fake_app_1");
-  manager()->AddApp("fake_app_2");
+  manager()->AddApp("fake_app_1", owner_settings_service_.get());
+  manager()->AddApp("fake_app_2", owner_settings_service_.get());
   EXPECT_EQ("fake_app_1,fake_app_2", GetAppIds());
 
   // Set an auto launch app.
-  manager()->SetAutoLaunchApp("fake_app_1");
+  manager()->SetAutoLaunchApp("fake_app_1", owner_settings_service_.get());
   EXPECT_EQ("fake_app_1", manager()->GetAutoLaunchApp());
 
   // Make sure that if an app was auto launched with zero delay, it is reflected
@@ -372,7 +384,7 @@
   EXPECT_TRUE(app.was_auto_launched_with_zero_delay);
 
   // Clear the auto launch app.
-  manager()->SetAutoLaunchApp("");
+  manager()->SetAutoLaunchApp("", owner_settings_service_.get());
   EXPECT_EQ("", manager()->GetAutoLaunchApp());
   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
 
@@ -382,7 +394,7 @@
   EXPECT_TRUE(app.was_auto_launched_with_zero_delay);
 
   // Set another auto launch app.
-  manager()->SetAutoLaunchApp("fake_app_2");
+  manager()->SetAutoLaunchApp("fake_app_2", owner_settings_service_.get());
   EXPECT_EQ("fake_app_2", manager()->GetAutoLaunchApp());
 
   // Check auto launch permissions.
@@ -391,24 +403,24 @@
   EXPECT_TRUE(manager()->IsAutoLaunchEnabled());
 
   // Remove the auto launch app.
-  manager()->RemoveApp("fake_app_2");
+  manager()->RemoveApp("fake_app_2", owner_settings_service_.get());
   EXPECT_EQ("fake_app_1", GetAppIds());
   EXPECT_EQ("", manager()->GetAutoLaunchApp());
 
   // Add the just removed auto launch app again and it should no longer be
   // the auto launch app.
-  manager()->AddApp("fake_app_2");
+  manager()->AddApp("fake_app_2", owner_settings_service_.get());
   EXPECT_EQ("", manager()->GetAutoLaunchApp());
-  manager()->RemoveApp("fake_app_2");
+  manager()->RemoveApp("fake_app_2", owner_settings_service_.get());
   EXPECT_EQ("fake_app_1", GetAppIds());
 
   // Set a none exist app as auto launch.
-  manager()->SetAutoLaunchApp("none_exist_app");
+  manager()->SetAutoLaunchApp("none_exist_app", owner_settings_service_.get());
   EXPECT_EQ("", manager()->GetAutoLaunchApp());
   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
 
   // Add an existing app again.
-  manager()->AddApp("fake_app_1");
+  manager()->AddApp("fake_app_1", owner_settings_service_.get());
   EXPECT_EQ("fake_app_1", GetAppIds());
 }
 
@@ -473,7 +485,7 @@
 
 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) {
   AppDataLoadWaiter waiter(manager(), 2);
-  manager()->AddApp("unknown_app");
+  manager()->AddApp("unknown_app", owner_settings_service_.get());
   waiter.Wait();
   EXPECT_FALSE(waiter.loaded());
   EXPECT_EQ("", GetAppIds());
@@ -484,7 +496,7 @@
   //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_1
   fake_cws()->SetNoUpdate("app_1");
   AppDataLoadWaiter waiter(manager(), 2);
-  manager()->AddApp("app_1");
+  manager()->AddApp("app_1", owner_settings_service_.get());
   waiter.Wait();
   EXPECT_TRUE(waiter.loaded());
 
@@ -533,7 +545,7 @@
   EXPECT_EQ("1.0.0", version);
 
   // Remove the app now.
-  manager()->RemoveApp(kTestLocalFsKioskApp);
+  manager()->RemoveApp(kTestLocalFsKioskApp, owner_settings_service_.get());
   content::RunAllBlockingPoolTasksUntilIdle();
   manager()->GetApps(&apps);
   ASSERT_EQ(0u, apps.size());
@@ -615,7 +627,7 @@
   EXPECT_TRUE(base::PathExists(v2_crx_path));
 
   // Remove the app now.
-  manager()->RemoveApp(kTestLocalFsKioskApp);
+  manager()->RemoveApp(kTestLocalFsKioskApp, owner_settings_service_.get());
   content::RunAllBlockingPoolTasksUntilIdle();
   manager()->GetApps(&apps);
   ASSERT_EQ(0u, apps.size());
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
index ee8d5de3..138d8b0 100644
--- a/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
+++ b/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
@@ -99,7 +99,7 @@
       num_retries_(0),
       retry_delay_(kRetryDelay),
       weak_factory_(this) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   attestation_subscription_ = cros_settings_->AddSettingsObserver(
       kDeviceAttestationEnabled,
       base::Bind(&AttestationPolicyObserver::AttestationSettingChanged,
@@ -118,7 +118,7 @@
       num_retries_(0),
       retry_delay_(kRetryDelay),
       weak_factory_(this) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   attestation_subscription_ = cros_settings_->AddSettingsObserver(
       kDeviceAttestationEnabled,
       base::Bind(&AttestationPolicyObserver::AttestationSettingChanged,
@@ -127,7 +127,7 @@
 }
 
 AttestationPolicyObserver::~AttestationPolicyObserver() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 }
 
 void AttestationPolicyObserver::AttestationSettingChanged() {
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc
index 61fa81f..ebb0fd0 100644
--- a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc
+++ b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc
@@ -10,9 +10,7 @@
 #include "chrome/browser/chromeos/attestation/attestation_key_payload.pb.h"
 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
 #include "chrome/browser/chromeos/attestation/fake_certificate.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chromeos/attestation/mock_attestation_flow.h"
 #include "chromeos/dbus/mock_cryptohome_client.h"
 #include "chromeos/settings/cros_settings_names.h"
@@ -80,23 +78,11 @@
  public:
   AttestationPolicyObserverTest()
       : ui_thread_(content::BrowserThread::UI, &message_loop_) {
-    // Remove the real DeviceSettingsProvider and replace it with a stub.
-    CrosSettings* cros_settings = CrosSettings::Get();
-    device_settings_provider_ =
-        cros_settings->GetProvider(kDeviceAttestationEnabled);
-    cros_settings->RemoveSettingsProvider(device_settings_provider_);
-    cros_settings->AddSettingsProvider(&stub_settings_provider_);
-    cros_settings->SetBoolean(kDeviceAttestationEnabled, true);
+    settings_helper_.ReplaceProvider(kDeviceAttestationEnabled);
+    settings_helper_.SetBoolean(kDeviceAttestationEnabled, true);
     policy_client_.SetDMToken("fake_dm_token");
   }
 
-  virtual ~AttestationPolicyObserverTest() {
-    // Restore the real DeviceSettingsProvider.
-    CrosSettings* cros_settings = CrosSettings::Get();
-    cros_settings->RemoveSettingsProvider(&stub_settings_provider_);
-    cros_settings->AddSettingsProvider(device_settings_provider_);
-  }
-
  protected:
   enum MockOptions {
     MOCK_KEY_EXISTS = 1,          // Configure so a certified key exists.
@@ -168,18 +154,14 @@
 
   base::MessageLoopForUI message_loop_;
   content::TestBrowserThread ui_thread_;
-  ScopedTestDeviceSettingsService test_device_settings_service_;
-  ScopedTestCrosSettings test_cros_settings_;
-  CrosSettingsProvider* device_settings_provider_;
-  StubCrosSettingsProvider stub_settings_provider_;
+  ScopedCrosSettingsTestHelper settings_helper_;
   StrictMock<MockCryptohomeClient> cryptohome_client_;
   StrictMock<MockAttestationFlow> attestation_flow_;
   StrictMock<policy::MockCloudPolicyClient> policy_client_;
 };
 
 TEST_F(AttestationPolicyObserverTest, FeatureDisabled) {
-  CrosSettings* cros_settings = CrosSettings::Get();
-  cros_settings->SetBoolean(kDeviceAttestationEnabled, false);
+  settings_helper_.SetBoolean(kDeviceAttestationEnabled, false);
   Run();
 }
 
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.cc b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
index cb15208..03170f4 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
@@ -141,7 +141,7 @@
       cryptohome_client_(DBusThreadManager::Get()->GetCryptohomeClient()),
       delegate_(NULL),
       timeout_delay_(base::TimeDelta::FromSeconds(kTimeoutInSeconds)) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   scoped_ptr<ServerProxy> attestation_ca_client(new AttestationCAClient());
   default_attestation_flow_.reset(new AttestationFlow(
       async_caller_,
@@ -162,7 +162,7 @@
       cryptohome_client_(cryptohome_client),
       delegate_(delegate),
       timeout_delay_(base::TimeDelta::FromSeconds(kTimeoutInSeconds)) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!delegate_) {
     default_delegate_.reset(new DefaultDelegate());
     delegate_ = default_delegate_.get();
@@ -177,7 +177,7 @@
     const std::string& service_id,
     const std::string& challenge,
     const ChallengeCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (!delegate_->GetURL(web_contents).is_valid()) {
     LOG(WARNING) << "PlatformVerificationFlow: Invalid URL.";
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
index a3101e5..5319ddf 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
@@ -11,9 +11,7 @@
 #include "chrome/browser/chromeos/attestation/fake_certificate.h"
 #include "chrome/browser/chromeos/attestation/platform_verification_flow.h"
 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/attestation/mock_attestation_flow.h"
@@ -153,20 +151,8 @@
     callback_ = base::Bind(&PlatformVerificationFlowTest::FakeChallengeCallback,
                            base::Unretained(this));
 
-    // Configure the global cros_settings.
-    CrosSettings* cros_settings = CrosSettings::Get();
-    device_settings_provider_ =
-        cros_settings->GetProvider(kAttestationForContentProtectionEnabled);
-    cros_settings->RemoveSettingsProvider(device_settings_provider_);
-    cros_settings->AddSettingsProvider(&stub_settings_provider_);
-    cros_settings->SetBoolean(kAttestationForContentProtectionEnabled, true);
-  }
-
-  void TearDown() {
-    // Restore the real DeviceSettingsProvider.
-    CrosSettings* cros_settings = CrosSettings::Get();
-    cros_settings->RemoveSettingsProvider(&stub_settings_provider_);
-    cros_settings->AddSettingsProvider(device_settings_provider_);
+    settings_helper_.ReplaceProvider(kAttestationForContentProtectionEnabled);
+    settings_helper_.SetBoolean(kAttestationForContentProtectionEnabled, true);
   }
 
   void ExpectAttestationFlow() {
@@ -239,10 +225,7 @@
   cryptohome::MockAsyncMethodCaller mock_async_caller_;
   CustomFakeCryptohomeClient fake_cryptohome_client_;
   FakeDelegate fake_delegate_;
-  CrosSettingsProvider* device_settings_provider_;
-  StubCrosSettingsProvider stub_settings_provider_;
-  ScopedTestDeviceSettingsService test_device_settings_service_;
-  ScopedTestCrosSettings test_cros_settings_;
+  ScopedCrosSettingsTestHelper settings_helper_;
   scoped_refptr<PlatformVerificationFlow> verifier_;
 
   // Controls result of FakeGetCertificate.
@@ -279,8 +262,7 @@
 }
 
 TEST_F(PlatformVerificationFlowTest, FeatureDisabledByPolicy) {
-  CrosSettings::Get()->SetBoolean(kAttestationForContentProtectionEnabled,
-                                  false);
+  settings_helper_.SetBoolean(kAttestationForContentProtectionEnabled, false);
   verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(PlatformVerificationFlow::POLICY_REJECTED, result_);
diff --git a/chrome/browser/chromeos/base/locale_util.cc b/chrome/browser/chromeos/base/locale_util.cc
index c185d78d..37e659b 100644
--- a/chrome/browser/chromeos/base/locale_util.cc
+++ b/chrome/browser/chromeos/base/locale_util.cc
@@ -50,7 +50,7 @@
 
 // Callback after SwitchLanguageDoReloadLocale() back in UI thread.
 void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (data->result.success) {
     g_browser_process->SetApplicationLocale(data->result.loaded_locale);
 
@@ -107,7 +107,7 @@
                     const bool enable_locale_keyboard_layouts,
                     const bool login_layouts_only,
                     const SwitchLanguageCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   scoped_ptr<SwitchLanguageData> data(new SwitchLanguageData(
       locale, enable_locale_keyboard_layouts, login_layouts_only, callback));
   base::Closure reloader(
diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.cc b/chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.cc
index 4943dd1e..ff089f38 100644
--- a/chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.cc
+++ b/chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.cc
@@ -86,8 +86,7 @@
 
 void BluetoothPairingDialog::OnCloseContents(WebContents* source,
                                              bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool BluetoothPairingDialog::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc b/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc
index 8e09a5a..3213831d 100644
--- a/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc
+++ b/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc
@@ -75,15 +75,15 @@
       retry_delay_(base::TimeDelta::FromSeconds(kRetrySleepSeconds)),
       on_wallpaper_fetch_completed_(on_wallpaper_fetch_completed),
       weak_factory_(this) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 }
 
 CustomizationWallpaperDownloader::~CustomizationWallpaperDownloader() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 }
 
 void CustomizationWallpaperDownloader::StartRequest() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(wallpaper_url_.is_valid());
 
   url_fetcher_.reset(
@@ -103,7 +103,7 @@
 }
 
 void CustomizationWallpaperDownloader::Retry() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   ++retries_;
 
   const double delay_seconds = std::min(
@@ -119,7 +119,7 @@
 }
 
 void CustomizationWallpaperDownloader::Start() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   scoped_ptr<bool> success(new bool(false));
 
   base::Closure mkdir_closure = base::Bind(&CreateWallpaperDirectory,
@@ -137,14 +137,14 @@
 
 void CustomizationWallpaperDownloader::OnWallpaperDirectoryCreated(
     scoped_ptr<bool> success) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (*success)
     StartRequest();
 }
 
 void CustomizationWallpaperDownloader::OnURLFetchComplete(
     const net::URLFetcher* source) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK_EQ(url_fetcher_.get(), source);
 
   const net::URLRequestStatus status = source->GetStatus();
@@ -188,7 +188,7 @@
 
 void CustomizationWallpaperDownloader::OnTemporaryFileRenamed(
     scoped_ptr<bool> success) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   on_wallpaper_fetch_completed_.Run(*success, wallpaper_url_);
 }
 
diff --git a/chrome/browser/chromeos/display/display_preferences.cc b/chrome/browser/chromeos/display/display_preferences.cc
index a71342d..dca2e5a2 100644
--- a/chrome/browser/chromeos/display/display_preferences.cc
+++ b/chrome/browser/chromeos/display/display_preferences.cc
@@ -348,16 +348,17 @@
 }
 
 void StoreDisplayRotationPrefs(bool rotation_lock) {
-  ash::DisplayManager* display_manager = GetDisplayManager();
-  if (!display_manager->HasInternalDisplay())
+  if (!gfx::Display::HasInternalDisplay())
     return;
 
   PrefService* local_state = g_browser_process->local_state();
   DictionaryPrefUpdate update(local_state, prefs::kDisplayRotationLock);
   base::DictionaryValue* pref_data = update.Get();
   pref_data->SetBoolean("lock", rotation_lock);
-  gfx::Display::Rotation rotation = display_manager->
-      GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
+  gfx::Display::Rotation rotation =
+      GetDisplayManager()
+          ->GetDisplayInfo(gfx::Display::InternalDisplayId())
+          .rotation();
   pref_data->SetInteger("orientation", static_cast<int>(rotation));
 }
 
diff --git a/chrome/browser/chromeos/drive/change_list_loader.cc b/chrome/browser/chromeos/drive/change_list_loader.cc
index 081d9a7..143927a 100644
--- a/chrome/browser/chromeos/drive/change_list_loader.cc
+++ b/chrome/browser/chromeos/drive/change_list_loader.cc
@@ -10,6 +10,7 @@
 #include "base/callback_helpers.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/synchronization/cancellation_flag.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/drive/change_list_loader_observer.h"
 #include "chrome/browser/chromeos/drive/change_list_processor.h"
@@ -294,6 +295,7 @@
     LoaderController* loader_controller)
     : logger_(logger),
       blocking_task_runner_(blocking_task_runner),
+      in_shutdown_(new base::CancellationFlag),
       resource_metadata_(resource_metadata),
       scheduler_(scheduler),
       about_resource_loader_(about_resource_loader),
@@ -303,6 +305,10 @@
 }
 
 ChangeListLoader::~ChangeListLoader() {
+  in_shutdown_->Set();
+  // Delete |in_shutdown_| with the blocking task runner so that it gets deleted
+  // after all active ChangeListProcessors.
+  blocking_task_runner_->DeleteSoon(FROM_HERE, in_shutdown_.release());
 }
 
 bool ChangeListLoader::IsRefreshing() const {
@@ -526,7 +532,7 @@
   }
 
   ChangeListProcessor* change_list_processor =
-      new ChangeListProcessor(resource_metadata_);
+      new ChangeListProcessor(resource_metadata_, in_shutdown_.get());
   // Don't send directory content change notification while performing
   // the initial content retrieval.
   const bool should_notify_changed_directories = is_delta_update;
diff --git a/chrome/browser/chromeos/drive/change_list_loader.h b/chrome/browser/chromeos/drive/change_list_loader.h
index 3486aa48..7bdac52 100644
--- a/chrome/browser/chromeos/drive/change_list_loader.h
+++ b/chrome/browser/chromeos/drive/change_list_loader.h
@@ -20,6 +20,7 @@
 class GURL;
 
 namespace base {
+class CancellationFlag;
 class ScopedClosureRunner;
 class SequencedTaskRunner;
 class Time;
@@ -213,6 +214,7 @@
 
   EventLogger* logger_;  // Not owned.
   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
+  scoped_ptr<base::CancellationFlag> in_shutdown_;
   ResourceMetadata* resource_metadata_;  // Not owned.
   JobScheduler* scheduler_;  // Not owned.
   AboutResourceLoader* about_resource_loader_;  // Not owned.
diff --git a/chrome/browser/chromeos/drive/change_list_processor.cc b/chrome/browser/chromeos/drive/change_list_processor.cc
index fb4f46e..4f1b4ce 100644
--- a/chrome/browser/chromeos/drive/change_list_processor.cc
+++ b/chrome/browser/chromeos/drive/change_list_processor.cc
@@ -6,6 +6,7 @@
 
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/synchronization/cancellation_flag.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/file_change.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
@@ -113,8 +114,11 @@
 
 ChangeList::~ChangeList() {}
 
-ChangeListProcessor::ChangeListProcessor(ResourceMetadata* resource_metadata)
-    : resource_metadata_(resource_metadata), changed_files_(new FileChange) {
+ChangeListProcessor::ChangeListProcessor(ResourceMetadata* resource_metadata,
+                                         base::CancellationFlag* in_shutdown)
+    : resource_metadata_(resource_metadata),
+      in_shutdown_(in_shutdown),
+      changed_files_(new FileChange) {
 }
 
 ChangeListProcessor::~ChangeListProcessor() {
@@ -230,6 +234,9 @@
   // Apply all entries except deleted ones to the metadata.
   std::vector<std::string> deleted_resource_ids;
   while (!entry_map_.empty()) {
+    if (in_shutdown_ && in_shutdown_->IsSet())
+      return FILE_ERROR_ABORT;
+
     ResourceEntryMap::iterator it = entry_map_.begin();
 
     // Process deleted entries later to avoid deleting moved entries under it.
diff --git a/chrome/browser/chromeos/drive/change_list_processor.h b/chrome/browser/chromeos/drive/change_list_processor.h
index 61ecf65..83a056e 100644
--- a/chrome/browser/chromeos/drive/change_list_processor.h
+++ b/chrome/browser/chromeos/drive/change_list_processor.h
@@ -16,11 +16,15 @@
 #include "chrome/browser/chromeos/drive/file_errors.h"
 #include "url/gurl.h"
 
+namespace base {
+class CancellationFlag;
+}  // namespace base
+
 namespace google_apis {
 class AboutResource;
 class ChangeList;
 class FileList;
-}  // google_apis
+}  // namespace google_apis
 
 namespace drive {
 
@@ -103,7 +107,8 @@
 // updates the resource metadata stored locally.
 class ChangeListProcessor {
  public:
-  explicit ChangeListProcessor(ResourceMetadata* resource_metadata);
+  ChangeListProcessor(ResourceMetadata* resource_metadata,
+                      base::CancellationFlag* in_shutdown);
   ~ChangeListProcessor();
 
   // Applies change lists or full resource lists to |resource_metadata_|.
@@ -151,6 +156,7 @@
   void UpdateChangedDirs(const ResourceEntry& entry);
 
   ResourceMetadata* resource_metadata_;  // Not owned.
+  base::CancellationFlag* in_shutdown_;  // Not owned.
 
   ResourceEntryMap entry_map_;
   ParentResourceIdMap parent_resource_id_map_;
diff --git a/chrome/browser/chromeos/drive/change_list_processor_unittest.cc b/chrome/browser/chromeos/drive/change_list_processor_unittest.cc
index be3457c..5ba073e 100644
--- a/chrome/browser/chromeos/drive/change_list_processor_unittest.cc
+++ b/chrome/browser/chromeos/drive/change_list_processor_unittest.cc
@@ -126,7 +126,7 @@
     about_resource->set_largest_change_id(kBaseResourceListChangestamp);
     about_resource->set_root_folder_id(kRootId);
 
-    ChangeListProcessor processor(metadata_.get());
+    ChangeListProcessor processor(metadata_.get(), nullptr);
     return processor.Apply(about_resource.Pass(),
                            changes.Pass(),
                            false /* is_delta_update */);
@@ -141,7 +141,7 @@
     about_resource->set_largest_change_id(kBaseResourceListChangestamp);
     about_resource->set_root_folder_id(kRootId);
 
-    ChangeListProcessor processor(metadata_.get());
+    ChangeListProcessor processor(metadata_.get(), nullptr);
     FileError error = processor.Apply(about_resource.Pass(),
                                       changes.Pass(),
                                       true /* is_delta_update */);
diff --git a/chrome/browser/chromeos/drive/file_task_executor.cc b/chrome/browser/chromeos/drive/file_task_executor.cc
index b91fc3a..eb799a2 100644
--- a/chrome/browser/chromeos/drive/file_task_executor.cc
+++ b/chrome/browser/chromeos/drive/file_task_executor.cc
@@ -136,7 +136,7 @@
 void FileTaskExecutor::OnAppAuthorized(const std::string& resource_id,
                                        google_apis::DriveApiErrorCode error,
                                        const GURL& open_link) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (error != google_apis::HTTP_SUCCESS || open_link.is_empty()) {
     Done(false);
@@ -153,7 +153,7 @@
 }
 
 void FileTaskExecutor::Done(bool success) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!done_.is_null())
     done_.Run(success
                   ? extensions::api::file_manager_private::TASK_RESULT_OPENED
diff --git a/chrome/browser/chromeos/extensions/wallpaper_function_base.cc b/chrome/browser/chromeos/extensions/wallpaper_function_base.cc
index 3331b7b..235f7fb 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_function_base.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_function_base.cc
@@ -45,9 +45,7 @@
     : public ImageDecoder::ImageRequest {
  public:
   explicit UnsafeWallpaperDecoder(scoped_refptr<WallpaperFunctionBase> function)
-      : ImageRequest(
-            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
-        function_(function) {}
+      : function_(function) {}
 
   void Start(const std::vector<char>& image_data) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index cef9f59..8c9d28a 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -1040,14 +1040,10 @@
                       TestParameter(NOT_IN_GUEST_MODE, "traverseDrive")));
 
 // Slow tests are disabled on debug build. http://crbug.com/327719
-// Disabled under MSAN as well. http://crbug.com/468980.
-#if !defined(NDEBUG) || defined(MEMORY_SANITIZER)
-#define MAYBE_SuggestAppDialog DISABLED_SuggestAppDialog
-#else
-#define MAYBE_SuggestAppDialog SuggestAppDialog
-#endif
+// Disabled under MSAN, ASAN, and LSAN as well. http://crbug.com/479757.
+// Flakes often: http://crbug.com/479757
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    MAYBE_SuggestAppDialog,
+    DISABLED_SuggestAppDialog,
     FileManagerBrowserTest,
     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "suggestAppDialog")));
 
@@ -1153,8 +1149,9 @@
                                     "tabindexFocusDownloads"),
                       TestParameter(IN_GUEST_MODE, "tabindexFocusDownloads")));
 
+// http://crbug.com/469061
 INSTANTIATE_TEST_CASE_P(
-    TabindexFocusDirectorySelected,
+    DISABLED_TabindexFocusDirectorySelected,
     FileManagerBrowserTest,
     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
                                     "tabindexFocusDirectorySelected")));
diff --git a/chrome/browser/chromeos/first_run/drive_first_run_controller.cc b/chrome/browser/chromeos/first_run/drive_first_run_controller.cc
index 63aedbb8..89ddecc 100644
--- a/chrome/browser/chromeos/first_run/drive_first_run_controller.cc
+++ b/chrome/browser/chromeos/first_run/drive_first_run_controller.cc
@@ -437,7 +437,7 @@
 }
 
 void DriveFirstRunController::OnOfflineInit(bool success, UMAOutcome outcome) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (success)
     ShowNotification();
   UMA_HISTOGRAM_ENUMERATION("DriveOffline.CrosAutoEnableOutcome",
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index 4fcbd03d..6d5ad0ca 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -596,6 +596,10 @@
   observer_->OnReset(active_component_id_);
 }
 
+bool InputMethodEngine::IsInterestedInKeyEvent() const {
+  return observer_->IsInterestedInKeyEvent();
+}
+
 void InputMethodEngine::ProcessKeyEvent(
     const ui::KeyEvent& key_event,
     const KeyEventDoneCallback& callback) {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h
index 36fc38d..d475a439 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -93,6 +93,8 @@
 
   int GetCotextIdForTesting() { return context_id_; }
 
+  bool IsInterestedInKeyEvent() const override;
+
  private:
   // Converts MenuItem to InputMethodMenuItem.
   void MenuItemToProperty(const MenuItem& item,
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 80f73a2..b183a3d4 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_interface.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine_interface.h
@@ -150,6 +150,9 @@
     // Called when an InputContext's properties change while it is focused.
     virtual void OnInputContextUpdate(const InputContext& context) = 0;
 
+    // Returns whether the observer is interested in key events.
+    virtual bool IsInterestedInKeyEvent() const = 0;
+
     // Called when the user pressed a key with a text field focused.
     virtual void OnKeyEvent(const std::string& engine_id,
                             const KeyboardEvent& event,
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 d38f27f..b31c17f 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -79,6 +79,7 @@
     calls_bitmap_ |= ONFOCUS;
   }
   void OnBlur(int context_id) override { calls_bitmap_ |= ONBLUR; }
+  bool IsInterestedInKeyEvent() const override { return true; }
   void OnKeyEvent(const std::string& engine_id,
                   const InputMethodEngineInterface::KeyboardEvent& event,
                   input_method::KeyEventHandle* key_data) override {}
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_engine.cc b/chrome/browser/chromeos/input_method/mock_input_method_engine.cc
index 2686cfc..0094309 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/mock_input_method_engine.cc
@@ -116,6 +116,10 @@
 void MockInputMethodEngine::Reset() {
 }
 
+bool MockInputMethodEngine::IsInterestedInKeyEvent() const {
+  return true;
+}
+
 void MockInputMethodEngine::ProcessKeyEvent(
     const ui::KeyEvent& key_event,
     const KeyEventDoneCallback& callback) {
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_engine.h b/chrome/browser/chromeos/input_method/mock_input_method_engine.h
index e722811..3a605750 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/mock_input_method_engine.h
@@ -74,6 +74,7 @@
   void Disable() override;
   void PropertyActivate(const std::string& property_name) override;
   void Reset() override;
+  bool IsInterestedInKeyEvent() const override;
   void ProcessKeyEvent(const ui::KeyEvent& key_event,
                        const KeyEventDoneCallback& callback) override;
   void CandidateClicked(uint32 index) override;
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
index c3dcd6e..2607ace 100644
--- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
+++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -434,15 +434,9 @@
   // and succeeded but we are in safe mode and the current user is not owner.
   state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
   SetOwnerState(false, false);
-  // Remove the real DeviceSettingsProvider and replace it with a stub.
-  CrosSettingsProvider* device_settings_provider =
-      CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo);
-  EXPECT_TRUE(device_settings_provider != NULL);
-  EXPECT_TRUE(
-      CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider));
-  StubCrosSettingsProvider stub_settings_provider;
-  CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider);
-  CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true);
+  ScopedCrosSettingsTestHelper settings_helper(false);
+  settings_helper.ReplaceProvider(kPolicyMissingMitigationMode);
+  settings_helper.SetBoolean(kPolicyMissingMitigationMode, true);
 
   // Initialize login state for this test to verify the login state is changed
   // to SAFE_MODE.
@@ -468,9 +462,6 @@
   // Unset global objects used by this test.
   fake_cryptohome_client_->set_unmount_result(true);
   LoginState::Shutdown();
-  EXPECT_TRUE(
-      CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider));
-  CrosSettings::Get()->AddSettingsProvider(device_settings_provider);
 }
 
 // Test the case that login switches to SafeMode and the Owner logs in, which
@@ -493,15 +484,9 @@
   // and succeeded but we are in safe mode and the current user is not owner.
   state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
   SetOwnerState(false, false);
-  // Remove the real DeviceSettingsProvider and replace it with a stub.
-  CrosSettingsProvider* device_settings_provider =
-      CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo);
-  EXPECT_TRUE(device_settings_provider != NULL);
-  EXPECT_TRUE(
-      CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider));
-  StubCrosSettingsProvider stub_settings_provider;
-  CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider);
-  CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true);
+  ScopedCrosSettingsTestHelper settings_helper(false);
+  settings_helper.ReplaceProvider(kPolicyMissingMitigationMode);
+  settings_helper.SetBoolean(kPolicyMissingMitigationMode, true);
 
   // Initialize login state for this test to verify the login state is changed
   // to SAFE_MODE.
@@ -526,9 +511,6 @@
   // Unset global objects used by this test.
   fake_cryptohome_client_->set_unmount_result(true);
   LoginState::Shutdown();
-  EXPECT_TRUE(
-      CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider));
-  CrosSettings::Get()->AddSettingsProvider(device_settings_provider);
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveFailedMount) {
diff --git a/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc b/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc
index e41275f..e87829c 100644
--- a/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc
@@ -57,8 +57,13 @@
 
 }  // namespace
 
-class BootstrapTest : public OobeBaseTest {
+// Boolean parameter is used to run this test for webview (true) and for
+// iframe (false) GAIA sign in.
+class BootstrapTest : public OobeBaseTest,
+                      public testing::WithParamInterface<bool> {
  public:
+  BootstrapTest() { set_use_webview(GetParam()); }
+
   void SetUpCommandLine(base::CommandLine* command_line) override {
     OobeBaseTest::SetUpCommandLine(command_line);
 
@@ -129,7 +134,7 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(BootstrapTest, Basic) {
+IN_PROC_BROWSER_TEST_P(BootstrapTest, Basic) {
   ScopedCompleteCallbackForTesting scoped_bootstrap_initialized(base::Bind(
       &BootstrapTest::OnBootstrapInitialized, base::Unretained(this)));
 
@@ -142,7 +147,7 @@
       content::NotificationService::AllSources()).Wait();
 }
 
-IN_PROC_BROWSER_TEST_F(BootstrapTest, PRE_CleanUpFailedUser) {
+IN_PROC_BROWSER_TEST_P(BootstrapTest, PRE_CleanUpFailedUser) {
   ScopedCompleteCallbackForTesting scoped_bootstrap_initialized(base::Bind(
       &BootstrapTest::OnBootstrapInitialized, base::Unretained(this)));
 
@@ -154,8 +159,13 @@
   content::RunMessageLoop();
 }
 
-IN_PROC_BROWSER_TEST_F(BootstrapTest, CleanUpFailedUser) {
+IN_PROC_BROWSER_TEST_P(BootstrapTest, CleanUpFailedUser) {
   EXPECT_FALSE(user_manager::UserManager::Get()->IsKnownUser(kFakeUser));
 }
 
+// TODO(nkostylev): Fix this test for webview. http://crbug.com/477402
+INSTANTIATE_TEST_CASE_P(BootstrapTestSuite,
+                        BootstrapTest,
+                        testing::Values(false));
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc
index a33cc520..c1ba482f 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc
@@ -59,7 +59,9 @@
     return;
   }
 
-  if (tpm_key_manager->PrepareTpmKey(false /* check_private_key */,
+  // Private TPM key is needed only when adding new keys.
+  if (remote_devices.empty() ||
+      tpm_key_manager->PrepareTpmKey(false /* check_private_key */,
                                      do_refresh_keys)) {
     do_refresh_keys.Run();
   } else {
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
index 07039aed..8e6c4f4 100644
--- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
@@ -141,14 +141,7 @@
   }
 }
 
-void EnrollmentScreen::ConfigureHost(bool accepted_eula,
-                                     const std::string& lang,
-                                     const std::string& timezone,
-                                     bool send_reports,
-                                     const std::string& keyboard_layout) {
-}
-
-void EnrollmentScreen::EnrollHost(const std::string& auth_token) {
+void EnrollmentScreen::EnrollHostRequested(const std::string& auth_token) {
   actor_->Show();
   actor_->ShowEnrollmentSpinnerScreen();
   CreateEnrollmentHelper();
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.h b/chrome/browser/chromeos/login/enrollment/enrollment_screen.h
index 664cc63..b932144 100644
--- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.h
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.h
@@ -68,12 +68,7 @@
 
   // pairing_chromeos::HostPairingController::Observer:
   void PairingStageChanged(Stage new_stage) override;
-  void ConfigureHost(bool accepted_eula,
-                     const std::string& lang,
-                     const std::string& timezone,
-                     bool send_reports,
-                     const std::string& keyboard_layout) override;
-  void EnrollHost(const std::string& auth_token) override;
+  void EnrollHostRequested(const std::string& auth_token) override;
 
   // EnrollmentScreenActor::Controller implementation:
   void OnLoginDone(const std::string& user,
diff --git a/chrome/browser/chromeos/login/helper.cc b/chrome/browser/chromeos/login/helper.cc
index decb068..a0177c5d 100644
--- a/chrome/browser/chromeos/login/helper.cc
+++ b/chrome/browser/chromeos/login/helper.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/json/json_reader.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
@@ -13,6 +14,7 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/chromeos_switches.h"
+#include "chromeos/network/managed_network_configuration_handler.h"
 #include "chromeos/network/network_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -131,18 +133,50 @@
   return base::string16();
 }
 
+void NetworkStateHelper::CreateNetworkFromOnc(
+    const std::string& onc_spec) const {
+  std::string error;
+  scoped_ptr<base::Value> root(base::JSONReader::ReadAndReturnError(
+      onc_spec, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error));
+
+  base::DictionaryValue* toplevel_onc = nullptr;
+  if (!root || !root->GetAsDictionary(&toplevel_onc)) {
+    LOG(ERROR) << "Invalid JSON Dictionary: " << error;
+    return;
+  }
+
+  NetworkHandler::Get()->managed_network_configuration_handler()->
+      CreateConfiguration(
+          "", *toplevel_onc,
+          base::Bind(&NetworkStateHelper::OnCreateConfiguration,
+                     base::Unretained(this)),
+          base::Bind(&NetworkStateHelper::OnCreateConfigurationFailed,
+                     base::Unretained(this)));
+}
+
+void NetworkStateHelper::OnCreateConfiguration(
+    const std::string& service_path) const {
+  // Do Nothing.
+}
+
+void NetworkStateHelper::OnCreateConfigurationFailed(
+    const std::string& error_name,
+    scoped_ptr<base::DictionaryValue> error_data) const {
+  LOG(ERROR) << "Failed to create network configuration: " << error_name;
+}
+
 bool NetworkStateHelper::IsConnected() const {
   chromeos::NetworkStateHandler* nsh =
       chromeos::NetworkHandler::Get()->network_state_handler();
   return nsh->ConnectedNetworkByType(chromeos::NetworkTypePattern::Default()) !=
-         NULL;
+         nullptr;
 }
 
 bool NetworkStateHelper::IsConnecting() const {
   chromeos::NetworkStateHandler* nsh =
       chromeos::NetworkHandler::Get()->network_state_handler();
   return nsh->ConnectingNetworkByType(
-      chromeos::NetworkTypePattern::Default()) != NULL;
+      chromeos::NetworkTypePattern::Default()) != nullptr;
 }
 
 content::StoragePartition* GetSigninPartition() {
diff --git a/chrome/browser/chromeos/login/helper.h b/chrome/browser/chromeos/login/helper.h
index 2809d66..c02cd5890 100644
--- a/chrome/browser/chromeos/login/helper.h
+++ b/chrome/browser/chromeos/login/helper.h
@@ -64,6 +64,9 @@
   // Ethernet > WiFi > Cellular. Same for connecting network.
   virtual base::string16 GetCurrentNetworkName() const;
 
+  // Add a network configuration.
+  virtual void CreateNetworkFromOnc(const std::string& onc_spec) const;
+
   // Returns true if the default network is in connected state.
   virtual bool IsConnected() const;
 
@@ -71,6 +74,11 @@
   virtual bool IsConnecting() const;
 
  private:
+  void OnCreateConfiguration(const std::string& service_path) const;
+  void OnCreateConfigurationFailed(
+      const std::string& error_name,
+      scoped_ptr<base::DictionaryValue> error_data) const;
+
   DISALLOW_COPY_AND_ASSIGN(NetworkStateHelper);
 };
 
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index b4f1aa887..ad6d36b 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.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 <vector>
+
 #include "ash/desktop_background/desktop_background_controller.h"
 #include "ash/desktop_background/desktop_background_controller_observer.h"
 #include "ash/shell.h"
@@ -14,11 +16,9 @@
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
 #include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/synchronization/lock.h"
-#include "base/thread_task_runner_handle.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/fake_cws.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
@@ -35,13 +35,13 @@
 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h"
+#include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
-#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -410,74 +410,18 @@
   DISALLOW_COPY_AND_ASSIGN(AppDataLoadWaiter);
 };
 
-class CrosSettingsPermanentlyUntrustedMaker :
-    public DeviceSettingsService::Observer {
- public:
-  CrosSettingsPermanentlyUntrustedMaker();
-
-  // DeviceSettingsService::Observer:
-  void OwnershipStatusChanged() override;
-  void DeviceSettingsUpdated() override;
-  void OnDeviceSettingsServiceShutdown() override;
-
- private:
-  bool untrusted_check_running_;
-  base::RunLoop run_loop_;
-
-  void CheckIfUntrusted();
-
-  DISALLOW_COPY_AND_ASSIGN(CrosSettingsPermanentlyUntrustedMaker);
-};
-
-CrosSettingsPermanentlyUntrustedMaker::CrosSettingsPermanentlyUntrustedMaker()
-    : untrusted_check_running_(false) {
-  DeviceSettingsService::Get()->AddObserver(this);
-
-  policy::DevicePolicyCrosTestHelper().InstallOwnerKey();
-  DeviceSettingsService::Get()->OwnerKeySet(true);
-
-  run_loop_.Run();
-}
-
-void CrosSettingsPermanentlyUntrustedMaker::OwnershipStatusChanged() {
-  if (untrusted_check_running_)
-    return;
-
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&CrosSettingsPermanentlyUntrustedMaker::CheckIfUntrusted,
-                 base::Unretained(this)));
-}
-
-void CrosSettingsPermanentlyUntrustedMaker::DeviceSettingsUpdated() {
-}
-
-void CrosSettingsPermanentlyUntrustedMaker::OnDeviceSettingsServiceShutdown() {
-}
-
-void CrosSettingsPermanentlyUntrustedMaker::CheckIfUntrusted() {
-  untrusted_check_running_ = true;
-  const CrosSettingsProvider::TrustedStatus trusted_status =
-      CrosSettings::Get()->PrepareTrustedValues(
-          base::Bind(&CrosSettingsPermanentlyUntrustedMaker::CheckIfUntrusted,
-                     base::Unretained(this)));
-  if (trusted_status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
-    return;
-  untrusted_check_running_ = false;
-
-  if (trusted_status == CrosSettingsProvider::TRUSTED)
-    return;
-
-  DeviceSettingsService::Get()->RemoveObserver(this);
-  run_loop_.Quit();
-}
-
 }  // namespace
 
-class KioskTest : public OobeBaseTest {
+// Boolean parameter is used to run this test for webview (true) and for
+// iframe (false) GAIA sign in.
+class KioskTest : public OobeBaseTest,
+                  public testing::WithParamInterface<bool> {
  public:
-  KioskTest() : use_consumer_kiosk_mode_(true),
-                fake_cws_(new FakeCWS) {
+  KioskTest()
+      : settings_helper_(false),
+        use_consumer_kiosk_mode_(true),
+        fake_cws_(new FakeCWS) {
+    set_use_webview(GetParam());
     set_exit_when_last_browser_closes(false);
   }
 
@@ -507,9 +451,13 @@
     // Needed to avoid showing Gaia screen instead of owner signin for
     // consumer network down test cases.
     StartupUtils::MarkDeviceRegistered(base::Closure());
+    settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts);
+    owner_settings_service_ = settings_helper_.CreateOwnerSettingsService(
+        ProfileManager::GetPrimaryUserProfile());
   }
 
   void TearDownOnMainThread() override {
+    settings_helper_.RestoreProvider();
     AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
     AppLaunchSigninScreen::SetUserManagerForTesting(NULL);
 
@@ -537,8 +485,9 @@
     SetupTestAppUpdateCheck();
 
     // Remove then add to ensure NOTIFICATION_KIOSK_APPS_LOADED fires.
-    KioskAppManager::Get()->RemoveApp(test_app_id_);
-    KioskAppManager::Get()->AddApp(test_app_id_);
+    KioskAppManager::Get()->RemoveApp(test_app_id_,
+                                      owner_settings_service_.get());
+    KioskAppManager::Get()->AddApp(test_app_id_, owner_settings_service_.get());
   }
 
   void FireKioskAppSettingsChanged() {
@@ -555,8 +504,9 @@
   void ReloadAutolaunchKioskApps() {
     SetupTestAppUpdateCheck();
 
-    KioskAppManager::Get()->AddApp(test_app_id_);
-    KioskAppManager::Get()->SetAutoLaunchApp(test_app_id_);
+    KioskAppManager::Get()->AddApp(test_app_id_, owner_settings_service_.get());
+    KioskAppManager::Get()->SetAutoLaunchApp(test_app_id_,
+                                             owner_settings_service_.get());
   }
 
   void StartUIForAppLaunch() {
@@ -800,6 +750,9 @@
     use_consumer_kiosk_mode_ = use;
   }
 
+  ScopedCrosSettingsTestHelper settings_helper_;
+  scoped_ptr<FakeOwnerSettingsService> owner_settings_service_;
+
  private:
   bool use_consumer_kiosk_mode_;
   std::string test_app_id_;
@@ -811,7 +764,7 @@
   DISALLOW_COPY_AND_ASSIGN(KioskTest);
 };
 
-IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) {
+IN_PROC_BROWSER_TEST_P(KioskTest, InstallAndLaunchApp) {
   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
   WaitForAppLaunchSuccess();
   KioskAppManager::App app;
@@ -819,7 +772,7 @@
   EXPECT_FALSE(app.was_auto_launched_with_zero_delay);
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, ZoomSupport) {
+IN_PROC_BROWSER_TEST_P(KioskTest, ZoomSupport) {
   ExtensionTestMessageListener
       app_window_loaded_listener("appWindowLoaded", false);
   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
@@ -886,7 +839,7 @@
   content::RunAllPendingInMessageLoop();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, NotSignedInWithGAIAAccount) {
+IN_PROC_BROWSER_TEST_P(KioskTest, NotSignedInWithGAIAAccount) {
   // Tests that the kiosk session is not considered to be logged in with a GAIA
   // account.
   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
@@ -898,18 +851,18 @@
       SigninManagerFactory::GetForProfile(app_profile)->IsAuthenticated());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, PRE_LaunchAppNetworkDown) {
+IN_PROC_BROWSER_TEST_P(KioskTest, PRE_LaunchAppNetworkDown) {
   // Tests the network down case for the initial app download and launch.
   RunAppLaunchNetworkDownTest();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDown) {
+IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppNetworkDown) {
   // Tests the network down case for launching an existing app that is
   // installed in PRE_LaunchAppNetworkDown.
   RunAppLaunchNetworkDownTest();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppWithNetworkConfigAccelerator) {
+IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppWithNetworkConfigAccelerator) {
   ScopedCanConfigureNetwork can_configure_network(true, false);
 
   // Block app loading until the network screen is shown.
@@ -946,7 +899,7 @@
   WaitForAppLaunchSuccess();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDownConfigureNotAllowed) {
+IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppNetworkDownConfigureNotAllowed) {
   // Mock network could not be configured.
   ScopedCanConfigureNetwork can_configure_network(false, true);
 
@@ -964,7 +917,7 @@
   WaitForAppLaunchSuccess();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkPortal) {
+IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppNetworkPortal) {
   // Mock network could be configured without the owner password.
   ScopedCanConfigureNetwork can_configure_network(true, false);
 
@@ -983,14 +936,14 @@
   WaitForAppLaunchSuccess();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppUserCancel) {
+IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppUserCancel) {
   // Make fake_cws_ return empty update response.
   set_test_app_version("");
   StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure());
   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
   splash_waiter.Wait();
 
-  CrosSettings::Get()->SetBoolean(
+  settings_helper_.SetBoolean(
       kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, true);
   content::WindowedNotificationObserver signal(
       chrome::NOTIFICATION_APP_TERMINATING,
@@ -1002,7 +955,7 @@
             chromeos::KioskAppLaunchError::Get());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, LaunchInDiagnosticMode) {
+IN_PROC_BROWSER_TEST_P(KioskTest, LaunchInDiagnosticMode) {
   PrepareAppLaunch();
   SimulateNetworkOnline();
 
@@ -1027,7 +980,7 @@
   WaitForAppLaunchSuccess();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) {
+IN_PROC_BROWSER_TEST_P(KioskTest, AutolaunchWarningCancel) {
   EnableConsumerKioskMode();
 
   chromeos::WizardController::SkipPostLoginScreensForTesting();
@@ -1059,7 +1012,7 @@
   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningConfirm) {
+IN_PROC_BROWSER_TEST_P(KioskTest, AutolaunchWarningConfirm) {
   EnableConsumerKioskMode();
 
   chromeos::WizardController::SkipPostLoginScreensForTesting();
@@ -1098,7 +1051,7 @@
   EXPECT_TRUE(app.was_auto_launched_with_zero_delay);
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableCancel) {
+IN_PROC_BROWSER_TEST_P(KioskTest, KioskEnableCancel) {
   chromeos::WizardController::SkipPostLoginScreensForTesting();
   chromeos::WizardController* wizard_controller =
       chromeos::WizardController::default_controller();
@@ -1132,7 +1085,7 @@
             GetConsumerKioskModeStatus());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableConfirmed) {
+IN_PROC_BROWSER_TEST_P(KioskTest, KioskEnableConfirmed) {
   // Start UI, find menu entry for this app and launch it.
   chromeos::WizardController::SkipPostLoginScreensForTesting();
   chromeos::WizardController* wizard_controller =
@@ -1165,7 +1118,7 @@
             GetConsumerKioskModeStatus());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAfter2ndSigninScreen) {
+IN_PROC_BROWSER_TEST_P(KioskTest, KioskEnableAfter2ndSigninScreen) {
   chromeos::WizardController::SkipPostLoginScreensForTesting();
   chromeos::WizardController* wizard_controller =
       chromeos::WizardController::default_controller();
@@ -1209,12 +1162,13 @@
       content::NotificationService::AllSources()).Wait();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskTest, DoNotLaunchWhenUntrusted) {
+IN_PROC_BROWSER_TEST_P(KioskTest, DoNotLaunchWhenUntrusted) {
   PrepareAppLaunch();
   SimulateNetworkOnline();
 
   // Make cros settings untrusted.
-  CrosSettingsPermanentlyUntrustedMaker();
+  settings_helper_.SetTrustedStatus(
+      CrosSettingsProvider::PERMANENTLY_UNTRUSTED);
 
   // Check that the attempt to start a kiosk app fails with an error.
   LaunchApp(test_app_id(), false);
@@ -1234,7 +1188,7 @@
 
 // Verifies that a consumer device does not auto-launch kiosk mode when cros
 // settings are untrusted.
-IN_PROC_BROWSER_TEST_F(KioskTest, NoConsumerAutoLaunchWhenUntrusted) {
+IN_PROC_BROWSER_TEST_P(KioskTest, NoConsumerAutoLaunchWhenUntrusted) {
   EnableConsumerKioskMode();
 
   // Wait for and confirm the auto-launch warning.
@@ -1253,14 +1207,15 @@
       base::FundamentalValue(true));
 
   // Make cros settings untrusted.
-  CrosSettingsPermanentlyUntrustedMaker();
+  settings_helper_.SetTrustedStatus(
+      CrosSettingsProvider::PERMANENTLY_UNTRUSTED);
 
   // Check that the attempt to auto-launch a kiosk app fails with an error.
   OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait();
 }
 
 // Verifies available volumes for kiosk apps in kiosk session.
-IN_PROC_BROWSER_TEST_F(KioskTest, GetVolumeList) {
+IN_PROC_BROWSER_TEST_P(KioskTest, GetVolumeList) {
   set_test_app_id(kTestGetVolumeListKioskApp);
   set_test_app_version("0.1");
   set_test_crx_file(test_app_id() + ".crx");
@@ -1272,12 +1227,13 @@
 
 // Verifies that an enterprise device does not auto-launch kiosk mode when cros
 // settings are untrusted.
-IN_PROC_BROWSER_TEST_F(KioskTest, NoEnterpriseAutoLaunchWhenUntrusted) {
+IN_PROC_BROWSER_TEST_P(KioskTest, NoEnterpriseAutoLaunchWhenUntrusted) {
   PrepareAppLaunch();
   SimulateNetworkOnline();
 
   // Make cros settings untrusted.
-  CrosSettingsPermanentlyUntrustedMaker();
+  settings_helper_.SetTrustedStatus(
+      CrosSettingsProvider::PERMANENTLY_UNTRUSTED);
 
   // Trigger the code that handles auto-launch on enterprise devices. This would
   // normally be called from ShowLoginWizard(), which runs so early that it is
@@ -1309,7 +1265,19 @@
     KioskTest::TearDown();
   }
 
-  void SetUpOnMainThread() override { KioskTest::SetUpOnMainThread(); }
+  void SetUpOnMainThread() override {
+    // For update tests, we cache the app in the PRE part, and then we load it
+    // in the test, so we need to both store the apps list on teardown (so that
+    // the app manager would accept existing files in its extension cache on the
+    // next startup) and copy the list to our stub settings provider as well.
+    settings_helper_.CopyStoredValue(kAccountsPrefDeviceLocalAccounts);
+    KioskTest::SetUpOnMainThread();
+  }
+
+  void TearDownOnMainThread() override {
+    settings_helper_.StoreCachedDeviceSetting(kAccountsPrefDeviceLocalAccounts);
+    KioskTest::TearDownOnMainThread();
+  }
 
   void PreCacheApp(const std::string& app_id,
                    const std::string& version,
@@ -1437,13 +1405,13 @@
   DISALLOW_COPY_AND_ASSIGN(KioskUpdateTest);
 };
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchOfflineEnabledAppNoNetwork) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PRE_LaunchOfflineEnabledAppNoNetwork) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "1.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchOfflineEnabledAppNoNetwork) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, LaunchOfflineEnabledAppNoNetwork) {
   set_test_app_id(kTestOfflineEnabledKioskApp);
   StartUIForAppLaunch();
   SimulateNetworkOffline();
@@ -1453,14 +1421,14 @@
   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest,
                        PRE_LaunchCachedOfflineEnabledAppNoNetwork) {
   PreCacheApp(kTestOfflineEnabledKioskApp,
               "1.0.0",
               std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest,
                        LaunchCachedOfflineEnabledAppNoNetwork) {
   set_test_app_id(kTestOfflineEnabledKioskApp);
   EXPECT_TRUE(
@@ -1475,7 +1443,7 @@
 
 // Network offline, app v1.0 has run before, has cached v2.0 crx and v2.0 should
 // be installed and launched during next launch.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest,
                        PRE_LaunchCachedNewVersionOfflineEnabledAppNoNetwork) {
   // Install and launch v1 app.
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
@@ -1488,7 +1456,7 @@
   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest,
                        LaunchCachedNewVersionOfflineEnabledAppNoNetwork) {
   set_test_app_id(kTestOfflineEnabledKioskApp);
   EXPECT_TRUE(KioskAppManager::Get()->HasCachedCrx(test_app_id()));
@@ -1502,13 +1470,13 @@
   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchOfflineEnabledAppNoUpdate) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PRE_LaunchOfflineEnabledAppNoUpdate) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "1.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchOfflineEnabledAppNoUpdate) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, LaunchOfflineEnabledAppNoUpdate) {
   set_test_app_id(kTestOfflineEnabledKioskApp);
   fake_cws()->SetNoUpdate(test_app_id());
 
@@ -1520,13 +1488,13 @@
   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchOfflineEnabledAppHasUpdate) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PRE_LaunchOfflineEnabledAppHasUpdate) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "1.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchOfflineEnabledAppHasUpdate) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, LaunchOfflineEnabledAppHasUpdate) {
   set_test_app_id(kTestOfflineEnabledKioskApp);
   fake_cws()->SetUpdateCrx(
       test_app_id(), "ajoggoflpgplnnjkjamcmbepjdjdnpdp.crx", "2.0.0");
@@ -1541,7 +1509,7 @@
 
 // Pre-cache v1 kiosk app, then launch the app without network,
 // plug in usb stick with a v2 app for offline updating.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_UsbStickUpdateAppNoNetwork) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PRE_UsbStickUpdateAppNoNetwork) {
   PreCacheApp(kTestOfflineEnabledKioskApp,
               "1.0.0",
               std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
@@ -1572,7 +1540,7 @@
 }
 
 // Restart the device, verify the app has been updated to v2.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppNoNetwork) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, UsbStickUpdateAppNoNetwork) {
   // Verify the kiosk app has been updated to v2.
   set_test_app_id(kTestOfflineEnabledKioskApp);
   StartUIForAppLaunch();
@@ -1583,7 +1551,7 @@
 }
 
 // Usb stick is plugged in without a manifest file on it.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppNoManifest) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, UsbStickUpdateAppNoManifest) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "1.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
@@ -1605,7 +1573,7 @@
 }
 
 // Usb stick is plugged in with a bad manifest file on it.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppBadManifest) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, UsbStickUpdateAppBadManifest) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "1.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
@@ -1628,7 +1596,7 @@
 
 // Usb stick is plugged in with a lower version of crx file specified in
 // manifest.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppLowerAppVersion) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, UsbStickUpdateAppLowerAppVersion) {
   // Precache v2 version of app.
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "2.0.0",
@@ -1652,7 +1620,7 @@
 
 // Usb stick is plugged in with a v1 crx file, although the manifest says
 // this is a v3 version.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppLowerCrxVersion) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, UsbStickUpdateAppLowerCrxVersion) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "2.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + ".crx");
@@ -1675,7 +1643,7 @@
 }
 
 // Usb stick is plugged in with a bad crx file.
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppBadCrx) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, UsbStickUpdateAppBadCrx) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "1.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
@@ -1697,13 +1665,13 @@
   EXPECT_EQ("1.0.0", cached_version);
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_PermissionChange) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PRE_PermissionChange) {
   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
                        "2.0.0",
                        std::string(kTestOfflineEnabledKioskApp) + ".crx");
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PermissionChange) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PermissionChange) {
   set_test_app_id(kTestOfflineEnabledKioskApp);
   set_test_app_version("2.0.0");
   set_test_crx_file(test_app_id() + "_v2_permission_change.crx");
@@ -1716,7 +1684,7 @@
   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_PreserveLocalData) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PRE_PreserveLocalData) {
   // Installs v1 app and writes some local data.
   set_test_app_id(kTestLocalFsKioskApp);
   set_test_app_version("1.0.0");
@@ -1729,7 +1697,7 @@
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PreserveLocalData) {
+IN_PROC_BROWSER_TEST_P(KioskUpdateTest, PreserveLocalData) {
   // Update existing v1 app installed in PRE_PreserveLocalData to v2
   // that reads and verifies the local data.
   set_test_app_id(kTestLocalFsKioskApp);
@@ -1751,8 +1719,9 @@
   }
 
   void SetUpInProcessBrowserTestFixture() override {
-    device_policy_test_helper_.MarkAsEnterpriseOwned();
-    device_policy_test_helper_.InstallOwnerKey();
+    policy::DevicePolicyCrosTestHelper::MarkAsEnterpriseOwnedBy(
+        kTestOwnerEmail);
+    settings_helper_.SetCurrentUserIsOwner(false);
 
     KioskTest::SetUpInProcessBrowserTestFixture();
   }
@@ -1795,47 +1764,27 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  static void StorePolicyCallback(const base::Closure& callback, bool result) {
-    ASSERT_TRUE(result);
-    callback.Run();
-  }
-
   void ConfigureKioskAppInPolicy(const std::string& account_id,
                                  const std::string& app_id,
                                  const std::string& update_url) {
-    em::DeviceLocalAccountsProto* accounts =
-        device_policy_test_helper_.device_policy()->payload()
-            .mutable_device_local_accounts();
-    em::DeviceLocalAccountInfoProto* account = accounts->add_account();
-    account->set_account_id(account_id);
-    account->set_type(
-        em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP);
-    account->mutable_kiosk_app()->set_app_id(app_id);
-    if (!update_url.empty())
-      account->mutable_kiosk_app()->set_update_url(update_url);
-    accounts->set_auto_login_id(account_id);
-    em::PolicyData& policy_data =
-        device_policy_test_helper_.device_policy()->policy_data();
-    policy_data.set_service_account_identity(kTestEnterpriseServiceAccountId);
-    device_policy_test_helper_.device_policy()->Build();
-
-    base::RunLoop run_loop;
-    DBusThreadManager::Get()->GetSessionManagerClient()->StoreDevicePolicy(
-        device_policy_test_helper_.device_policy()->GetBlob(),
-        base::Bind(&KioskEnterpriseTest::StorePolicyCallback,
-                   run_loop.QuitClosure()));
-    run_loop.Run();
-
-    DeviceSettingsService::Get()->Load();
+    settings_helper_.SetCurrentUserIsOwner(true);
+    std::vector<policy::DeviceLocalAccount> accounts;
+    accounts.push_back(
+        policy::DeviceLocalAccount(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
+                                   account_id, app_id, update_url));
+    policy::SetDeviceLocalAccounts(owner_settings_service_.get(), accounts);
+    settings_helper_.SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
+                               account_id);
+    settings_helper_.SetString(kServiceAccountIdentity,
+                               kTestEnterpriseServiceAccountId);
+    settings_helper_.SetCurrentUserIsOwner(false);
   }
 
-  policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(KioskEnterpriseTest);
 };
 
-IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest, EnterpriseKioskApp) {
+IN_PROC_BROWSER_TEST_P(KioskEnterpriseTest, EnterpriseKioskApp) {
   // Prepare Fake CWS to serve app crx.
   set_test_app_id(kTestEnterpriseKioskApp);
   set_test_app_version("1.0.0");
@@ -1890,7 +1839,7 @@
   content::RunAllPendingInMessageLoop();
 }
 
-IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest, PrivateStore) {
+IN_PROC_BROWSER_TEST_P(KioskEnterpriseTest, PrivateStore) {
   set_test_app_id(kTestEnterpriseKioskApp);
 
   const char kPrivateStoreUpdate[] = "/private_store_update";
@@ -1975,7 +1924,7 @@
   DISALLOW_COPY_AND_ASSIGN(KioskHiddenWebUITest);
 };
 
-IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) {
+IN_PROC_BROWSER_TEST_P(KioskHiddenWebUITest, AutolaunchWarning) {
   // Add a device owner.
   FakeChromeUserManager* user_manager = new FakeChromeUserManager();
   user_manager->AddUser(kTestOwnerEmail);
@@ -2006,4 +1955,13 @@
   EXPECT_TRUE(wallpaper_loaded());
 }
 
+INSTANTIATE_TEST_CASE_P(KioskSuite, KioskTest, testing::Bool());
+INSTANTIATE_TEST_CASE_P(KioskUpdateSuite, KioskUpdateTest, testing::Bool());
+INSTANTIATE_TEST_CASE_P(KioskEnterpriseSuite,
+                        KioskEnterpriseTest,
+                        testing::Bool());
+INSTANTIATE_TEST_CASE_P(KioskHiddenWebUISuite,
+                        KioskHiddenWebUITest,
+                        testing::Bool());
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc
index 89cf712..c58af0c 100644
--- a/chrome/browser/chromeos/login/login_manager_test.cc
+++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -33,7 +33,7 @@
 namespace chromeos {
 
 LoginManagerTest::LoginManagerTest(bool should_launch_browser)
-    : use_webview_(false),
+    : use_webview_(true),
       should_launch_browser_(should_launch_browser),
       web_contents_(NULL) {
   set_exit_when_last_browser_closes(false);
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index 09eb71e..6025228 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
+#include "chrome/browser/chromeos/login/test/oobe_base_test.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/rlz/rlz.h"
@@ -42,39 +43,10 @@
 
 }  // namespace
 
-class LoginUtilsTest : public InProcessBrowserTest {
+class LoginUtilsTest : public OobeBaseTest,
+                       public testing::WithParamInterface<bool> {
  public:
-  LoginUtilsTest() {}
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    // Initialize the test server early, so that we can use its base url for
-    // the command line flags.
-    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-    // Use the login manager screens and the gaia auth extension.
-    command_line->AppendSwitch(switches::kLoginManager);
-    command_line->AppendSwitch(switches::kForceLoginManagerInTests);
-    command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
-    command_line->AppendSwitchASCII(::switches::kAuthExtensionPath,
-                                    "gaia_auth");
-
-    // Redirect requests to gaia and the policy server to the test server.
-    command_line->AppendSwitchASCII(::switches::kGaiaUrl,
-                                    embedded_test_server()->base_url().spec());
-    command_line->AppendSwitchASCII(::switches::kLsoUrl,
-                                    embedded_test_server()->base_url().spec());
-  }
-
-  void SetUpOnMainThread() override {
-    fake_gaia_.Initialize();
-    embedded_test_server()->RegisterRequestHandler(
-        base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
-  }
-
-  void TearDownOnMainThread() override {
-    RunUntilIdle();
-    EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
-  }
+  LoginUtilsTest() { set_use_webview(GetParam()); }
 
   void RunUntilIdle() {
     base::RunLoop().RunUntilIdle();
@@ -104,23 +76,12 @@
   }
 
  private:
-  FakeGaia fake_gaia_;
-
   DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest);
 };
 
 #if defined(ENABLE_RLZ)
-IN_PROC_BROWSER_TEST_F(LoginUtilsTest, RlzInitialized) {
-  // Skip to the signin screen.
-  WizardController::SkipPostLoginScreensForTesting();
-  WizardController* wizard_controller = WizardController::default_controller();
-  ASSERT_TRUE(wizard_controller);
-  wizard_controller->SkipToLoginForTesting(LoginScreenContext());
-
-  content::WindowedNotificationObserver(
-      chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
-      content::NotificationService::AllSources()).Wait();
-  RunUntilIdle();
+IN_PROC_BROWSER_TEST_P(LoginUtilsTest, RlzInitialized) {
+  WaitForSigninScreen();
 
   // No RLZ brand code set initially.
   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kRLZBrand));
@@ -154,6 +115,9 @@
     EXPECT_EQ(base::string16(), rlz_string);
   }
 }
+
+INSTANTIATE_TEST_CASE_P(LoginUtilsTestSuite, LoginUtilsTest, testing::Bool());
+
 #endif
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/proxy_auth_dialog_browsertest.cc b/chrome/browser/chromeos/login/proxy_auth_dialog_browsertest.cc
index 3eef72f..9fb5726 100644
--- a/chrome/browser/chromeos/login/proxy_auth_dialog_browsertest.cc
+++ b/chrome/browser/chromeos/login/proxy_auth_dialog_browsertest.cc
@@ -68,9 +68,7 @@
         proxy_server_(net::SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
                       net::SpawnedTestServer::kLocalhost,
                       base::FilePath()) {
-    // TODO(paulmeyer): Re-enable webview version of this test
-    // (uncomment this line) once http://crbug.com/452452 is fixed.
-    // set_use_webview(GetParam());
+    set_use_webview(GetParam());
   }
 
   ~ProxyAuthOnUserBoardScreenTest() override {}
@@ -128,8 +126,10 @@
   }
 }
 
+// TODO(paulmeyer): Re-enable webview version of this test
+// (once http://crbug.com/452452 is fixed.
 INSTANTIATE_TEST_CASE_P(ProxyAuthOnUserBoardScreenTestSuite,
                         ProxyAuthOnUserBoardScreenTest,
-                        testing::Bool());
+                        testing::Values(false));
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screen_manager.h b/chrome/browser/chromeos/login/screen_manager.h
index 7a18ba65..2473126 100644
--- a/chrome/browser/chromeos/login/screen_manager.h
+++ b/chrome/browser/chromeos/login/screen_manager.h
@@ -22,7 +22,7 @@
   virtual ~ScreenManager();
 
   // Getter for screen with lazy initialization.
-  BaseScreen* GetScreen(const std::string& screen_name);
+  virtual BaseScreen* GetScreen(const std::string& screen_name);
 
   // Factory for screen instances.
   virtual BaseScreen* CreateScreen(const std::string& screen_name) = 0;
diff --git a/chrome/browser/chromeos/login/screens/host_pairing_screen.cc b/chrome/browser/chromeos/login/screens/host_pairing_screen.cc
index a2921e2..fba3190 100644
--- a/chrome/browser/chromeos/login/screens/host_pairing_screen.cc
+++ b/chrome/browser/chromeos/login/screens/host_pairing_screen.cc
@@ -84,24 +84,30 @@
   CommitContextChanges();
 }
 
-void HostPairingScreen::ConfigureHost(bool accepted_eula,
-                                      const std::string& lang,
-                                      const std::string& timezone,
-                                      bool send_reports,
-                                      const std::string& keyboard_layout) {
+void HostPairingScreen::ConfigureHostRequested(
+    bool accepted_eula,
+    const std::string& lang,
+    const std::string& timezone,
+    bool send_reports,
+    const std::string& keyboard_layout) {
   VLOG(1) << "ConfigureHostMessage language=" << lang
           << ", timezone=" << timezone
           << ", keyboard_layout=" << keyboard_layout;
 
   remora_controller_->RemoveObserver(this);
   if (delegate_) {
-    delegate_->ConfigureHost(
+    delegate_->ConfigureHostRequested(
         accepted_eula, lang, timezone, send_reports, keyboard_layout);
   }
   Finish(WizardController::HOST_PAIRING_FINISHED);
 }
 
-void HostPairingScreen::EnrollHost(const std::string& auth_token) {
+void HostPairingScreen::AddNetworkRequested(const std::string& onc_spec) {
+  if (delegate_)
+    delegate_->AddNetworkRequested(onc_spec);
+}
+
+void HostPairingScreen::EnrollHostRequested(const std::string& auth_token) {
   NOTREACHED();
 }
 
diff --git a/chrome/browser/chromeos/login/screens/host_pairing_screen.h b/chrome/browser/chromeos/login/screens/host_pairing_screen.h
index 37c4598..73df4b8 100644
--- a/chrome/browser/chromeos/login/screens/host_pairing_screen.h
+++ b/chrome/browser/chromeos/login/screens/host_pairing_screen.h
@@ -21,11 +21,18 @@
   class Delegate {
    public:
     virtual ~Delegate() {}
-    virtual void ConfigureHost(bool accepted_eula,
-                               const std::string& lang,
-                               const std::string& timezone,
-                               bool send_reports,
-                               const std::string& keyboard_layout) = 0;
+
+    // Called when a configuration has been received, and should be applied to
+    // this device.
+    virtual void ConfigureHostRequested(bool accepted_eula,
+                                        const std::string& lang,
+                                        const std::string& timezone,
+                                        bool send_reports,
+                                        const std::string& keyboard_layout) = 0;
+
+    // Called when a network configuration has been received, and should be
+    // used on this device.
+    virtual void AddNetworkRequested(const std::string& onc_spec) = 0;
   };
 
   HostPairingScreen(BaseScreenDelegate* base_screen_delegate,
@@ -47,12 +54,13 @@
 
   // pairing_chromeos::HostPairingController::Observer:
   void PairingStageChanged(Stage new_stage) override;
-  void ConfigureHost(bool accepted_eula,
-                     const std::string& lang,
-                     const std::string& timezone,
-                     bool send_reports,
-                     const std::string& keyboard_layout) override;
-  void EnrollHost(const std::string& auth_token) override;
+  void ConfigureHostRequested(bool accepted_eula,
+                              const std::string& lang,
+                              const std::string& timezone,
+                              bool send_reports,
+                              const std::string& keyboard_layout) override;
+  void AddNetworkRequested(const std::string& onc_spec) override;
+  void EnrollHostRequested(const std::string& auth_token) override;
 
   // Overridden from ControllerPairingView::Delegate:
   void OnActorDestroyed(HostPairingScreenActor* actor) override;
diff --git a/chrome/browser/chromeos/login/screens/network_screen.cc b/chrome/browser/chromeos/login/screens/network_screen.cc
index f451b52..13c6afa 100644
--- a/chrome/browser/chromeos/login/screens/network_screen.cc
+++ b/chrome/browser/chromeos/login/screens/network_screen.cc
@@ -224,6 +224,10 @@
   return timezone_;
 }
 
+void NetworkScreen::CreateNetworkFromOnc(const std::string& onc_spec) {
+  network_state_helper_->CreateNetworkFromOnc(onc_spec);
+}
+
 void NetworkScreen::AddObserver(Observer* observer) {
   if (observer)
     observers_.AddObserver(observer);
@@ -370,7 +374,7 @@
     scoped_ptr<base::ListValue> new_language_list,
     std::string new_language_list_locale,
     std::string new_selected_language) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   language_list_.reset(new_language_list.release());
   language_list_locale_ = new_language_list_locale;
diff --git a/chrome/browser/chromeos/login/screens/network_screen.h b/chrome/browser/chromeos/login/screens/network_screen.h
index 5c8cc2d..9c1ae66f 100644
--- a/chrome/browser/chromeos/login/screens/network_screen.h
+++ b/chrome/browser/chromeos/login/screens/network_screen.h
@@ -88,6 +88,8 @@
   void SetTimezone(const std::string& timezone_id);
   std::string GetTimezone() const;
 
+  void CreateNetworkFromOnc(const std::string& onc_spec);
+
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.cc b/chrome/browser/chromeos/login/screens/user_image_screen.cc
index d62c9702..56063c9 100644
--- a/chrome/browser/chromeos/login/screens/user_image_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_image_screen.cc
@@ -66,8 +66,6 @@
 UserImageScreen::UserImageScreen(BaseScreenDelegate* base_screen_delegate,
                                  UserImageView* view)
     : UserImageModel(base_screen_delegate),
-      ImageRequest(
-          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
       view_(view),
       accept_photo_after_decoding_(false),
       selected_image_(user_manager::User::USER_IMAGE_INVALID),
diff --git a/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc b/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc
index df9427e..0f7c591 100644
--- a/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc
+++ b/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc
@@ -203,7 +203,7 @@
 }
 
 ScreenshotTester::PNGFile ScreenshotTester::TakeScreenshot() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   aura::Window* primary_window = ash::Shell::GetPrimaryRootWindow();
   gfx::Rect rect = primary_window->bounds();
   PNGFile screenshot = new base::RefCountedBytes;
diff --git a/chrome/browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc b/chrome/browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc
index afb3c6e..de641da 100644
--- a/chrome/browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc
+++ b/chrome/browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc
@@ -27,8 +27,7 @@
 void ScreenshotTestingMixin::SetUpCommandLine(base::CommandLine* command_line) {
   if (enable_test_screenshots_) {
     command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
-  } else {
-    command_line->AppendSwitch(switches::kUIDisableImplSidePainting);
+    command_line->AppendSwitch(switches::kUIEnableImplSidePainting);
   }
 }
 
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 01d04f1d..1fbb3d8 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -476,12 +476,12 @@
 }
 
 bool UserSessionManager::UserSessionsRestored() const {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   return user_sessions_restored_;
 }
 
 bool UserSessionManager::UserSessionsRestoreInProgress() const {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   return user_sessions_restore_in_progress_;
 }
 
@@ -673,13 +673,13 @@
 
 void UserSessionManager::AddSessionStateObserver(
     chromeos::UserSessionStateObserver* observer) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   session_state_observer_list_.AddObserver(observer);
 }
 
 void UserSessionManager::RemoveSessionStateObserver(
     chromeos::UserSessionStateObserver* observer) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   session_state_observer_list_.RemoveObserver(observer);
 }
 
@@ -788,15 +788,16 @@
   RestorePendingUserSessions();
 }
 
-void UserSessionManager::ChildAccountStatusReceivedCallback() {
-  StopChildStatusObserving();
+void UserSessionManager::ChildAccountStatusReceivedCallback(Profile* profile) {
+  StopChildStatusObserving(profile);
 }
 
-void UserSessionManager::StopChildStatusObserving() {
-  if (!waiting_for_child_account_status_) {
+void UserSessionManager::StopChildStatusObserving(Profile* profile) {
+  if (!waiting_for_child_account_status_ &&
+      !SessionStartupPref::TypeIsManaged(profile->GetPrefs())) {
     InitializeStartUrls();
-    waiting_for_child_account_status_ = false;
   }
+  waiting_for_child_account_status_ = false;
 }
 
 void UserSessionManager::CreateUserSession(const UserContext& user_context,
@@ -1149,13 +1150,12 @@
 bool UserSessionManager::InitializeUserSession(Profile* profile) {
   ChildAccountService* child_service =
       ChildAccountServiceFactory::GetForProfile(profile);
-  child_service->AddChildStatusReceivedCallback(base::Bind(
-      &UserSessionManager::ChildAccountStatusReceivedCallback,
-      weak_factory_.GetWeakPtr()));
+  child_service->AddChildStatusReceivedCallback(
+      base::Bind(&UserSessionManager::ChildAccountStatusReceivedCallback,
+                 weak_factory_.GetWeakPtr(), profile));
   base::MessageLoopProxy::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&UserSessionManager::StopChildStatusObserving,
-                 weak_factory_.GetWeakPtr()),
+      FROM_HERE, base::Bind(&UserSessionManager::StopChildStatusObserving,
+                            weak_factory_.GetWeakPtr(), profile),
       base::TimeDelta::FromMilliseconds(kFlagsFetchingLoginTimeoutMs));
 
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
@@ -1254,8 +1254,14 @@
 
   // Authentication request context may not be available if user was not
   // signing in with GAIA webview (i.e. webview instance hasn't been
-  // initialized at all). Use fallback request context.
-  if (!auth_request_context) {
+  // initialized at all). Use fallback request context if authenticator was
+  // provided.
+  // Authenticator instance may not be initialized for session
+  // restore case when Chrome is restarting after crash or to apply custom user
+  // flags. In that case auth_request_context will be nullptr which is accepted
+  // by RestoreSession() for session restore case.
+  if (!auth_request_context &&
+      (authenticator_.get() && authenticator_->authentication_context())) {
     auth_request_context =
         authenticator_->authentication_context()->GetRequestContext();
   }
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h
index 9be9b718..fc5f779 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.h
+++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -254,9 +254,9 @@
   // Used when restoring user sessions after crash.
   void OnProfilePrepared(Profile* profile, bool browser_launched) override;
 
-  void ChildAccountStatusReceivedCallback();
+  void ChildAccountStatusReceivedCallback(Profile* profile);
 
-  void StopChildStatusObserving();
+  void StopChildStatusObserving(Profile* profile);
 
   void CreateUserSession(const UserContext& user_context,
                          bool has_auth_cookies);
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
index 4197cc8..15b3473 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
@@ -90,6 +90,8 @@
   // RESTORE_FROM_AUTH_CODE, respectively
   // parameters |oauth2_refresh_token| or |auth_code| need to have non-empty
   // value.
+  // For |restore_strategy| with values RESTORE_FROM_COOKIE_JAR or
+  // RESTORE_FROM_AUTH_CODE |auth_request_context| must be initialized.
   void RestoreSession(
       net::URLRequestContextGetter* auth_request_context,
       SessionRestoreStrategy restore_strategy,
diff --git a/chrome/browser/chromeos/login/startup_utils.cc b/chrome/browser/chromeos/login/startup_utils.cc
index c136ea3..ec108c5c 100644
--- a/chrome/browser/chromeos/login/startup_utils.cc
+++ b/chrome/browser/chromeos/login/startup_utils.cc
@@ -61,6 +61,7 @@
   registry->RegisterStringPref(prefs::kInitialLocale, "en-US");
   registry->RegisterBooleanPref(prefs::kNewOobe, false);
   registry->RegisterBooleanPref(prefs::kWebviewSigninDisabled, false);
+  registry->RegisterBooleanPref(prefs::kNewLoginUIPopup, false);
 }
 
 // static
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 7e784d65..041be37 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
@@ -100,8 +100,6 @@
     BaseScreenDelegate* base_screen_delegate,
     SupervisedUserCreationScreenHandler* actor)
     : BaseScreen(base_screen_delegate),
-      ImageRequest(content::BrowserThread::GetMessageLoopProxyForThread(
-          content::BrowserThread::UI)),
       actor_(actor),
       on_error_screen_(false),
       manager_signin_in_progress_(false),
@@ -212,6 +210,10 @@
   controller_->FinishCreation();
 }
 
+void SupervisedUserCreationScreen::HideFlow() {
+  Hide();
+}
+
 void SupervisedUserCreationScreen::AuthenticateManager(
     const std::string& manager_id,
     const std::string& manager_password) {
@@ -589,7 +591,7 @@
 
 void SupervisedUserCreationScreen::OnPhotoTaken(
     const std::string& raw_data) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   user_photo_ = gfx::ImageSkia();
   ImageDecoder::Cancel(this);
   ImageDecoder::Start(this, raw_data);
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 62bf1ea..d51a8ed 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h
@@ -92,6 +92,7 @@
                            const std::string& manager_password) override;
   void AbortFlow() override;
   void FinishFlow() override;
+  void HideFlow() override;
   bool FindUserByDisplayName(const base::string16& display_name,
                              std::string* out_id) const override;
   void OnPageSelected(const std::string& page) override;
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc
index 5aa0eff..1851974e 100644
--- a/chrome/browser/chromeos/login/test/oobe_base_test.cc
+++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -44,7 +44,7 @@
       network_portal_detector_(NULL),
       needs_background_networking_(false),
       gaia_frame_parent_("signin-frame"),
-      use_webview_(false),
+      use_webview_(true),
       initialize_fake_merge_session_(true) {
   set_exit_when_last_browser_closes(false);
   set_chromeos_user_ = false;
diff --git a/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc b/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc
index 50432bd..50f9670 100644
--- a/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc
+++ b/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc
@@ -218,18 +218,17 @@
   ASSERT_TRUE(host);
   OobeUI* oobe = host->GetOobeUI();
   ASSERT_TRUE(oobe);
-  NetworkErrorView* network_error_view = oobe->GetNetworkErrorView();
-  ASSERT_TRUE(network_error_view);
 
   // Error screen asks portal detector to change detection strategy.
-  ErrorScreen error_screen(NULL, network_error_view);
+  ErrorScreen* error_screen = oobe->GetErrorScreen();
+  ASSERT_TRUE(error_screen);
 
   ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN, strategy_id());
   network_portal_detector()->NotifyObserversForTesting();
   OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait();
   ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN, strategy_id());
 
-  error_screen.ShowCaptivePortal();
+  error_screen->ShowCaptivePortal();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_web_dialog.cc b/chrome/browser/chromeos/login/ui/login_web_dialog.cc
index 4c3a0dd..c46692f 100644
--- a/chrome/browser/chromeos/login/ui/login_web_dialog.cc
+++ b/chrome/browser/chromeos/login/ui/login_web_dialog.cc
@@ -137,8 +137,7 @@
 
 void LoginWebDialog::OnCloseContents(WebContents* source,
                                      bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 
   if (g_web_contents_stack.Pointer()->size() &&
       source == g_web_contents_stack.Pointer()->front()) {
diff --git a/chrome/browser/chromeos/login/ui/oobe_display.h b/chrome/browser/chromeos/login/ui/oobe_display.h
index 1bf92f38..75f6614b 100644
--- a/chrome/browser/chromeos/login/ui/oobe_display.h
+++ b/chrome/browser/chromeos/login/ui/oobe_display.h
@@ -19,6 +19,7 @@
 class DeviceDisabledScreenActor;
 class EnableDebuggingScreenActor;
 class EnrollmentScreenActor;
+class ErrorScreen;
 class EulaView;
 class GaiaScreenHandler;
 class HIDDetectionView;
@@ -84,7 +85,7 @@
   virtual KioskEnableScreenActor* GetKioskEnableScreenActor() = 0;
   virtual TermsOfServiceScreenActor* GetTermsOfServiceScreenActor() = 0;
   virtual UserImageView* GetUserImageView() = 0;
-  virtual NetworkErrorView* GetNetworkErrorView() = 0;
+  virtual ErrorScreen* GetErrorScreen() = 0;
   virtual WrongHWIDScreenActor* GetWrongHWIDScreenActor() = 0;
   virtual AutoEnrollmentCheckScreenActor*
       GetAutoEnrollmentCheckScreenActor() = 0;
diff --git a/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc b/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc
index a91b2e3..7bb0765ca 100644
--- a/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc
+++ b/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc
@@ -62,7 +62,7 @@
                      window,
                      base::string16(),
                      GetURLForProxySettings(network.guid())) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   ++instance_count_;
 
   gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size()));
@@ -84,7 +84,7 @@
 }
 
 ProxySettingsDialog::~ProxySettingsDialog() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   --instance_count_;
 }
 
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc
index ccf60bf..b03a8a33 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -70,6 +70,7 @@
 const char kAccelNameAppLaunchNetworkConfig[] = "app_launch_network_config";
 const char kAccelNameNewOobe[] = "new_oobe";
 const char kAccelNameToggleWebviewSignin[] = "toggle_webview_signin";
+const char kAccelNameToggleNewLoginUI[] = "toggle_new_login_ui";
 const char kAccelNameToggleEasyBootstrap[] = "toggle_easy_bootstrap";
 
 // A class to change arrow key traversal behavior when it's alive.
@@ -134,6 +135,9 @@
       ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN)] =
       kAccelNameToggleWebviewSignin;
   accel_map_[ui::Accelerator(
+      ui::VKEY_L, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN)] =
+      kAccelNameToggleNewLoginUI;
+  accel_map_[ui::Accelerator(
       ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN)] =
       kAccelNameToggleEasyBootstrap;
 
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
index 8860df4..a5fb1fc8 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
@@ -44,8 +44,7 @@
   return true;
 }
 
-ImageLoader::ImageLoader(const base::FilePath& path)
-    : ImageRequest(base::MessageLoopProxy::current()), path_(path) {
+ImageLoader::ImageLoader(const base::FilePath& path) : path_(path) {
 }
 
 ImageLoader::~ImageLoader() {
diff --git a/chrome/browser/chromeos/login/users/user_manager_unittest.cc b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
index 3765efa..b2e6368 100644
--- a/chrome/browser/chromeos/login/users/user_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
@@ -11,14 +11,11 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/prefs/pref_service.h"
 #include "base/run_loop.h"
-#include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -26,7 +23,6 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/settings/cros_settings_names.h"
-#include "chromeos/settings/cros_settings_provider.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/common/content_switches.h"
@@ -50,7 +46,6 @@
   }
 };
 
-
 class UserManagerTest : public testing::Test {
  protected:
   void SetUp() override {
@@ -59,15 +54,7 @@
     command_line.AppendSwitch(
         chromeos::switches::kIgnoreUserProfileMappingForTests);
 
-    cros_settings_ = CrosSettings::Get();
-
-    // Replace the real DeviceSettingsProvider with a stub.
-    device_settings_provider_ =
-        cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
-    EXPECT_TRUE(device_settings_provider_);
-    EXPECT_TRUE(
-        cros_settings_->RemoveSettingsProvider(device_settings_provider_));
-    cros_settings_->AddSettingsProvider(&stub_settings_provider_);
+    settings_helper_.ReplaceProvider(kDeviceOwner);
 
     // Populate the stub DeviceSettingsProvider with valid values.
     SetDeviceSettings(false, "", false);
@@ -90,11 +77,6 @@
     // Unregister the in-memory local settings instance.
     local_state_.reset();
 
-    // Restore the real DeviceSettingsProvider.
-    EXPECT_TRUE(
-      cros_settings_->RemoveSettingsProvider(&stub_settings_provider_));
-    cros_settings_->AddSettingsProvider(device_settings_provider_);
-
     // Shut down the DeviceSettingsService.
     DeviceSettingsService::Get()->UnsetSessionManager();
     TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL);
@@ -140,14 +122,11 @@
   void SetDeviceSettings(bool ephemeral_users_enabled,
                          const std::string &owner,
                          bool supervised_users_enabled) {
-    base::FundamentalValue
-        ephemeral_users_enabled_value(ephemeral_users_enabled);
-    stub_settings_provider_.Set(kAccountsPrefEphemeralUsersEnabled,
-        ephemeral_users_enabled_value);
-    base::StringValue owner_value(owner);
-    stub_settings_provider_.Set(kDeviceOwner, owner_value);
-    stub_settings_provider_.Set(kAccountsPrefSupervisedUsersEnabled,
-        base::FundamentalValue(supervised_users_enabled));
+    settings_helper_.SetBoolean(kAccountsPrefEphemeralUsersEnabled,
+                                ephemeral_users_enabled);
+    settings_helper_.SetString(kDeviceOwner, owner);
+    settings_helper_.SetBoolean(kAccountsPrefSupervisedUsersEnabled,
+                                supervised_users_enabled);
   }
 
   void RetrieveTrustedDevicePolicies() {
@@ -157,14 +136,9 @@
  protected:
   content::TestBrowserThreadBundle thread_bundle_;
 
-  CrosSettings* cros_settings_;
-  CrosSettingsProvider* device_settings_provider_;
-  StubCrosSettingsProvider stub_settings_provider_;
+  ScopedCrosSettingsTestHelper settings_helper_;
   scoped_ptr<ScopedTestingLocalState> local_state_;
 
-  ScopedTestDeviceSettingsService test_device_settings_service_;
-  ScopedTestCrosSettings test_cros_settings_;
-
   scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
   base::ScopedTempDir temp_dir_;
 };
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 56f4a8a5..493fabb 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -286,7 +286,13 @@
 }
 
 ErrorScreen* WizardController::GetErrorScreen() {
-  return static_cast<ErrorScreen*>(GetScreen(kErrorScreenName));
+  return oobe_display_->GetErrorScreen();
+}
+
+BaseScreen* WizardController::GetScreen(const std::string& screen_name) {
+  if (screen_name == kErrorScreenName)
+    return GetErrorScreen();
+  return ScreenManager::GetScreen(screen_name);
 }
 
 BaseScreen* WizardController::CreateScreen(const std::string& screen_name) {
@@ -295,13 +301,6 @@
         new NetworkScreen(this, this, oobe_display_->GetNetworkView()));
     screen->Initialize(nullptr /* context */);
     return screen.release();
-  } else if (screen_name == kErrorScreenName) {
-    scoped_ptr<ErrorScreen> screen =
-        static_cast<OobeUI*>(oobe_display_)->GetErrorScreen();
-    if (!screen)
-      screen.reset(new ErrorScreen(this, oobe_display_->GetNetworkErrorView()));
-    screen->Initialize(nullptr /* context */);
-    return screen.release();
   } else if (screen_name == kUpdateScreenName) {
     scoped_ptr<UpdateScreen> screen(new UpdateScreen(
         this, oobe_display_->GetUpdateView(), remora_controller_.get()));
@@ -1054,11 +1053,12 @@
   }
 }
 
-void WizardController::ConfigureHost(bool accepted_eula,
-                                     const std::string& lang,
-                                     const std::string& timezone,
-                                     bool send_reports,
-                                     const std::string& keyboard_layout) {
+void WizardController::ConfigureHostRequested(
+    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.
@@ -1071,6 +1071,11 @@
   network_screen->SetInputMethod(keyboard_layout);
 }
 
+void WizardController::AddNetworkRequested(const std::string& onc_spec) {
+  NetworkScreen* network_screen = NetworkScreen::Get(this);
+  network_screen->CreateNetworkFromOnc(onc_spec);
+}
+
 void WizardController::OnEnableDebuggingScreenRequested() {
   if (!login_screen_started())
     AdvanceToScreen(WizardController::kEnableDebuggingScreenName);
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h
index 0a4b8c6..87e79cff 100644
--- a/chrome/browser/chromeos/login/wizard_controller.h
+++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -133,6 +133,7 @@
   bool login_screen_started() const { return login_screen_started_; }
 
   // ScreenManager implementation.
+  BaseScreen* GetScreen(const std::string& screen_name) override;
   BaseScreen* CreateScreen(const std::string& screen_name) override;
 
   static const char kNetworkScreenName[];
@@ -248,11 +249,12 @@
   void SetHostConfiguration() override;
 
   // Override from HostPairingScreen::Delegate:
-  void ConfigureHost(bool accepted_eula,
-                     const std::string& lang,
-                     const std::string& timezone,
-                     bool send_reports,
-                     const std::string& keyboard_layout) override;
+  void ConfigureHostRequested(bool accepted_eula,
+                              const std::string& lang,
+                              const std::string& timezone,
+                              bool send_reports,
+                              const std::string& keyboard_layout) override;
+  void AddNetworkRequested(const std::string& onc_spec) override;
 
   // Override from NetworkScreen::Delegate:
   void OnEnableDebuggingScreenRequested() override;
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
index 3b717469..1d6f75ad 100644
--- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -1012,11 +1012,6 @@
       if (!GetParam())
         local_state_dict.SetBoolean(prefs::kWebviewSigninDisabled, true);
 
-      // TODO(paulmeyer): Re-enable webview version of this test
-      // (drop this condition) once http://crbug.com/452452 is fixed.
-      if (GetParam())
-        local_state_dict.SetBoolean(prefs::kWebviewSigninDisabled, true);
-
       CHECK(JSONFileValueSerializer(local_state_path)
                 .Serialize(local_state_dict));
     }
@@ -1044,9 +1039,11 @@
   auth_needed_waiter.Wait();
 }
 
+// TODO(paulmeyer): Re-enable webview version of this test
+// (drop this condition) once http://crbug.com/452452 is fixed.
 INSTANTIATE_TEST_CASE_P(WizardControllerProxyAuthOnSigninSuite,
                         WizardControllerProxyAuthOnSigninTest,
-                        testing::Bool());
+                        testing::Values(false));
 
 class WizardControllerKioskFlowTest : public WizardControllerFlowTest {
  protected:
diff --git a/chrome/browser/chromeos/mobile/mobile_activator.cc b/chrome/browser/chromeos/mobile/mobile_activator.cc
index 73b5d44..02b0b534 100644
--- a/chrome/browser/chromeos/mobile/mobile_activator.cc
+++ b/chrome/browser/chromeos/mobile/mobile_activator.cc
@@ -239,17 +239,17 @@
 }
 
 void MobileActivator::AddObserver(MobileActivator::Observer* observer) {
-  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   observers_.AddObserver(observer);
 }
 
 void MobileActivator::RemoveObserver(MobileActivator::Observer* observer) {
-  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   observers_.RemoveObserver(observer);
 }
 
 void MobileActivator::InitiateActivation(const std::string& service_path) {
-  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const NetworkState* network =  GetNetworkState(service_path);
   if (!network) {
     LOG(WARNING) << "Cellular service can't be found: " << service_path;
diff --git a/chrome/browser/chromeos/net/network_portal_web_dialog.cc b/chrome/browser/chromeos/net/network_portal_web_dialog.cc
index fd14550..3b6db22c 100644
--- a/chrome/browser/chromeos/net/network_portal_web_dialog.cc
+++ b/chrome/browser/chromeos/net/network_portal_web_dialog.cc
@@ -94,8 +94,7 @@
 
 void NetworkPortalWebDialog::OnCloseContents(content::WebContents* /* source */,
                                              bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool NetworkPortalWebDialog::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc b/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc
index b515447..8042251 100644
--- a/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc
+++ b/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc
@@ -4,13 +4,27 @@
 
 #include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h"
 
+#include "base/logging.h"
+#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "components/ownership/mock_owner_key_util.h"
+
 namespace chromeos {
 
+FakeOwnerSettingsService::FakeOwnerSettingsService(Profile* profile)
+    : OwnerSettingsServiceChromeOS(nullptr,
+                                   profile,
+                                   new ownership::MockOwnerKeyUtil()),
+      set_management_settings_result_(true),
+      settings_provider_(nullptr) {
+}
+
 FakeOwnerSettingsService::FakeOwnerSettingsService(
     Profile* profile,
-    const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util)
+    const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util,
+    StubCrosSettingsProvider* provider)
     : OwnerSettingsServiceChromeOS(nullptr, profile, owner_key_util),
-      set_management_settings_result_(true) {
+      set_management_settings_result_(true),
+      settings_provider_(provider) {
 }
 
 FakeOwnerSettingsService::~FakeOwnerSettingsService() {
@@ -23,4 +37,11 @@
   callback.Run(set_management_settings_result_);
 }
 
+bool FakeOwnerSettingsService::Set(const std::string& setting,
+                                   const base::Value& value) {
+  CHECK(settings_provider_);
+  settings_provider_->Set(setting, value);
+  return true;
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/ownership/fake_owner_settings_service.h b/chrome/browser/chromeos/ownership/fake_owner_settings_service.h
index bed4d06..3f785c1 100644
--- a/chrome/browser/chromeos/ownership/fake_owner_settings_service.h
+++ b/chrome/browser/chromeos/ownership/fake_owner_settings_service.h
@@ -17,11 +17,15 @@
 
 namespace chromeos {
 
+class StubCrosSettingsProvider;
+
 class FakeOwnerSettingsService : public OwnerSettingsServiceChromeOS {
  public:
+  explicit FakeOwnerSettingsService(Profile* profile);
   FakeOwnerSettingsService(
       Profile* profile,
-      const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util);
+      const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util,
+      StubCrosSettingsProvider* provider);
   ~FakeOwnerSettingsService() override;
 
   void set_set_management_settings_result(bool success) {
@@ -36,10 +40,12 @@
   void SetManagementSettings(
       const ManagementSettings& settings,
       const OnManagementSettingsSetCallback& callback) override;
+  bool Set(const std::string& setting, const base::Value& value) override;
 
  private:
   bool set_management_settings_result_;
   ManagementSettings last_settings_;
+  StubCrosSettingsProvider* settings_provider_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeOwnerSettingsService);
 };
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
index bac0fba..a96f0aa 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -174,6 +174,7 @@
   NOTREACHED();
   return false;
 }
+
 }  // namespace
 
 OwnerSettingsServiceChromeOS::ManagementSettings::ManagementSettings() {
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
index 03b0504..72db1d7 100644
--- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
+++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -85,7 +85,10 @@
       public content::NotificationObserver,
       public testing::WithParamInterface<BlockingLoginTestParam> {
  public:
-  BlockingLoginTest() : profile_added_(NULL) {}
+  BlockingLoginTest() : profile_added_(NULL) {
+    // TODO(nkostylev): Fix this test for webview. http://crbug.com/477402
+    set_use_webview(false);
+  }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     OobeBaseTest::SetUpCommandLine(command_line);
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc
index cacf3960..1a9ba8b 100644
--- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc
+++ b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc
@@ -59,9 +59,8 @@
         base::ThreadTaskRunnerHandle::Get()));
 
     // Set up FakeOwnerSettingsService.
-    fake_owner_settings_service_.reset(
-        new chromeos::FakeOwnerSettingsService(
-            profile_.get(), owner_key_util_));
+    fake_owner_settings_service_.reset(new chromeos::FakeOwnerSettingsService(
+        profile_.get(), owner_key_util_, nullptr));
     chromeos::OwnerSettingsServiceChromeOS::ManagementSettings settings;
     settings.management_mode = policy::MANAGEMENT_MODE_CONSUMER_MANAGED;
     settings.request_token = "fake_request_token";
diff --git a/chrome/browser/chromeos/policy/device_local_account.cc b/chrome/browser/chromeos/policy/device_local_account.cc
index 80b89b2..63c7a14 100644
--- a/chrome/browser/chromeos/policy/device_local_account.cc
+++ b/chrome/browser/chromeos/policy/device_local_account.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chromeos/login/user_names.h"
 #include "chromeos/settings/cros_settings_names.h"
@@ -91,9 +92,8 @@
   return true;
 }
 
-void SetDeviceLocalAccounts(
-    chromeos::CrosSettings* cros_settings,
-    const std::vector<DeviceLocalAccount>& accounts) {
+void SetDeviceLocalAccounts(chromeos::OwnerSettingsServiceChromeOS* service,
+                            const std::vector<DeviceLocalAccount>& accounts) {
   base::ListValue list;
   for (std::vector<DeviceLocalAccount>::const_iterator it = accounts.begin();
        it != accounts.end(); ++it) {
@@ -117,7 +117,7 @@
     list.Append(entry.release());
   }
 
-  cros_settings->Set(chromeos::kAccountsPrefDeviceLocalAccounts, list);
+  service->Set(chromeos::kAccountsPrefDeviceLocalAccounts, list);
 }
 
 std::vector<DeviceLocalAccount> GetDeviceLocalAccounts(
diff --git a/chrome/browser/chromeos/policy/device_local_account.h b/chrome/browser/chromeos/policy/device_local_account.h
index 69a7480..8827119 100644
--- a/chrome/browser/chromeos/policy/device_local_account.h
+++ b/chrome/browser/chromeos/policy/device_local_account.h
@@ -10,6 +10,7 @@
 
 namespace chromeos {
 class CrosSettings;
+class OwnerSettingsServiceChromeOS;
 }
 
 namespace policy {
@@ -64,12 +65,11 @@
 bool IsDeviceLocalAccountUser(const std::string& user_id,
                               DeviceLocalAccount::Type* type);
 
-// Stores a list of device-local accounts in |cros_settings|. The accounts are
-// stored as a list of dictionaries with each dictionary containing the
-// information about one |DeviceLocalAccount|.
-void SetDeviceLocalAccounts(
-    chromeos::CrosSettings* cros_settings,
-    const std::vector<DeviceLocalAccount>& accounts);
+// Stores a list of device-local accounts in |service|. The accounts are stored
+// as a list of dictionaries with each dictionary containing the information
+// about one |DeviceLocalAccount|.
+void SetDeviceLocalAccounts(chromeos::OwnerSettingsServiceChromeOS* service,
+                            const std::vector<DeviceLocalAccount>& accounts);
 
 // Retrieves a list of device-local accounts from |cros_settings|.
 std::vector<DeviceLocalAccount> GetDeviceLocalAccounts(
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
index 59e8401..8e78071 100644
--- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
+++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 
-#include <string>
 #include <vector>
 
 #include "base/files/file_path.h"
@@ -31,13 +30,14 @@
 
 DevicePolicyCrosTestHelper::~DevicePolicyCrosTestHelper() {}
 
-void DevicePolicyCrosTestHelper::MarkAsEnterpriseOwned() {
+// static
+void DevicePolicyCrosTestHelper::MarkAsEnterpriseOwnedBy(
+    const std::string& user_name) {
   OverridePaths();
 
   const std::string install_attrs_blob(
       EnterpriseInstallAttributes::
-          GetEnterpriseOwnedInstallAttributesBlobForTesting(
-              device_policy_.policy_data().username()));
+          GetEnterpriseOwnedInstallAttributesBlobForTesting(user_name));
 
   base::FilePath install_attrs_file;
   ASSERT_TRUE(
@@ -48,6 +48,10 @@
                             install_attrs_blob.size()));
 }
 
+void DevicePolicyCrosTestHelper::MarkAsEnterpriseOwned() {
+  MarkAsEnterpriseOwnedBy(device_policy_.policy_data().username());
+}
+
 void DevicePolicyCrosTestHelper::InstallOwnerKey() {
   OverridePaths();
 
@@ -63,6 +67,7 @@
       static_cast<int>(owner_key_bits.size()));
 }
 
+// static
 void DevicePolicyCrosTestHelper::OverridePaths() {
   // This is usually done by ChromeBrowserMainChromeOS, but some tests
   // use the overridden paths before ChromeBrowserMain starts. Make sure that
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
index e6e90a9e..ca528977 100644
--- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
+++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_POLICY_CROS_BROWSER_TEST_H_
 #define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_POLICY_CROS_BROWSER_TEST_H_
 
+#include <string>
+
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
@@ -25,6 +27,7 @@
   // Marks the device as enterprise-owned. Must be called to make device
   // policies apply Chrome-wide. If this is not called, device policies will
   // affect CrosSettings only.
+  static void MarkAsEnterpriseOwnedBy(const std::string& user_name);
   void MarkAsEnterpriseOwned();
 
   // Writes the owner key to disk. To be called before installing a policy.
@@ -33,7 +36,7 @@
   DevicePolicyBuilder* device_policy() { return &device_policy_; }
 
  private:
-  void OverridePaths();
+  static void OverridePaths();
 
   // Carries Chrome OS device policies for tests.
   DevicePolicyBuilder device_policy_;
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
index c031b59..dbd79a7 100644
--- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -18,12 +18,11 @@
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
+#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.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/stub_enterprise_install_attributes.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/dbus/cros_disks_client.h"
@@ -37,7 +36,6 @@
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/settings/cros_settings_names.h"
-#include "chromeos/settings/cros_settings_provider.h"
 #include "chromeos/system/fake_statistics_provider.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/geolocation_provider.h"
@@ -230,20 +228,20 @@
 class DeviceStatusCollectorTest : public testing::Test {
  public:
   DeviceStatusCollectorTest()
-    : ui_thread_(content::BrowserThread::UI, &message_loop_),
-      file_thread_(content::BrowserThread::FILE, &message_loop_),
-      io_thread_(content::BrowserThread::IO, &message_loop_),
-      install_attributes_("managed.com",
-                          "user@managed.com",
-                          "device_id",
-                          DEVICE_MODE_ENTERPRISE),
-      user_manager_(new chromeos::MockUserManager()),
-      user_manager_enabler_(user_manager_),
-      fake_device_local_account_(
-          policy::DeviceLocalAccount::TYPE_KIOSK_APP,
-          kKioskAccountId,
-          kKioskAppId,
-          std::string() /* kiosk_app_update_url */) {
+      : ui_thread_(content::BrowserThread::UI, &message_loop_),
+        file_thread_(content::BrowserThread::FILE, &message_loop_),
+        io_thread_(content::BrowserThread::IO, &message_loop_),
+        install_attributes_("managed.com",
+                            "user@managed.com",
+                            "device_id",
+                            DEVICE_MODE_ENTERPRISE),
+        settings_helper_(false),
+        user_manager_(new chromeos::MockUserManager()),
+        user_manager_enabler_(user_manager_),
+        fake_device_local_account_(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
+                                   kKioskAccountId,
+                                   kKioskAppId,
+                                   std::string() /* kiosk_app_update_url */) {
     // Run this test with a well-known timezone so that Time::LocalMidnight()
     // returns the same values on all machines.
     scoped_ptr<base::Environment> env(base::Environment::Create());
@@ -274,14 +272,9 @@
     DiskMountManager::InitializeForTesting(mock_disk_mount_manager.release());
     TestingDeviceStatusCollector::RegisterPrefs(prefs_.registry());
 
-    // Remove the real DeviceSettingsProvider and replace it with a stub.
-    cros_settings_ = chromeos::CrosSettings::Get();
-    device_settings_provider_ =
-        cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
-    EXPECT_TRUE(device_settings_provider_ != NULL);
-    EXPECT_TRUE(
-        cros_settings_->RemoveSettingsProvider(device_settings_provider_));
-    cros_settings_->AddSettingsProvider(&stub_settings_provider_);
+    settings_helper_.ReplaceProvider(chromeos::kReportDeviceActivityTimes);
+    owner_settings_service_ =
+        settings_helper_.CreateOwnerSettingsService(nullptr);
 
     RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
                            base::Bind(&GetEmptyCPUStatistics));
@@ -301,18 +294,16 @@
     message_loop_.RunUntilIdle();
     storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
     DiskMountManager::Shutdown();
-
-    // Restore the real DeviceSettingsProvider.
-    EXPECT_TRUE(
-        cros_settings_->RemoveSettingsProvider(&stub_settings_provider_));
-    cros_settings_->AddSettingsProvider(device_settings_provider_);
   }
 
   void SetUp() override {
     // Disable network interface reporting since it requires additional setup.
-    cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
+    settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces,
+                                false);
   }
 
+  void TearDown() override { settings_helper_.RestoreProvider(); }
+
   void RestartStatusCollector(
       const policy::DeviceStatusCollector::VolumeInfoFetcher& volume_info,
       const policy::DeviceStatusCollector::CPUStatisticsFetcher& cpu_stats) {
@@ -370,7 +361,7 @@
   void MockRunningKioskApp(const DeviceLocalAccount& account) {
     std::vector<DeviceLocalAccount> accounts;
     accounts.push_back(account);
-    SetDeviceLocalAccounts(cros_settings_, accounts);
+    SetDeviceLocalAccounts(owner_settings_service_.get(), accounts);
     user_manager_->CreateKioskAppUser(account.user_id);
     EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp()).WillRepeatedly(
         Return(true));
@@ -396,9 +387,8 @@
   DiskMountManager::MountPointMap mount_point_map_;
   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
   chromeos::ScopedTestCrosSettings test_cros_settings_;
-  chromeos::CrosSettings* cros_settings_;
-  chromeos::CrosSettingsProvider* device_settings_provider_;
-  chromeos::StubCrosSettingsProvider stub_settings_provider_;
+  chromeos::ScopedCrosSettingsTestHelper settings_helper_;
+  scoped_ptr<chromeos::FakeOwnerSettingsService> owner_settings_service_;
   chromeos::MockUserManager* user_manager_;
   chromeos::ScopedUserManagerEnabler user_manager_enabler_;
   em::DeviceStatusReportRequest status_;
@@ -412,7 +402,7 @@
     ui::IDLE_STATE_IDLE,
     ui::IDLE_STATE_IDLE
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
 
   // Test reporting with no data.
   GetStatus();
@@ -439,7 +429,7 @@
     ui::IDLE_STATE_ACTIVE,
     ui::IDLE_STATE_ACTIVE
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
 
   // Test a single active sample.
   status_collector_->Simulate(test_states, 1);
@@ -466,7 +456,7 @@
     ui::IDLE_STATE_IDLE,
     ui::IDLE_STATE_ACTIVE
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
@@ -482,7 +472,7 @@
     ui::IDLE_STATE_IDLE,
     ui::IDLE_STATE_IDLE
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
 
@@ -507,7 +497,7 @@
     ui::IDLE_STATE_IDLE,
     ui::IDLE_STATE_IDLE
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
@@ -521,7 +511,7 @@
   };
   const int kMaxDays = 10;
 
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
   status_collector_->set_max_stored_past_activity_days(kMaxDays - 1);
   status_collector_->set_max_stored_future_activity_days(1);
   Time baseline = Time::Now().LocalMidnight();
@@ -576,7 +566,7 @@
 
 TEST_F(DeviceStatusCollectorTest, ActivityTimesOff) {
   // Device activity times should not be reported if explicitly disabled.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, false);
 
   ui::IdleState test_states[] = {
     ui::IDLE_STATE_ACTIVE,
@@ -594,7 +584,7 @@
   ui::IdleState test_states[] = {
     ui::IDLE_STATE_ACTIVE
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
 
   // Set the baseline time to 10 seconds after midnight.
   status_collector_->SetBaselineTime(
@@ -626,7 +616,7 @@
     ui::IDLE_STATE_ACTIVE,
     ui::IDLE_STATE_ACTIVE,
   };
-  cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
 
   status_collector_->Simulate(test_states, 2);
   GetStatus();
@@ -654,14 +644,14 @@
   EXPECT_EQ("Verified", status_.boot_mode());
 
   // Test that boot mode data is not reported if the pref turned off.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceBootMode, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceBootMode, false);
 
   GetStatus();
   EXPECT_FALSE(status_.has_boot_mode());
 
   // Turn the pref on, and check that the status is reported iff the
   // statistics provider returns valid data.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceBootMode, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceBootMode, true);
 
   fake_statistics_provider_.SetMachineStatistic(
       chromeos::system::kDevSwitchBootKey, "(error)");
@@ -695,13 +685,13 @@
 
   // When the pref to collect this data is not enabled, expect that none of
   // the fields are present in the protobuf.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceVersionInfo, false);
   GetStatus();
   EXPECT_FALSE(status_.has_browser_version());
   EXPECT_FALSE(status_.has_os_version());
   EXPECT_FALSE(status_.has_firmware_version());
 
-  cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceVersionInfo, true);
   GetStatus();
   EXPECT_TRUE(status_.has_browser_version());
   EXPECT_TRUE(status_.has_os_version());
@@ -733,7 +723,7 @@
   // Check that when device location reporting is enabled and a valid fix is
   // available, the location is reported and is stored in local state.
   SetMockPositionToReturnNext(valid_fix);
-  cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, true);
   EXPECT_FALSE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
   CheckThatAValidLocationIsReported();
 
@@ -748,7 +738,7 @@
   // Check that after disabling location reporting again, the last known
   // location has been cleared from local state and is no longer reported.
   SetMockPositionToReturnNext(valid_fix);
-  cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, false);
   // Allow the new pref to propagate to the status collector.
   message_loop_.RunUntilIdle();
   EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
@@ -757,7 +747,7 @@
   // Check that after enabling location reporting again, an error is reported
   // if no valid fix is available.
   SetMockPositionToReturnNext(invalid_fix);
-  cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, true);
   // Allow the new pref to propagate to the status collector.
   message_loop_.RunUntilIdle();
   CheckThatALocationErrorIsReported();
@@ -777,7 +767,7 @@
   EXPECT_EQ(6, status_.user_size());
 
   // Verify that users are reported after enabling the setting.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceUsers, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, true);
   GetStatus();
   EXPECT_EQ(6, status_.user_size());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(0).type());
@@ -794,7 +784,7 @@
   EXPECT_EQ("user5@managed.com", status_.user(5).email());
 
   // Verify that users are no longer reported if setting is disabled.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceUsers, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, false);
   GetStatus();
   EXPECT_EQ(0, status_.user_size());
 }
@@ -843,7 +833,7 @@
   }
 
   // Now turn off hardware status reporting - should have no data.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
   GetStatus();
   EXPECT_EQ(0, status_.volume_info_size());
 }
@@ -903,21 +893,21 @@
     EXPECT_EQ(0, utilization);
 
   // Turning off hardware reporting should not report CPU utilization.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
   GetStatus();
   EXPECT_EQ(0, status_.cpu_utilization_pct().size());
 }
 
 TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfNotKioskMode) {
   // Should not report session status if we don't have an active kiosk app.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceSessionStatus, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true);
   em::SessionStatusReportRequest session_status;
   EXPECT_FALSE(status_collector_->GetDeviceSessionStatus(&session_status));
 }
 
 TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfSessionReportingDisabled) {
   // Should not report session status if session status reporting is disabled.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceSessionStatus, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, false);
   status_collector_->set_kiosk_account(make_scoped_ptr(
       new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
   // Set up a device-local account for single-app kiosk mode.
@@ -928,7 +918,7 @@
 }
 
 TEST_F(DeviceStatusCollectorTest, ReportSessionStatus) {
-  cros_settings_->SetBoolean(chromeos::kReportDeviceSessionStatus, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true);
   status_collector_->set_kiosk_account(make_scoped_ptr(
       new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
 
@@ -1164,13 +1154,13 @@
   EXPECT_LT(0, status_.network_state_size());
 
   // No interfaces should be reported if the policy is off.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
   GetStatus();
   EXPECT_EQ(0, status_.network_interface_size());
   EXPECT_EQ(0, status_.network_state_size());
 
   // Switch the policy on and verify the interface list is present.
-  cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
+  settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
   GetStatus();
 
   int count = 0;
diff --git a/chrome/browser/chromeos/policy/extension_cache_unittest.cc b/chrome/browser/chromeos/policy/extension_cache_unittest.cc
index 0b88894..5191e0c 100644
--- a/chrome/browser/chromeos/policy/extension_cache_unittest.cc
+++ b/chrome/browser/chromeos/policy/extension_cache_unittest.cc
@@ -10,14 +10,11 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/run_loop.h"
 #include "base/time/time.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/extensions/updater/chromeos_extension_cache_delegate.h"
 #include "chrome/browser/extensions/updater/extension_cache_impl.h"
 #include "chrome/browser/extensions/updater/local_extension_cache.h"
 #include "chromeos/settings/cros_settings_names.h"
-#include "chromeos/settings/cros_settings_provider.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -58,39 +55,14 @@
 }  // namespace
 
 class ExtensionCacheTest : public testing::Test {
- public:
-  void SetUp() override {
-    // Swap out the DeviceSettingsProvider with our stub settings provider
-    // so we can set values for maximum extension cache size.
-    chromeos::CrosSettings* const cros_settings = chromeos::CrosSettings::Get();
-    device_settings_provider_ =
-        cros_settings->GetProvider(chromeos::kExtensionCacheSize);
-    EXPECT_TRUE(device_settings_provider_);
-    EXPECT_TRUE(
-        cros_settings->RemoveSettingsProvider(device_settings_provider_));
-    cros_settings->AddSettingsProvider(&stub_settings_provider_);
-  }
-
-  void TearDown() override {
-    // Restore the real DeviceSettingsProvider.
-    chromeos::CrosSettings* const cros_settings = chromeos::CrosSettings::Get();
-    EXPECT_TRUE(
-        cros_settings->RemoveSettingsProvider(&stub_settings_provider_));
-    cros_settings->AddSettingsProvider(device_settings_provider_);
-  }
-
-  // Helpers used to mock out cros settings.
-  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
-  chromeos::ScopedTestCrosSettings test_cros_settings_;
-  chromeos::CrosSettingsProvider* device_settings_provider_ = nullptr;
-  chromeos::StubCrosSettingsProvider stub_settings_provider_;
-
+ protected:
   content::TestBrowserThreadBundle thread_bundle_;
+  chromeos::ScopedCrosSettingsTestHelper settings_helper_;
 };
 
 TEST_F(ExtensionCacheTest, SizePolicy) {
-  chromeos::CrosSettings::Get()->SetInteger(chromeos::kExtensionCacheSize,
-                                            kMaxCacheSize);
+  settings_helper_.ReplaceProvider(chromeos::kExtensionCacheSize);
+  settings_helper_.SetInteger(chromeos::kExtensionCacheSize, kMaxCacheSize);
 
   // Create and initialize local cache.
   const base::Time now = base::Time::Now();
diff --git a/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc b/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc
index 7a1a05c..8e5686b4e 100644
--- a/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc
+++ b/chrome/browser/chromeos/policy/heartbeat_scheduler_unittest.cc
@@ -6,9 +6,7 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "base/test/test_simple_task_runner.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/gcm_driver/fake_gcm_driver.h"
 #include "content/public/test/test_utils.h"
@@ -63,24 +61,11 @@
   }
 
   void SetUp() override {
-    // Swap out the DeviceSettingsProvider with our stub settings provider
-    // so we can set values for the heartbeat frequency.
-    chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
-    device_settings_provider_ =
-        cros_settings->GetProvider(chromeos::kReportDeviceVersionInfo);
-    EXPECT_TRUE(device_settings_provider_);
-    EXPECT_TRUE(
-        cros_settings->RemoveSettingsProvider(device_settings_provider_));
-    cros_settings->AddSettingsProvider(&stub_settings_provider_);
+    settings_helper_.ReplaceProvider(chromeos::kHeartbeatEnabled);
   }
 
   void TearDown() override {
     content::RunAllBlockingPoolTasksUntilIdle();
-    // Restore the real DeviceSettingsProvider.
-    chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
-    EXPECT_TRUE(cros_settings->RemoveSettingsProvider(
-        &stub_settings_provider_));
-    cros_settings->AddSettingsProvider(device_settings_provider_);
   }
 
   void CheckPendingTaskDelay(base::Time last_heartbeat,
@@ -106,14 +91,8 @@
   }
 
   base::MessageLoop loop_;
-
-  // Helpers used to mock out cros settings.
-  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
-  chromeos::ScopedTestCrosSettings test_cros_settings_;
-  chromeos::CrosSettingsProvider* device_settings_provider_;
-  chromeos::StubCrosSettingsProvider stub_settings_provider_;
-
   MockGCMDriver gcm_driver_;
+  chromeos::ScopedCrosSettingsTestHelper settings_helper_;
 
   // TaskRunner used to run individual tests.
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
@@ -125,16 +104,14 @@
 TEST_F(HeartbeatSchedulerTest, Basic) {
   // Just makes sure we can spin up and shutdown the scheduler with
   // heartbeats disabled.
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, false);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, false);
   ASSERT_TRUE(task_runner_->GetPendingTasks().empty());
 }
 
 TEST_F(HeartbeatSchedulerTest, PermanentlyFailedGCMRegistration) {
   // If heartbeats are enabled, we should register with GCMDriver.
   EXPECT_CALL(gcm_driver_, RegisterImpl(kHeartbeatGCMAppID, _));
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, true);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, true);
   gcm_driver_.CompleteRegistration(
       kHeartbeatGCMAppID, gcm::GCMClient::GCM_DISABLED);
 
@@ -144,8 +121,7 @@
 
 TEST_F(HeartbeatSchedulerTest, TemporarilyFailedGCMRegistration) {
   EXPECT_CALL(gcm_driver_, RegisterImpl(kHeartbeatGCMAppID, _));
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, true);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, true);
   gcm_driver_.CompleteRegistration(
       kHeartbeatGCMAppID, gcm::GCMClient::SERVER_ERROR);
   testing::Mock::VerifyAndClearExpectations(&gcm_driver_);
@@ -165,8 +141,7 @@
 
 TEST_F(HeartbeatSchedulerTest, ChangeHeartbeatFrequency) {
   EXPECT_CALL(gcm_driver_, RegisterImpl(kHeartbeatGCMAppID, _));
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, true);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, true);
   gcm_driver_.CompleteRegistration(
       kHeartbeatGCMAppID, gcm::GCMClient::SUCCESS);
 
@@ -176,8 +151,7 @@
   testing::Mock::VerifyAndClearExpectations(&gcm_driver_);
 
   const int new_delay = 1234*1000;  // 1234 seconds.
-  chromeos::CrosSettings::Get()->SetInteger(chromeos::kHeartbeatFrequency,
-                                            new_delay);
+  settings_helper_.SetInteger(chromeos::kHeartbeatFrequency, new_delay);
   // Now run pending heartbeat task, should send a heartbeat.
   gcm::GCMClient::OutgoingMessage message;
   EXPECT_CALL(gcm_driver_, SendImpl(kHeartbeatGCMAppID, _, _))
@@ -197,8 +171,7 @@
 TEST_F(HeartbeatSchedulerTest, DisableHeartbeats) {
   // Makes sure that we can disable heartbeats on the fly.
   EXPECT_CALL(gcm_driver_, RegisterImpl(kHeartbeatGCMAppID, _));
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, true);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, true);
   gcm::GCMClient::OutgoingMessage message;
   EXPECT_CALL(gcm_driver_, SendImpl(kHeartbeatGCMAppID, _, _))
       .WillOnce(SaveArg<2>(&message));
@@ -221,8 +194,7 @@
   testing::Mock::VerifyAndClearExpectations(&gcm_driver_);
 
   // Now disable heartbeats. Should get no more heartbeats sent.
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, false);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, false);
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
 }
@@ -232,8 +204,7 @@
   EXPECT_CALL(gcm_driver_, RegisterImpl(kHeartbeatGCMAppID, _));
   EXPECT_CALL(gcm_driver_, SendImpl(kHeartbeatGCMAppID, _, _))
       .WillOnce(SaveArg<2>(&message));
-  chromeos::CrosSettings::Get()->SetBoolean(
-      chromeos::kHeartbeatEnabled, true);
+  settings_helper_.SetBoolean(chromeos::kHeartbeatEnabled, true);
   gcm_driver_.CompleteRegistration(
       kHeartbeatGCMAppID, gcm::GCMClient::SUCCESS);
   task_runner_->RunPendingTasks();
diff --git a/chrome/browser/chromeos/policy/login_policy_test_base.cc b/chrome/browser/chromeos/policy/login_policy_test_base.cc
index 5525ccf..710b0bda 100644
--- a/chrome/browser/chromeos/policy/login_policy_test_base.cc
+++ b/chrome/browser/chromeos/policy/login_policy_test_base.cc
@@ -66,6 +66,8 @@
 const char LoginPolicyTestBase::kAccountId[] = "user@example.com";
 
 LoginPolicyTestBase::LoginPolicyTestBase() {
+  // TODO(nkostylev): Fix this test harness for webview. http://crbug.com/477402
+  set_use_webview(false);
   set_open_about_blank_on_browser_launch(false);
 }
 
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
index 1dd6406..da4a95c 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -12,8 +12,7 @@
 #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
 #include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/network/fake_network_device_handler.h"
 #include "chromeos/network/mock_managed_network_configuration_handler.h"
@@ -287,10 +286,7 @@
   StrictMock<chromeos::MockManagedNetworkConfigurationHandler>
       network_config_handler_;
   FakeNetworkDeviceHandler network_device_handler_;
-
-  // Not used directly. Required for CrosSettings.
-  chromeos::ScopedTestDeviceSettingsService scoped_device_settings_service_;
-  chromeos::ScopedTestCrosSettings scoped_cros_settings_;
+  chromeos::ScopedCrosSettingsTestHelper settings_helper_;
 
   // Ownership of certificate_importer_owned_ is passed to the
   // NetworkConfigurationUpdater. When that happens, |certificate_importer_|
@@ -313,28 +309,16 @@
   // Ignore network config updates.
   EXPECT_CALL(network_config_handler_, SetPolicy(_, _, _, _)).Times(AtLeast(1));
 
-  // Setup the DataRoaming device setting.
-  chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
-  chromeos::CrosSettingsProvider* device_settings_provider =
-      cros_settings->GetProvider(chromeos::kSignedDataRoamingEnabled);
-  cros_settings->RemoveSettingsProvider(device_settings_provider);
-  delete device_settings_provider;
-  chromeos::StubCrosSettingsProvider* stub_settings_provider =
-      new chromeos::StubCrosSettingsProvider;
-  cros_settings->AddSettingsProvider(stub_settings_provider);
-
-  chromeos::CrosSettings::Get()->Set(chromeos::kSignedDataRoamingEnabled,
-                                     base::FundamentalValue(false));
+  settings_helper_.ReplaceProvider(chromeos::kSignedDataRoamingEnabled);
+  settings_helper_.SetBoolean(chromeos::kSignedDataRoamingEnabled, false);
   EXPECT_FALSE(network_device_handler_.allow_roaming_);
 
   CreateNetworkConfigurationUpdaterForDevicePolicy();
   MarkPolicyProviderInitialized();
-  chromeos::CrosSettings::Get()->Set(chromeos::kSignedDataRoamingEnabled,
-                                     base::FundamentalValue(true));
+  settings_helper_.SetBoolean(chromeos::kSignedDataRoamingEnabled, true);
   EXPECT_TRUE(network_device_handler_.allow_roaming_);
 
-  chromeos::CrosSettings::Get()->Set(chromeos::kSignedDataRoamingEnabled,
-                                     base::FundamentalValue(false));
+  settings_helper_.SetBoolean(chromeos::kSignedDataRoamingEnabled, false);
   EXPECT_FALSE(network_device_handler_.allow_roaming_);
 }
 
diff --git a/chrome/browser/chromeos/policy/policy_cert_verifier.cc b/chrome/browser/chromeos/policy/policy_cert_verifier.cc
index 524ca947..cca86b06 100644
--- a/chrome/browser/chromeos/policy/policy_cert_verifier.cc
+++ b/chrome/browser/chromeos/policy/policy_cert_verifier.cc
@@ -18,7 +18,7 @@
 void MaybeSignalAnchorUse(int error,
                           const base::Closure& anchor_used_callback,
                           const net::CertVerifyResult& verify_result) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (error != net::OK || !verify_result.is_issued_by_additional_trust_anchor ||
       anchor_used_callback.is_null()) {
     return;
@@ -31,7 +31,7 @@
     const net::CompletionCallback& completion_callback,
     const net::CertVerifyResult* verify_result,
     int error) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   MaybeSignalAnchorUse(error, anchor_used_callback, *verify_result);
   if (!completion_callback.is_null())
     completion_callback.Run(error);
@@ -42,7 +42,7 @@
 PolicyCertVerifier::PolicyCertVerifier(
     const base::Closure& anchor_used_callback)
     : anchor_used_callback_(anchor_used_callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 }
 
 PolicyCertVerifier::~PolicyCertVerifier() {
diff --git a/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc b/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc
new file mode 100644
index 0000000..81bb0564
--- /dev/null
+++ b/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc
@@ -0,0 +1,97 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/policy/login_policy_test_base.h"
+#include "chrome/browser/prefs/session_startup_pref.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/host_desktop.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_utils.h"
+#include "policy/policy_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace policy {
+
+namespace {
+const char kStartUpURL1[] = "chrome://chrome/";
+const char kStartUpURL2[] = "chrome://version/";
+}
+
+// Verifies that the |kRestoreOnStartup| and |kRestoreOnStartupURLs| policies
+// are honored on Chrome OS.
+class RestoreOnStartupTestChromeOS : public LoginPolicyTestBase {
+ public:
+  RestoreOnStartupTestChromeOS();
+
+  // LoginPolicyTestBase:
+  void SetUpCommandLine(base::CommandLine* command_line) override;
+  scoped_ptr<base::DictionaryValue> GetMandatoryPoliciesValue() const override;
+
+  void LogInAndVerifyStartUpURLs();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(RestoreOnStartupTestChromeOS);
+};
+
+RestoreOnStartupTestChromeOS::RestoreOnStartupTestChromeOS() {
+}
+
+void RestoreOnStartupTestChromeOS::SetUpCommandLine(
+    base::CommandLine* command_line) {
+  LoginPolicyTestBase::SetUpCommandLine(command_line);
+  command_line->AppendSwitch(switches::kDisableChildAccountDetection);
+}
+
+scoped_ptr<base::DictionaryValue>
+RestoreOnStartupTestChromeOS::GetMandatoryPoliciesValue() const {
+  scoped_ptr<base::DictionaryValue> policy(new base::DictionaryValue);
+  policy->SetInteger(key::kRestoreOnStartup,
+                     SessionStartupPref::kPrefValueURLs);
+  scoped_ptr<base::ListValue> urls(new base::ListValue);
+  urls->AppendString(kStartUpURL1);
+  urls->AppendString(kStartUpURL2);
+  policy->Set(key::kRestoreOnStartupURLs, urls.Pass());
+  return policy;
+}
+
+void RestoreOnStartupTestChromeOS::LogInAndVerifyStartUpURLs() {
+  LogIn(kAccountId, kAccountPassword);
+
+  const BrowserList* const browser_list =
+      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
+  ASSERT_EQ(1U, browser_list->size());
+  const Browser* const browser = browser_list->get(0);
+  ASSERT_TRUE(browser);
+  const TabStripModel* tabs = browser->tab_strip_model();
+  ASSERT_TRUE(tabs);
+  ASSERT_EQ(2, tabs->count());
+  EXPECT_EQ(GURL(kStartUpURL1), tabs->GetWebContentsAt(0)->GetURL());
+  EXPECT_EQ(GURL(kStartUpURL2), tabs->GetWebContentsAt(1)->GetURL());
+}
+
+// Verify that the policies are honored on a new user's login.
+IN_PROC_BROWSER_TEST_F(RestoreOnStartupTestChromeOS, PRE_LogInAndVerify) {
+  SkipToLoginScreen();
+  LogInAndVerifyStartUpURLs();
+}
+
+// Verify that the policies are honored on an existing user's login.
+IN_PROC_BROWSER_TEST_F(RestoreOnStartupTestChromeOS, LogInAndVerify) {
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
+      content::NotificationService::AllSources()).Wait();
+  LogInAndVerifyStartUpURLs();
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_uploader_unittest.cc b/chrome/browser/chromeos/policy/status_uploader_unittest.cc
index 4ef34eb..13a033c 100644
--- a/chrome/browser/chromeos/policy/status_uploader_unittest.cc
+++ b/chrome/browser/chromeos/policy/status_uploader_unittest.cc
@@ -7,8 +7,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/policy/device_status_collector.h"
 #include "chrome/browser/chromeos/policy/status_uploader.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/policy/core/common/cloud/cloud_policy_client.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
@@ -46,35 +45,18 @@
 namespace policy {
 class StatusUploaderTest : public testing::Test {
  public:
-  StatusUploaderTest()
-      : task_runner_(new base::TestSimpleTaskRunner()),
-        device_settings_provider_(nullptr) {
+  StatusUploaderTest() : task_runner_(new base::TestSimpleTaskRunner()) {
     DeviceStatusCollector::RegisterPrefs(prefs_.registry());
   }
 
   void SetUp() override {
     client_.SetDMToken("dm_token");
     collector_.reset(new MockDeviceStatusCollector(&prefs_));
-
-    // Swap out the DeviceSettingsProvider with our stub settings provider
-    // so we can set values for the upload frequency.
-    chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
-    device_settings_provider_ =
-        cros_settings->GetProvider(chromeos::kReportDeviceVersionInfo);
-    EXPECT_TRUE(device_settings_provider_);
-    EXPECT_TRUE(
-        cros_settings->RemoveSettingsProvider(device_settings_provider_));
-    cros_settings->AddSettingsProvider(&stub_settings_provider_);
-
+    settings_helper_.ReplaceProvider(chromeos::kReportUploadFrequency);
   }
 
   void TearDown() override {
     content::RunAllBlockingPoolTasksUntilIdle();
-    // Restore the real DeviceSettingsProvider.
-    chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
-    EXPECT_TRUE(cros_settings->RemoveSettingsProvider(
-        &stub_settings_provider_));
-    cros_settings->AddSettingsProvider(device_settings_provider_);
   }
 
   // Given a pending task to upload status, mocks out a server response.
@@ -114,11 +96,8 @@
 
   base::MessageLoop loop_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
-  chromeos::ScopedTestCrosSettings test_cros_settings_;
+  chromeos::ScopedCrosSettingsTestHelper settings_helper_;
   scoped_ptr<MockDeviceStatusCollector> collector_;
-  chromeos::CrosSettingsProvider* device_settings_provider_;
-  chromeos::StubCrosSettingsProvider stub_settings_provider_;
   MockCloudPolicyClient client_;
   MockDeviceManagementService device_management_service_;
   TestingPrefServiceSimple prefs_;
@@ -137,8 +116,7 @@
   // when it is passed to the StatusUploader constructor below.
   MockDeviceStatusCollector* const mock_collector = collector_.get();
   const int new_delay = StatusUploader::kDefaultUploadDelayMs * 2;
-  chromeos::CrosSettings::Get()->SetInteger(chromeos::kReportUploadFrequency,
-                                            new_delay);
+  settings_helper_.SetInteger(chromeos::kReportUploadFrequency, new_delay);
   const base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(
       new_delay);
   EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
@@ -202,8 +180,7 @@
   // Change the frequency. The new frequency should be reflected in the timing
   // used for the next callback.
   const int new_delay = StatusUploader::kDefaultUploadDelayMs * 2;
-  chromeos::CrosSettings::Get()->SetInteger(chromeos::kReportUploadFrequency,
-                                            new_delay);
+  settings_helper_.SetInteger(chromeos::kReportUploadFrequency, new_delay);
   const base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(
       new_delay);
   RunPendingUploadTaskAndCheckNext(uploader, expected_delay);
diff --git a/chrome/browser/chromeos/power/cpu_data_collector.cc b/chrome/browser/chromeos/power/cpu_data_collector.cc
index 5b30252..bc43420 100644
--- a/chrome/browser/chromeos/power/cpu_data_collector.cc
+++ b/chrome/browser/chromeos/power/cpu_data_collector.cc
@@ -382,7 +382,7 @@
     const std::vector<CpuDataCollector::StateOccupancySample>* idle_samples,
     const std::vector<std::string>* cpu_freq_state_names,
     const std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   cpu_count_ = *cpu_count;
 
diff --git a/chrome/browser/chromeos/power/peripheral_battery_observer.cc b/chrome/browser/chromeos/power/peripheral_battery_observer.cc
index 91cedf6c..a36a5edc73 100644
--- a/chrome/browser/chromeos/power/peripheral_battery_observer.cc
+++ b/chrome/browser/chromeos/power/peripheral_battery_observer.cc
@@ -107,7 +107,7 @@
     const std::string& path,
     const std::string& name,
     int level) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   std::string address;
   if (IsBluetoothHIDBattery(path)) {
     // For HID bluetooth device, device address is used as key to index
@@ -178,7 +178,7 @@
 }
 
 void PeripheralBatteryObserver::RemoveBattery(const std::string& address) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   std::string address_lowercase = address;
   base::StringToLowerASCII(&address_lowercase);
   std::map<std::string, BatteryInfo>::iterator it =
diff --git a/chrome/browser/chromeos/set_time_dialog.cc b/chrome/browser/chromeos/set_time_dialog.cc
index d561f34..62ceebb 100644
--- a/chrome/browser/chromeos/set_time_dialog.cc
+++ b/chrome/browser/chromeos/set_time_dialog.cc
@@ -66,8 +66,7 @@
 
 void SetTimeDialog::OnCloseContents(WebContents* source,
                                     bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool SetTimeDialog::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/chromeos/settings/cros_settings_unittest.cc b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
index b0714f0..45ebe62 100644
--- a/chrome/browser/chromeos/settings/cros_settings_unittest.cc
+++ b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
@@ -43,7 +43,7 @@
   }
 
   void FetchPref(const std::string& pref) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     if (expected_props_.find(pref) == expected_props_.end())
       return;
 
@@ -65,7 +65,7 @@
   }
 
   void SetPref(const std::string& pref_name, const base::Value* value) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     settings_.Set(pref_name, *value);
   }
 
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service_factory.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service_factory.cc
index 8cc8746..65e319c 100644
--- a/chrome/browser/chromeos/settings/device_oauth2_token_service_factory.cc
+++ b/chrome/browser/chromeos/settings/device_oauth2_token_service_factory.cc
@@ -20,13 +20,13 @@
 
 // static
 DeviceOAuth2TokenService* DeviceOAuth2TokenServiceFactory::Get() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   return g_device_oauth2_token_service_;
 }
 
 // static
 void DeviceOAuth2TokenServiceFactory::Initialize() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(!g_device_oauth2_token_service_);
   g_device_oauth2_token_service_ = new DeviceOAuth2TokenService(
       g_browser_process->system_request_context(),
@@ -35,7 +35,7 @@
 
 // static
 void DeviceOAuth2TokenServiceFactory::Shutdown() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (g_device_oauth2_token_service_) {
     delete g_device_oauth2_token_service_;
     g_device_oauth2_token_service_ = NULL;
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc
index a33b23f9..05fe7685 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -56,10 +56,14 @@
     kAllowedConnectionTypesForUpdate,
     kAttestationForContentProtectionEnabled,
     kDeviceAttestationEnabled,
+    kDeviceDisabled,
+    kDeviceDisabledMessage,
     kDeviceOwner,
+    kExtensionCacheSize,
     kHeartbeatEnabled,
     kHeartbeatFrequency,
     kPolicyMissingMitigationMode,
+    kRebootOnShutdown,
     kReleaseChannel,
     kReleaseChannelDelegated,
     kReportDeviceActivityTimes,
@@ -79,10 +83,6 @@
     kSystemUse24HourClock,
     kUpdateDisabled,
     kVariationsRestrictParameter,
-    kDeviceDisabled,
-    kDeviceDisabledMessage,
-    kRebootOnShutdown,
-    kExtensionCacheSize,
 };
 
 bool HasOldMetricsFile() {
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h
index 0e5742e..0736342 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.h
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -19,7 +19,6 @@
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "components/ownership/mock_owner_key_util.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc
new file mode 100644
index 0000000..bcbb947e9
--- /dev/null
+++ b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
+
+#include "base/logging.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.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/cros_settings.h"
+#include "chrome/browser/chromeos/settings/device_settings_cache.h"
+#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/ownership/mock_owner_key_util.h"
+#include "policy/proto/device_management_backend.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+ScopedCrosSettingsTestHelper::ScopedCrosSettingsTestHelper() {
+  Initialize(true);
+}
+
+ScopedCrosSettingsTestHelper::ScopedCrosSettingsTestHelper(
+    bool create_settings_service) {
+  Initialize(create_settings_service);
+}
+
+ScopedCrosSettingsTestHelper::~ScopedCrosSettingsTestHelper() {
+  RestoreProvider();
+}
+
+scoped_ptr<FakeOwnerSettingsService>
+ScopedCrosSettingsTestHelper::CreateOwnerSettingsService(Profile* profile) {
+  return make_scoped_ptr(new FakeOwnerSettingsService(
+      profile, new ownership::MockOwnerKeyUtil(), &stub_settings_provider_));
+}
+
+void ScopedCrosSettingsTestHelper::ReplaceProvider(const std::string& path) {
+  CHECK(!real_settings_provider_);
+  // Swap out the DeviceSettingsProvider with our settings provider so we can
+  // set values for the specified path.
+  CrosSettings* const cros_settings = CrosSettings::Get();
+  real_settings_provider_ = cros_settings->GetProvider(path);
+  EXPECT_TRUE(real_settings_provider_);
+  EXPECT_TRUE(cros_settings->RemoveSettingsProvider(real_settings_provider_));
+  cros_settings->AddSettingsProvider(&stub_settings_provider_);
+}
+
+void ScopedCrosSettingsTestHelper::RestoreProvider() {
+  if (real_settings_provider_) {
+    // Restore the real DeviceSettingsProvider.
+    CrosSettings* const cros_settings = CrosSettings::Get();
+    EXPECT_TRUE(
+        cros_settings->RemoveSettingsProvider(&stub_settings_provider_));
+    cros_settings->AddSettingsProvider(real_settings_provider_);
+    real_settings_provider_ = nullptr;
+  }
+}
+
+void ScopedCrosSettingsTestHelper::SetTrustedStatus(
+    CrosSettingsProvider::TrustedStatus status) {
+  stub_settings_provider_.SetTrustedStatus(status);
+}
+
+void ScopedCrosSettingsTestHelper::SetCurrentUserIsOwner(bool owner) {
+  stub_settings_provider_.SetCurrentUserIsOwner(owner);
+}
+
+void ScopedCrosSettingsTestHelper::Set(const std::string& path,
+                                       const base::Value& in_value) {
+  stub_settings_provider_.Set(path, in_value);
+}
+
+void ScopedCrosSettingsTestHelper::SetBoolean(const std::string& path,
+                                              bool in_value) {
+  Set(path, base::FundamentalValue(in_value));
+}
+
+void ScopedCrosSettingsTestHelper::SetInteger(const std::string& path,
+                                              int in_value) {
+  Set(path, base::FundamentalValue(in_value));
+}
+
+void ScopedCrosSettingsTestHelper::SetDouble(const std::string& path,
+                                             double in_value) {
+  Set(path, base::FundamentalValue(in_value));
+}
+
+void ScopedCrosSettingsTestHelper::SetString(const std::string& path,
+                                             const std::string& in_value) {
+  Set(path, base::StringValue(in_value));
+}
+
+void ScopedCrosSettingsTestHelper::StoreCachedDeviceSetting(
+    const std::string& path) {
+  const base::Value* const value = stub_settings_provider_.Get(path);
+  if (value) {
+    enterprise_management::PolicyData data;
+    enterprise_management::ChromeDeviceSettingsProto settings;
+    if (device_settings_cache::Retrieve(&data,
+                                        g_browser_process->local_state())) {
+      CHECK(settings.ParseFromString(data.policy_value()));
+    }
+    OwnerSettingsServiceChromeOS::UpdateDeviceSettings(path, *value, settings);
+    CHECK(settings.SerializeToString(data.mutable_policy_value()));
+    CHECK(device_settings_cache::Store(data, g_browser_process->local_state()));
+  }
+}
+
+void ScopedCrosSettingsTestHelper::CopyStoredValue(const std::string& path) {
+  CrosSettingsProvider* provider = real_settings_provider_
+                                       ? real_settings_provider_
+                                       : CrosSettings::Get()->GetProvider(path);
+  const base::Value* const value = provider->Get(path);
+  if (value) {
+    stub_settings_provider_.Set(path, *value);
+  }
+}
+
+void ScopedCrosSettingsTestHelper::Initialize(bool create_settings_service) {
+  if (create_settings_service) {
+    CHECK(!DeviceSettingsService::IsInitialized());
+    test_device_settings_service_.reset(new ScopedTestDeviceSettingsService());
+    test_cros_settings_.reset(new ScopedTestCrosSettings());
+  }
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h
new file mode 100644
index 0000000..86a07bd
--- /dev/null
+++ b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h
@@ -0,0 +1,83 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_SCOPED_CROS_SETTINGS_TEST_HELPER_H_
+#define CHROME_BROWSER_CHROMEOS_SETTINGS_SCOPED_CROS_SETTINGS_TEST_HELPER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chromeos/settings/cros_settings_provider.h"
+
+class Profile;
+
+namespace base {
+class Value;
+}
+
+namespace chromeos {
+
+class FakeOwnerSettingsService;
+class ScopedTestCrosSettings;
+class ScopedTestDeviceSettingsService;
+
+class ScopedCrosSettingsTestHelper {
+ public:
+  ScopedCrosSettingsTestHelper();
+
+  // In some cases it is required to pass |create_settings_service| as false:
+  // If the test already has a device settings service and/or CrosSettings set
+  // up by another (instantiated or base) class, creating another one causes
+  // crash.
+  explicit ScopedCrosSettingsTestHelper(bool create_settings_service);
+  ~ScopedCrosSettingsTestHelper();
+
+  // Methods to replace and restore CrosSettingsProvider for the specified
+  // |path|.
+  void ReplaceProvider(const std::string& path);
+  void RestoreProvider();
+
+  // Method to create an owner settings service that uses
+  // |stub_settings_provider_| as settings write path.
+  scoped_ptr<FakeOwnerSettingsService> CreateOwnerSettingsService(
+      Profile* profile);
+
+  // These methods simply call the according |stub_settings_provider_| method.
+  void SetTrustedStatus(CrosSettingsProvider::TrustedStatus status);
+  void SetCurrentUserIsOwner(bool owner);
+  void Set(const std::string& path, const base::Value& in_value);
+
+  // Convenience forms of Set() from CrosSettingsProvider. These methods will
+  // replace any existing value at that |path|, even if it has a different type.
+  void SetBoolean(const std::string& path, bool in_value);
+  void SetInteger(const std::string& path, int in_value);
+  void SetDouble(const std::string& path, double in_value);
+  void SetString(const std::string& path, const std::string& in_value);
+
+  // This may be called before |ReplaceProvider| to copy values currently stored
+  // in the old provider. If the method is called after |ReplaceProvider|, then
+  // the value is retreived from |real_settings_provider_| for any |path|.
+  void CopyStoredValue(const std::string& path);
+
+  // Write the setting from |path| to local state so that it can be retreived
+  // later on browser test startup by the device settings service.
+  void StoreCachedDeviceSetting(const std::string& path);
+
+ private:
+  // Helpers used to mock out cros settings.
+  scoped_ptr<ScopedTestDeviceSettingsService> test_device_settings_service_;
+  scoped_ptr<ScopedTestCrosSettings> test_cros_settings_;
+  CrosSettingsProvider* real_settings_provider_ = nullptr;
+  StubCrosSettingsProvider stub_settings_provider_;
+
+  void Initialize(bool create_settings_service);
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedCrosSettingsTestHelper);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_SETTINGS_SCOPED_CROS_SETTINGS_TEST_HELPER_H_
diff --git a/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc b/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc
index eadd410..8b9669f9 100644
--- a/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc
+++ b/chrome/browser/chromeos/settings/shutdown_policy_handler_unittest.cc
@@ -6,15 +6,10 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/run_loop.h"
-#include "base/values.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chromeos/chromeos_switches.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/settings/cros_settings_names.h"
-#include "chromeos/settings/cros_settings_provider.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -30,29 +25,21 @@
 
  protected:
   ShutdownPolicyHandlerTest()
-      : cros_settings_(nullptr),
-        callback_called_(false),
+      : callback_called_(false),
         reboot_on_shutdown_(false),
-        delegate_invocations_count_(0) {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kStubCrosSettings);
-    test_cros_settings_.reset(new ScopedTestCrosSettings);
-}
+        delegate_invocations_count_(0) {}
 
   // testing::Test:
-void SetUp() override {
+  void SetUp() override {
     testing::Test::SetUp();
-    cros_settings_ = CrosSettings::Get();
     DBusThreadManager::Initialize();
+    settings_helper_.ReplaceProvider(kRebootOnShutdown);
   }
 
   void TearDown() override { DBusThreadManager::Shutdown(); }
 
   void SetRebootOnShutdown(bool reboot_on_shutdown) {
-    const base::FundamentalValue reboot_on_shutdown_value(reboot_on_shutdown);
-    CrosSettings::Get()
-        ->GetProvider(kRebootOnShutdown)
-        ->Set(kRebootOnShutdown, reboot_on_shutdown_value);
+    settings_helper_.SetBoolean(kRebootOnShutdown, reboot_on_shutdown);
     base::RunLoop().RunUntilIdle();
   }
 
@@ -64,20 +51,14 @@
 
  protected:
   content::TestBrowserThreadBundle thread_bundle_;
-
-  CrosSettings* cros_settings_;
-  scoped_ptr<CrosSettingsProvider> device_settings_provider_;
-
-  ScopedTestDeviceSettingsService test_device_settings_service_;
-  scoped_ptr<ScopedTestCrosSettings> test_cros_settings_;
-
+  ScopedCrosSettingsTestHelper settings_helper_;
   bool callback_called_;
   bool reboot_on_shutdown_;
   int delegate_invocations_count_;
 };
 
 TEST_F(ShutdownPolicyHandlerTest, RetrieveTrustedDevicePolicies) {
-  ShutdownPolicyHandler shutdown_policy_observer(cros_settings_, this);
+  ShutdownPolicyHandler shutdown_policy_observer(CrosSettings::Get(), this);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, delegate_invocations_count_);
 
@@ -100,7 +81,7 @@
 }
 
 TEST_F(ShutdownPolicyHandlerTest, CheckIfRebootOnShutdown) {
-  ShutdownPolicyHandler shutdown_policy_observer(cros_settings_, this);
+  ShutdownPolicyHandler shutdown_policy_observer(CrosSettings::Get(), this);
   base::RunLoop().RunUntilIdle();
 
   // Allow shutdown.
diff --git a/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc b/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
index c11e3c30..3b6a89a2 100644
--- a/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
@@ -37,17 +37,27 @@
 
 CrosSettingsProvider::TrustedStatus
     StubCrosSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
-  // We don't have a trusted store so all values are available immediately.
-  return TRUSTED;
+  return trusted_status_;
 }
 
 bool StubCrosSettingsProvider::HandlesSetting(const std::string& path) const {
   return DeviceSettingsProvider::IsDeviceSetting(path);
 }
 
+void StubCrosSettingsProvider::SetTrustedStatus(TrustedStatus status) {
+  trusted_status_ = status;
+}
+
+void StubCrosSettingsProvider::SetCurrentUserIsOwner(bool owner) {
+  current_user_is_owner_ = owner;
+}
+
 void StubCrosSettingsProvider::DoSet(const std::string& path,
                                      const base::Value& value) {
-  values_.SetValue(path, value.DeepCopy());
+  if (current_user_is_owner_)
+    values_.SetValue(path, value.DeepCopy());
+  else
+    LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
   NotifyObservers(path);
 }
 
diff --git a/chrome/browser/chromeos/settings/stub_cros_settings_provider.h b/chrome/browser/chromeos/settings/stub_cros_settings_provider.h
index 5fcb65c1..4d54a3e 100644
--- a/chrome/browser/chromeos/settings/stub_cros_settings_provider.h
+++ b/chrome/browser/chromeos/settings/stub_cros_settings_provider.h
@@ -24,6 +24,9 @@
   TrustedStatus PrepareTrustedValues(const base::Closure& callback) override;
   bool HandlesSetting(const std::string& path) const override;
 
+  void SetTrustedStatus(TrustedStatus status);
+  void SetCurrentUserIsOwner(bool owner);
+
  private:
   // CrosSettingsProvider implementation:
   void DoSet(const std::string& path, const base::Value& value) override;
@@ -34,6 +37,14 @@
   // In-memory settings storage.
   PrefValueMap values_;
 
+  // Some tests imply that calling Set() as non-owner doesn't change the actual
+  // value but still trigger a notification. For such cases, it is possible to
+  // emulate this behavior by changing the ownership status to non-owner with
+  // |SetCurrentUserIsOwner(false)|.
+  bool current_user_is_owner_ = true;
+
+  TrustedStatus trusted_status_ = CrosSettingsProvider::TRUSTED;
+
   DISALLOW_COPY_AND_ASSIGN(StubCrosSettingsProvider);
 };
 
diff --git a/chrome/browser/chromeos/sim_dialog_delegate.cc b/chrome/browser/chromeos/sim_dialog_delegate.cc
index 4321b1c8..babd901 100644
--- a/chrome/browser/chromeos/sim_dialog_delegate.cc
+++ b/chrome/browser/chromeos/sim_dialog_delegate.cc
@@ -101,8 +101,7 @@
 
 void SimDialogDelegate::OnCloseContents(WebContents* source,
                                         bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool SimDialogDelegate::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/chromeos/system/device_disabling_browsertest.cc b/chrome/browser/chromeos/system/device_disabling_browsertest.cc
index 1470800..62e4cb8d 100644
--- a/chrome/browser/chromeos/system/device_disabling_browsertest.cc
+++ b/chrome/browser/chromeos/system/device_disabling_browsertest.cc
@@ -48,9 +48,12 @@
 
 }  // namespace
 
+// Boolean parameter is used to run this test for webview (true) and for
+// iframe (false) GAIA sign in.
 class DeviceDisablingTest
     : public OobeBaseTest,
-      public NetworkStateInformer::NetworkStateInformerObserver {
+      public NetworkStateInformer::NetworkStateInformerObserver,
+      public testing::WithParamInterface<bool> {
  public:
   DeviceDisablingTest();
 
@@ -80,6 +83,7 @@
 
 DeviceDisablingTest::DeviceDisablingTest()
     : fake_session_manager_client_(new FakeSessionManagerClient) {
+  set_use_webview(GetParam());
 }
 
 void DeviceDisablingTest::MarkDisabledAndWaitForPolicyFetch() {
@@ -135,8 +139,7 @@
   network_state_change_wait_run_loop_.Quit();
 }
 
-
-IN_PROC_BROWSER_TEST_F(DeviceDisablingTest, DisableDuringNormalOperation) {
+IN_PROC_BROWSER_TEST_P(DeviceDisablingTest, DisableDuringNormalOperation) {
   // Mark the device as disabled and wait until cros settings update.
   MarkDisabledAndWaitForPolicyFetch();
 
@@ -155,7 +158,7 @@
 // causes the UI to try and show the login screen after some delay. It must
 // be ensured that the login screen does not show and does not clobber the
 // disabled screen.
-IN_PROC_BROWSER_TEST_F(DeviceDisablingTest, DisableWithEphemeralUsers) {
+IN_PROC_BROWSER_TEST_P(DeviceDisablingTest, DisableWithEphemeralUsers) {
   // Connect to the fake Ethernet network. This ensures that Chrome OS will not
   // try to show the offline error screen.
   base::RunLoop connect_run_loop;
@@ -219,5 +222,9 @@
   EXPECT_EQ(OobeUI::kScreenDeviceDisabled, GetCurrentScreenName(web_contents));
 }
 
+INSTANTIATE_TEST_CASE_P(DeviceDisablingSuite,
+                        DeviceDisablingTest,
+                        testing::Bool());
+
 }  // namespace system
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc b/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc
index 60791f94..b9e92df6 100644
--- a/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc
+++ b/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc
@@ -60,7 +60,7 @@
 
 void InputDeviceSettingsImplOzone::TouchpadExists(
     const DeviceExistsCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   callback.Run(input_controller_->HasTouchpad());
 }
 
@@ -99,7 +99,7 @@
 
 void InputDeviceSettingsImplOzone::MouseExists(
     const DeviceExistsCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   callback.Run(input_controller_->HasMouse());
 }
 
diff --git a/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc b/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc
index aa41497a..17c06499 100644
--- a/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc
+++ b/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc
@@ -62,7 +62,7 @@
 }
 
 void ExecuteScript(const std::vector<std::string>& argv) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (argv.size() == 1)
     return;
@@ -115,14 +115,14 @@
 void RunCallbackUIThread(
     scoped_refptr<RefCountedBool> exists,
     const InputDeviceSettings::DeviceExistsCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DVLOG(1) << "RunCallbackUIThread " << exists->data;
   callback.Run(exists->data);
 }
 
 void DeviceExists(const char* script,
                   const InputDeviceSettings::DeviceExistsCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // One or both of the control scripts can apparently hang during shutdown
   // (http://crbug.com/255546). Run the blocking pool task with
diff --git a/chrome/browser/chromeos/system_logs/dbus_log_source.cc b/chrome/browser/chromeos/system_logs/dbus_log_source.cc
index f7b4e68..7f3b4fc 100644
--- a/chrome/browser/chromeos/system_logs/dbus_log_source.cc
+++ b/chrome/browser/chromeos/system_logs/dbus_log_source.cc
@@ -19,7 +19,7 @@
 }
 
 void DBusLogSource::Fetch(const SysLogsSourceCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(!callback.is_null());
 
   SystemLogsResponse response;
diff --git a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc
index d1780f92..263d03cb 100644
--- a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc
+++ b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc
@@ -39,7 +39,7 @@
 DebugDaemonLogSource::~DebugDaemonLogSource() {}
 
 void DebugDaemonLogSource::Fetch(const SysLogsSourceCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(!callback.is_null());
   DCHECK(callback_.is_null());
 
@@ -77,7 +77,7 @@
 
 void DebugDaemonLogSource::OnGetRoutes(bool succeeded,
                                        const std::vector<std::string>& routes) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (succeeded)
     (*response_)[kRoutesKeyName] = JoinString(routes, '\n');
@@ -88,7 +88,7 @@
 
 void DebugDaemonLogSource::OnGetNetworkStatus(bool succeeded,
                                               const std::string& status) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (succeeded)
     (*response_)[kNetworkStatusKeyName] = status;
diff --git a/chrome/browser/chromeos/system_logs/device_event_log_source.cc b/chrome/browser/chromeos/system_logs/device_event_log_source.cc
index 0fb8a01..30e57a2c 100644
--- a/chrome/browser/chromeos/system_logs/device_event_log_source.cc
+++ b/chrome/browser/chromeos/system_logs/device_event_log_source.cc
@@ -20,7 +20,7 @@
 }
 
 void DeviceEventLogSource::Fetch(const SysLogsSourceCallback& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(!callback.is_null());
 
   scoped_ptr<SystemLogsResponse> response(new SystemLogsResponse);
diff --git a/chrome/browser/chromeos/ui/choose_mobile_network_dialog.cc b/chrome/browser/chromeos/ui/choose_mobile_network_dialog.cc
index 43e4b5c..0da2c869 100644
--- a/chrome/browser/chromeos/ui/choose_mobile_network_dialog.cc
+++ b/chrome/browser/chromeos/ui/choose_mobile_network_dialog.cc
@@ -62,8 +62,7 @@
 
 void ChooseMobileNetworkDialog::OnCloseContents(WebContents* source,
                                                 bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool ChooseMobileNetworkDialog::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/chromeos/ui/inline_login_dialog.cc b/chrome/browser/chromeos/ui/inline_login_dialog.cc
index b60b32e..35548a1 100644
--- a/chrome/browser/chromeos/ui/inline_login_dialog.cc
+++ b/chrome/browser/chromeos/ui/inline_login_dialog.cc
@@ -71,8 +71,7 @@
 
 void InlineLoginDialog::OnCloseContents(content::WebContents* source,
                                         bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool InlineLoginDialog::ShouldShowDialogTitle() const {
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 dc14204..6247af2 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -965,6 +965,7 @@
                   prefs, CONTENT_SETTING_ASK,
                   CONTENT_SETTINGS_TYPE_FULLSCREEN));
 
+  // The mediastream setting is deprecated.
   EXPECT_FALSE(HostContentSettingsMap::IsSettingAllowedForType(
                    prefs, CONTENT_SETTING_ALLOW,
                    CONTENT_SETTINGS_TYPE_MEDIASTREAM));
@@ -975,6 +976,21 @@
                    prefs, CONTENT_SETTING_BLOCK,
                    CONTENT_SETTINGS_TYPE_MEDIASTREAM));
 
+  // We support the ALLOW value for media permission exceptions,
+  // but not as the default setting.
+  EXPECT_TRUE(HostContentSettingsMap::IsSettingAllowedForType(
+                  prefs, CONTENT_SETTING_ALLOW,
+                  CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC));
+  EXPECT_TRUE(HostContentSettingsMap::IsSettingAllowedForType(
+                  prefs, CONTENT_SETTING_ALLOW,
+                  CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA));
+  EXPECT_FALSE(HostContentSettingsMap::IsDefaultSettingAllowedForType(
+                   prefs, CONTENT_SETTING_ALLOW,
+                   CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC));
+  EXPECT_FALSE(HostContentSettingsMap::IsDefaultSettingAllowedForType(
+                   prefs, CONTENT_SETTING_ALLOW,
+                   CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA));
+
   // TODO(msramek): Add more checks for setting type - setting pairs where
   // it is not obvious whether or not they are allowed.
 }
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index 99bfd7cf2..88a20e35 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -115,19 +115,19 @@
 
 bool ProtocolHandlerRegistry::IOThreadDelegate::IsHandledProtocol(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   return enabled_ && !LookupHandler(default_handlers_, scheme).IsEmpty();
 }
 
 void ProtocolHandlerRegistry::IOThreadDelegate::ClearDefault(
     const std::string& scheme) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   default_handlers_.erase(scheme);
 }
 
 void ProtocolHandlerRegistry::IOThreadDelegate::SetDefault(
     const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   ClearDefault(handler.protocol());
   default_handlers_.insert(std::make_pair(handler.protocol(), handler));
 }
@@ -137,7 +137,7 @@
 // the url from |request|.
 net::URLRequestJob* ProtocolHandlerRegistry::IOThreadDelegate::MaybeCreateJob(
     net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   ProtocolHandler handler = LookupHandler(default_handlers_,
                                           request->url().scheme());
@@ -181,7 +181,7 @@
     const std::string& scheme,
     net::URLRequest* request,
     net::NetworkDelegate* network_delegate) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   net::URLRequestJob* job = io_thread_delegate_->MaybeCreateJob(
       request, network_delegate);
   if (job)
@@ -208,14 +208,14 @@
 
 bool ProtocolHandlerRegistry::JobInterceptorFactory::IsHandledProtocol(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   return io_thread_delegate_->IsHandledProtocol(scheme) ||
       job_factory_->IsHandledProtocol(scheme);
 }
 
 bool ProtocolHandlerRegistry::JobInterceptorFactory::IsHandledURL(
     const GURL& url) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   return (url.is_valid() &&
       io_thread_delegate_->IsHandledProtocol(url.scheme())) ||
       job_factory_->IsHandledURL(url);
@@ -223,7 +223,7 @@
 
 bool ProtocolHandlerRegistry::JobInterceptorFactory::IsSafeRedirectTarget(
     const GURL& location) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   return job_factory_->IsSafeRedirectTarget(location);
 }
 
@@ -350,7 +350,7 @@
 
 void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
     const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   RegisterProtocolHandler(handler, USER);
   SetDefault(handler);
   Save();
@@ -359,7 +359,7 @@
 
 void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
     const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   RegisterProtocolHandler(handler, USER);
   Save();
   NotifyChanged();
@@ -367,14 +367,14 @@
 
 void ProtocolHandlerRegistry::OnIgnoreRegisterProtocolHandler(
     const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   IgnoreProtocolHandler(handler, USER);
   Save();
   NotifyChanged();
 }
 
 bool ProtocolHandlerRegistry::AttemptReplace(const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandler old_default = GetHandlerFor(handler.protocol());
   bool make_new_handler_default = handler.IsSameOrigin(old_default);
   ProtocolHandlerList to_replace(GetReplacedHandlers(handler));
@@ -410,7 +410,7 @@
 }
 
 void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   default_handlers_.erase(scheme);
   BrowserThread::PostTask(
@@ -423,7 +423,7 @@
 
 bool ProtocolHandlerRegistry::IsDefault(
     const ProtocolHandler& handler) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return GetHandlerFor(handler.protocol()) == handler;
 }
 
@@ -444,7 +444,7 @@
 }
 
 void ProtocolHandlerRegistry::InitProtocolSettings() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Any further default additions to the table will get rejected from now on.
   is_loaded_ = true;
@@ -484,7 +484,7 @@
 }
 
 int ProtocolHandlerRegistry::GetHandlerIndex(const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const ProtocolHandler& handler = GetHandlerFor(scheme);
   if (handler.IsEmpty())
     return -1;
@@ -504,7 +504,7 @@
 ProtocolHandlerRegistry::ProtocolHandlerList
 ProtocolHandlerRegistry::GetHandlersFor(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme);
   if (p == protocol_handlers_.end()) {
     return ProtocolHandlerList();
@@ -519,7 +519,7 @@
 
 void ProtocolHandlerRegistry::GetRegisteredProtocols(
     std::vector<std::string>* output) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerMultiMap::const_iterator p;
   for (p = protocol_handlers_.begin(); p != protocol_handlers_.end(); ++p) {
     if (!p->second.empty())
@@ -529,7 +529,7 @@
 
 bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const ProtocolHandlerList* handlers = GetHandlerList(scheme);
   // If we already have a handler for this scheme, we can add more.
   if (handlers != NULL && !handlers->empty())
@@ -540,7 +540,7 @@
 
 bool ProtocolHandlerRegistry::IsRegistered(
     const ProtocolHandler& handler) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol());
   if (!handlers) {
     return false;
@@ -561,7 +561,7 @@
 }
 
 bool ProtocolHandlerRegistry::IsIgnored(const ProtocolHandler& handler) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerList::const_iterator i;
   for (i = ignored_protocol_handlers_.begin();
        i != ignored_protocol_handlers_.end(); ++i) {
@@ -574,7 +574,7 @@
 
 bool ProtocolHandlerRegistry::HasRegisteredEquivalent(
     const ProtocolHandler& handler) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol());
   if (!handlers) {
     return false;
@@ -590,7 +590,7 @@
 
 bool ProtocolHandlerRegistry::HasIgnoredEquivalent(
     const ProtocolHandler& handler) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerList::const_iterator i;
   for (i = ignored_protocol_handlers_.begin();
        i != ignored_protocol_handlers_.end(); ++i) {
@@ -603,7 +603,7 @@
 
 void ProtocolHandlerRegistry::RemoveIgnoredHandler(
     const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   bool should_notify = false;
   if (HandlerExists(handler, ignored_protocol_handlers_) &&
       HandlerExists(handler, user_ignored_protocol_handlers_)) {
@@ -620,13 +620,13 @@
 
 bool ProtocolHandlerRegistry::IsHandledProtocol(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return enabled_ && !GetHandlerFor(scheme).IsEmpty();
 }
 
 void ProtocolHandlerRegistry::RemoveHandler(
     const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerList& handlers = protocol_handlers_[handler.protocol()];
   bool erase_success = false;
   if (HandlerExists(handler, handlers) &&
@@ -661,7 +661,7 @@
 }
 
 void ProtocolHandlerRegistry::RemoveDefaultHandler(const std::string& scheme) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandler current_default = GetHandlerFor(scheme);
   if (!current_default.IsEmpty())
     RemoveHandler(current_default);
@@ -669,12 +669,12 @@
 
 const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return LookupHandler(default_handlers_, scheme);
 }
 
 void ProtocolHandlerRegistry::Enable() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (enabled_) {
     return;
   }
@@ -693,7 +693,7 @@
 }
 
 void ProtocolHandlerRegistry::Disable() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!enabled_) {
     return;
   }
@@ -712,7 +712,7 @@
 }
 
 void ProtocolHandlerRegistry::Shutdown() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   delegate_.reset(NULL);
   // We free these now in case there are any outstanding workers running. If
   // we didn't free them they could respond to workers and try to update the
@@ -742,12 +742,12 @@
 }
 
 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(default_client_observers_.empty());
 }
 
 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(IsRegistered(handler));
   ProtocolHandlerMultiMap::iterator p =
       protocol_handlers_.find(handler.protocol());
@@ -757,7 +757,7 @@
 }
 
 void ProtocolHandlerRegistry::Save() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (is_loading_) {
     return;
   }
@@ -776,7 +776,7 @@
 const ProtocolHandlerRegistry::ProtocolHandlerList*
 ProtocolHandlerRegistry::GetHandlerList(
     const std::string& scheme) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme);
   if (p == protocol_handlers_.end()) {
     return NULL;
@@ -785,7 +785,7 @@
 }
 
 void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerMap::const_iterator p = default_handlers_.find(
       handler.protocol());
   // If we're not loading, and we are setting a default for a new protocol,
@@ -802,7 +802,7 @@
 }
 
 void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerMultiMap::iterator p =
       protocol_handlers_.find(handler.protocol());
 
@@ -817,7 +817,7 @@
 }
 
 base::Value* ProtocolHandlerRegistry::EncodeRegisteredHandlers() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::ListValue* protocol_handlers = new base::ListValue();
   for (ProtocolHandlerMultiMap::iterator i = user_protocol_handlers_.begin();
        i != user_protocol_handlers_.end();
@@ -835,7 +835,7 @@
 }
 
 base::Value* ProtocolHandlerRegistry::EncodeIgnoredHandlers() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::ListValue* handlers = new base::ListValue();
   for (ProtocolHandlerList::iterator i =
            user_ignored_protocol_handlers_.begin();
@@ -847,7 +847,7 @@
 }
 
 void ProtocolHandlerRegistry::NotifyChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
       content::Source<content::BrowserContext>(context_),
@@ -857,7 +857,7 @@
 void ProtocolHandlerRegistry::RegisterProtocolHandler(
     const ProtocolHandler& handler,
     const HandlerSource source) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(CanSchemeBeOverridden(handler.protocol()));
   DCHECK(!handler.IsEmpty());
   ProtocolHandlerMultiMap& map =
@@ -875,7 +875,7 @@
 
 std::vector<const base::DictionaryValue*>
 ProtocolHandlerRegistry::GetHandlersFromPref(const char* pref_name) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::vector<const base::DictionaryValue*> result;
   PrefService* prefs = user_prefs::UserPrefs::Get(context_);
   if (!prefs->HasPrefPath(pref_name)) {
@@ -917,7 +917,7 @@
 void ProtocolHandlerRegistry::IgnoreProtocolHandler(
     const ProtocolHandler& handler,
     const HandlerSource source) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProtocolHandlerList& list = (source == POLICY)
                                   ? policy_ignored_protocol_handlers_
                                   : user_ignored_protocol_handlers_;
@@ -970,7 +970,7 @@
 
 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
 ProtocolHandlerRegistry::CreateJobInterceptorFactory() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // this is always created on the UI thread (in profile_io's
   // InitializeOnUIThread. Any method calls must be done
   // on the IO thread (this is checked).
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index ffdf7dee..61da17f6 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -34,7 +34,7 @@
 void AssertInterceptedIO(
     const GURL& url,
     net::URLRequestJobFactory* interceptor) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   net::URLRequestContext context;
   scoped_ptr<net::URLRequest> request(context.CreateRequest(
       url, net::DEFAULT_PRIORITY, NULL));
@@ -47,7 +47,7 @@
 void AssertIntercepted(
     const GURL& url,
     net::URLRequestJobFactory* interceptor) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   BrowserThread::PostTask(BrowserThread::IO,
                           FROM_HERE,
                           base::Bind(AssertInterceptedIO,
@@ -96,7 +96,7 @@
     const std::string& scheme,
     bool expected,
     ProtocolHandlerRegistry::JobInterceptorFactory* interceptor) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   interceptor->Chain(scoped_ptr<net::URLRequestJobFactory>(
       new FakeURLRequestJobFactory()));
   ASSERT_EQ(expected, interceptor->IsHandledProtocol(scheme));
@@ -107,7 +107,7 @@
     const std::string& scheme,
     bool expected,
     ProtocolHandlerRegistry::JobInterceptorFactory* interceptor) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   BrowserThread::PostTask(BrowserThread::IO,
                           FROM_HERE,
                           base::Bind(AssertWillHandleIO,
diff --git a/chrome/browser/download/download_commands.cc b/chrome/browser/download/download_commands.cc
index 97784977..d571907 100644
--- a/chrome/browser/download/download_commands.cc
+++ b/chrome/browser/download/download_commands.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/download/download_commands.h"
 
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/download/download_crx_util.h"
 #include "chrome/browser/download/download_item_model.h"
@@ -15,7 +16,9 @@
 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/google/core/browser/google_util.h"
 #include "grit/theme_resources.h"
+#include "net/base/url_util.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -29,7 +32,7 @@
   DCHECK(download_item);
 }
 
-int DownloadCommands::GetCommandIconId(Command command) {
+int DownloadCommands::GetCommandIconId(Command command) const {
   switch (command) {
     case PAUSE:
       return IDR_DOWNLOAD_NOTIFICATION_MENU_PAUSE;
@@ -58,6 +61,16 @@
   return -1;
 }
 
+GURL DownloadCommands::GetLearnMoreURLForInterruptedDownload() const {
+  GURL learn_more_url(chrome::kDownloadInterruptedLearnMoreURL);
+  learn_more_url = google_util::AppendGoogleLocaleParam(
+      learn_more_url, g_browser_process->GetApplicationLocale());
+  return net::AppendQueryParameter(
+      learn_more_url, "ctx",
+      base::StringPrintf("%d",
+                         static_cast<int>(download_item_->GetLastReason())));
+}
+
 gfx::Image DownloadCommands::GetCommandIcon(Command command) {
   ResourceBundle& bundle = ResourceBundle::GetSharedInstance();
   return bundle.GetImageNamed(GetCommandIconId(command));
@@ -194,7 +207,7 @@
     }
     case LEARN_MORE_INTERRUPTED:
       GetBrowser()->OpenURL(content::OpenURLParams(
-          GURL(chrome::kDownloadInterruptedLearnMoreURL), content::Referrer(),
+          GetLearnMoreURLForInterruptedDownload(), content::Referrer(),
           NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, false));
       break;
     case PAUSE:
diff --git a/chrome/browser/download/download_commands.h b/chrome/browser/download/download_commands.h
index d6849b4..3ecfa08 100644
--- a/chrome/browser/download/download_commands.h
+++ b/chrome/browser/download/download_commands.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_COMMANDS_H_
 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_COMMANDS_H_
 
+#include "base/gtest_prod_util.h"
 #include "base/strings/string16.h"
-
 #include "chrome/browser/ui/browser.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/page_navigator.h"
@@ -47,11 +47,13 @@
 #endif
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(
+      DownloadCommandsTest,
+      GetLearnMoreURLForInterruptedDownload_ContainsContext);
+
   Browser* GetBrowser() const;
-
-  int GetCommandIconId(Command command);
-
-  int GetAlwaysOpenStringId() const;
+  int GetCommandIconId(Command command) const;
+  GURL GetLearnMoreURLForInterruptedDownload() const;
 
   content::DownloadItem* const download_item_;
 };
diff --git a/chrome/browser/download/download_commands_unittest.cc b/chrome/browser/download/download_commands_unittest.cc
index 46717c4..e21770d 100644
--- a/chrome/browser/download/download_commands_unittest.cc
+++ b/chrome/browser/download/download_commands_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "base/strings/stringprintf.h"
 #include "content/public/test/mock_download_item.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -154,3 +155,15 @@
   EXPECT_CALL(item(), Resume()).Times(1);
   commands().ExecuteCommand(DownloadCommands::RESUME);
 }
+
+TEST_F(DownloadCommandsTest,
+       GetLearnMoreURLForInterruptedDownload_ContainsContext) {
+  EXPECT_CALL(item(), GetLastReason())
+      .WillOnce(
+          Return(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED));
+  GURL learn_more_url = commands().GetLearnMoreURLForInterruptedDownload();
+  std::string name_value_pair = base::StringPrintf(
+      "ctx=%d", content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
+  EXPECT_LT(0u, learn_more_url.query().find(name_value_pair))
+      << learn_more_url.spec();
+}
diff --git a/chrome/browser/engagement/OWNERS b/chrome/browser/engagement/OWNERS
new file mode 100644
index 0000000..86e271a
--- /dev/null
+++ b/chrome/browser/engagement/OWNERS
@@ -0,0 +1,2 @@
+benwells@chromium.org
+raymes@chromium.org
diff --git a/chrome/browser/engagement/site_engagement_helper.cc b/chrome/browser/engagement/site_engagement_helper.cc
new file mode 100644
index 0000000..dfc9e57
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_helper.cc
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/engagement/site_engagement_helper.h"
+
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/engagement/site_engagement_service_factory.h"
+#include "chrome/browser/prerender/prerender_contents.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(SiteEngagementHelper);
+
+SiteEngagementHelper::~SiteEngagementHelper() {
+}
+
+SiteEngagementHelper::SiteEngagementHelper(content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents) {
+}
+
+void SiteEngagementHelper::DidStartNavigationToPendingEntry(
+    const GURL& url,
+    content::NavigationController::ReloadType reload_type) {
+  prerender::PrerenderContents* prerender_contents =
+      prerender::PrerenderContents::FromWebContents(web_contents());
+
+  // Ignore pre-render loads.
+  if (prerender_contents != NULL)
+    return;
+
+  // Ignore all schemes except HTTP and HTTPS.
+  if (!url.SchemeIsHTTPOrHTTPS())
+    return;
+
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
+  SiteEngagementService* service =
+      SiteEngagementServiceFactory::GetForProfile(profile);
+  DCHECK(service);
+
+  service->HandleNavigation(url);
+}
diff --git a/chrome/browser/engagement/site_engagement_helper.h b/chrome/browser/engagement/site_engagement_helper.h
new file mode 100644
index 0000000..c3883d5
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_helper.h
@@ -0,0 +1,38 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_HELPER_H_
+#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_HELPER_H_
+
+#include "base/macros.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+class WebContents;
+}
+
+class GURL;
+
+// Per-WebContents class to handle updating the site engagement scores for
+// origins as the user navigates.
+class SiteEngagementHelper
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<SiteEngagementHelper> {
+ public:
+  ~SiteEngagementHelper() override;
+
+ private:
+  explicit SiteEngagementHelper(content::WebContents* web_contents);
+  friend class content::WebContentsUserData<SiteEngagementHelper>;
+
+  // content::WebContentsObserver overrides.
+  void DidStartNavigationToPendingEntry(
+      const GURL& url,
+      content::NavigationController::ReloadType reload_type) override;
+
+  DISALLOW_COPY_AND_ASSIGN(SiteEngagementHelper);
+};
+
+#endif  // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_HELPER_H_
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc
new file mode 100644
index 0000000..d77fc6b
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -0,0 +1,42 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/engagement/site_engagement_service.h"
+
+#include <algorithm>
+
+#include "base/command_line.h"
+#include "chrome/browser/engagement/site_engagement_helper.h"
+#include "chrome/browser/engagement/site_engagement_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
+#include "url/gurl.h"
+
+// static
+SiteEngagementService* SiteEngagementService::Get(Profile* profile) {
+  return SiteEngagementServiceFactory::GetForProfile(profile);
+}
+
+// static
+bool SiteEngagementService::IsEnabled() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableSiteEngagementService);
+}
+
+SiteEngagementService::SiteEngagementService(Profile* profile)
+    : profile_(profile) {
+}
+
+SiteEngagementService::~SiteEngagementService() {
+}
+
+void SiteEngagementService::HandleNavigation(const GURL& url) {
+  GURL origin = url.GetOrigin();
+  scores_[origin] = scores_[origin] + 1;
+}
+
+int SiteEngagementService::GetScore(const GURL& url) {
+  return scores_[url.GetOrigin()];
+}
+
diff --git a/chrome/browser/engagement/site_engagement_service.h b/chrome/browser/engagement/site_engagement_service.h
new file mode 100644
index 0000000..bc150af
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_service.h
@@ -0,0 +1,52 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_
+#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_
+
+#include <map>
+
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class GURL;
+class Profile;
+
+// Stores and retrieves the engagement score of an origin.
+//
+// An engagement score is a positive integer that represents how much a user has
+// engaged with an origin - the higher it is, the more engagement the user has
+// had with this site recently.
+//
+// Positive user activity, such as visiting the origin often and adding it to
+// the homescreen, will increase the site engagement score. Negative activity,
+// such as rejecting permission prompts or not responding to notifications, will
+// decrease the site engagement score.
+class SiteEngagementService : public KeyedService {
+ public:
+  static SiteEngagementService* Get(Profile* profile);
+
+  // Returns whether or not the SiteEngagementService is enabled.
+  static bool IsEnabled();
+
+  explicit SiteEngagementService(Profile* profile);
+  ~SiteEngagementService() override;
+
+  // Update the karma score of the origin matching |url| for user navigation.
+  void HandleNavigation(const GURL& url);
+
+  // Returns a non-negative integer representing the engagement score of the
+  // origin for this URL.
+  int GetScore(const GURL& url);
+
+ private:
+  Profile* profile_;
+
+  // Temporary non-persistent score database for testing.
+  std::map<GURL, int> scores_;
+
+  DISALLOW_COPY_AND_ASSIGN(SiteEngagementService);
+};
+
+#endif  // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_
diff --git a/chrome/browser/engagement/site_engagement_service_factory.cc b/chrome/browser/engagement/site_engagement_service_factory.cc
new file mode 100644
index 0000000..ce9070a
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_service_factory.cc
@@ -0,0 +1,39 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/engagement/site_engagement_service_factory.h"
+
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+// static
+SiteEngagementService* SiteEngagementServiceFactory::GetForProfile(
+    Profile* profile) {
+  return static_cast<SiteEngagementService*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+SiteEngagementServiceFactory* SiteEngagementServiceFactory::GetInstance() {
+  return Singleton<SiteEngagementServiceFactory>::get();
+}
+
+SiteEngagementServiceFactory::SiteEngagementServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+          "SiteEngagementService",
+          BrowserContextDependencyManager::GetInstance()) {
+}
+
+SiteEngagementServiceFactory::~SiteEngagementServiceFactory() {
+}
+
+bool SiteEngagementServiceFactory::ServiceIsNULLWhileTesting() const {
+  return true;
+}
+
+KeyedService* SiteEngagementServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* profile) const {
+  return new SiteEngagementService(static_cast<Profile*>(profile));
+}
diff --git a/chrome/browser/engagement/site_engagement_service_factory.h b/chrome/browser/engagement/site_engagement_service_factory.h
new file mode 100644
index 0000000..ccec13a
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_service_factory.h
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+class SiteEngagementService;
+
+// Singleton that owns all SiteEngagementServices and associates them with
+// Profiles. Listens for the Profile's destruction notification and cleans up
+// the associated SiteEngagementService.
+//
+// The default factory behavior is suitable for this factory as:
+// * there should be no site engagement tracking in incognito
+// * the site engagement service should be created lazily
+// * the site engagement service is needed in tests.
+class SiteEngagementServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static SiteEngagementService* GetForProfile(Profile* profile);
+
+  static SiteEngagementServiceFactory* GetInstance();
+
+ private:
+  friend struct DefaultSingletonTraits<SiteEngagementServiceFactory>;
+
+  SiteEngagementServiceFactory();
+  ~SiteEngagementServiceFactory() override;
+
+  // KeyedServiceBaseFactory:
+  bool ServiceIsNULLWhileTesting() const override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* profile) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(SiteEngagementServiceFactory);
+};
+
+#endif  // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_FACTORY_H_
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
new file mode 100644
index 0000000..baa1886
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "chrome/browser/engagement/site_engagement_helper.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/engagement/site_engagement_service_factory.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+
+using SiteEngagementServiceTest = BrowserWithTestWindowTest;
+
+// Tests that the Site Engagement score is initially 0, and increments by 1 on
+// each page request.
+TEST_F(SiteEngagementServiceTest, ScoreIncrementsOnPageRequest) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableSiteEngagementService);
+
+  SiteEngagementService* service =
+      SiteEngagementServiceFactory::GetForProfile(profile());
+  DCHECK(service);
+
+  GURL url("http://www.google.com/");
+
+  AddTab(browser(), GURL("about:blank"));
+  EXPECT_EQ(0, service->GetScore(url));
+
+  for (int i = 0; i < 10; ++i) {
+    NavigateAndCommitActiveTab(url);
+    EXPECT_EQ(i + 1, service->GetScore(url));
+  }
+}
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 2d7d367..47e5e93 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -245,11 +245,13 @@
       error_console_observer_(this),
       process_manager_observer_(this),
       app_window_registry_observer_(this),
+      extension_action_api_observer_(this),
       profile_(profile) {
   extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
   error_console_observer_.Add(ErrorConsole::Get(profile));
   process_manager_observer_.Add(ProcessManager::Get(profile));
   app_window_registry_observer_.Add(AppWindowRegistry::Get(profile));
+  extension_action_api_observer_.Add(ExtensionActionAPI::Get(profile));
 }
 
 DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() {
@@ -338,6 +340,13 @@
                             window->extension_id());
 }
 
+void DeveloperPrivateEventRouter::OnExtensionActionVisibilityChanged(
+    const std::string& extension_id,
+    bool is_now_visible) {
+  BroadcastItemStateChanged(
+       profile_, developer::EVENT_TYPE_PREFS_CHANGED, extension_id);
+}
+
 void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) {
   last_unpacked_directory_ = path;
 }
@@ -605,8 +614,7 @@
         extension->id(), browser_context(), *update.run_on_all_urls);
   }
   if (update.show_action_button) {
-    ExtensionActionAPI::SetBrowserActionVisibility(
-        ExtensionPrefs::Get(browser_context()),
+    ExtensionActionAPI::Get(browser_context())->SetBrowserActionVisibility(
         extension->id(),
         *update.show_action_button);
   }
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h
index fea6e72..8e2e013a 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.h
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -10,6 +10,7 @@
 #include "base/files/file.h"
 #include "base/scoped_observer.h"
 #include "chrome/browser/extensions/api/developer_private/entry_picker.h"
+#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
 #include "chrome/browser/extensions/chrome_extension_function.h"
 #include "chrome/browser/extensions/error_console/error_console.h"
@@ -65,7 +66,8 @@
 class DeveloperPrivateEventRouter : public ExtensionRegistryObserver,
                                     public ErrorConsole::Observer,
                                     public ProcessManagerObserver,
-                                    public AppWindowRegistry::Observer {
+                                    public AppWindowRegistry::Observer,
+                                    public ExtensionActionAPI::Observer {
  public:
   explicit DeveloperPrivateEventRouter(Profile* profile);
   ~DeveloperPrivateEventRouter() override;
@@ -105,6 +107,10 @@
   void OnAppWindowAdded(AppWindow* window) override;
   void OnAppWindowRemoved(AppWindow* window) override;
 
+  // ExtensionActionAPI::Observer:
+  void OnExtensionActionVisibilityChanged(const std::string& extension_id,
+                                          bool is_now_visible) override;
+
   ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
       extension_registry_observer_;
   ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_;
@@ -112,6 +118,8 @@
       process_manager_observer_;
   ScopedObserver<AppWindowRegistry, AppWindowRegistry::Observer>
       app_window_registry_observer_;
+  ScopedObserver<ExtensionActionAPI, ExtensionActionAPI::Observer>
+      extension_action_api_observer_;
 
   Profile* profile_;
 
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
index 562da65..9ac1c43 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
@@ -140,6 +140,7 @@
     : browser_context_(browser_context),
       extension_system_(ExtensionSystem::Get(browser_context)),
       extension_prefs_(ExtensionPrefs::Get(browser_context)),
+      extension_action_api_(ExtensionActionAPI::Get(browser_context)),
       warning_service_(WarningService::Get(browser_context)),
       error_console_(ErrorConsole::Get(browser_context)) {
 }
@@ -155,8 +156,7 @@
   // Don't consider the button hidden with the redesign, because "hidden"
   // buttons are now just hidden in the wrench menu.
   info->action_button_hidden =
-      !ExtensionActionAPI::GetBrowserActionVisibility(
-          extension_prefs_, extension.id()) &&
+      !extension_action_api_->GetBrowserActionVisibility(extension.id()) &&
       !FeatureSwitch::extension_action_redesign()->IsEnabled();
 
   // Blacklist text.
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.h b/chrome/browser/extensions/api/developer_private/extension_info_generator.h
index 736acce..29dc73ea 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator.h
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.h
@@ -14,6 +14,7 @@
 namespace extensions {
 class ErrorConsole;
 class Extension;
+class ExtensionActionAPI;
 class ExtensionPrefs;
 class ExtensionSystem;
 class WarningService;
@@ -46,6 +47,7 @@
   content::BrowserContext* browser_context_;
   ExtensionSystem* extension_system_;
   ExtensionPrefs* extension_prefs_;
+  ExtensionActionAPI* extension_action_api_;
   WarningService* warning_service_;
   ErrorConsole* error_console_;
 
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
index bb99a6a1..578592240 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -461,7 +461,9 @@
       base::Bind(
           &EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction::OnSeekFailure,
           this),
-      content::BrowserThread::GetBlockingPool());
+      content::BrowserThread::GetBlockingPool()->
+          GetTaskRunnerWithShutdownBehavior(
+              base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN).get());
   return true;
 }
 
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc
index d85b6ad6..3f64a3f 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc
@@ -13,9 +13,10 @@
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
-#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
+#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chromeos/attestation/attestation_constants.h"
@@ -24,7 +25,6 @@
 #include "chromeos/cryptohome/mock_async_method_caller.h"
 #include "chromeos/dbus/dbus_method_call_status.h"
 #include "chromeos/dbus/mock_cryptohome_client.h"
-#include "chromeos/settings/cros_settings_provider.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "extensions/common/test_util.h"
@@ -141,7 +141,8 @@
 
 class EPKPChallengeKeyTestBase : public BrowserWithTestWindowTest {
  protected:
-  EPKPChallengeKeyTestBase() : extension_(test_util::CreateEmptyExtension()) {
+  EPKPChallengeKeyTestBase()
+      : settings_helper_(false), extension_(test_util::CreateEmptyExtension()) {
     // Set up the default behavior of mocks.
     ON_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
         .WillByDefault(WithArgs<3>(Invoke(FakeBoolDBusMethod(
@@ -163,25 +164,8 @@
     stub_install_attributes_.SetDeviceId("device_id");
     stub_install_attributes_.SetMode(policy::DEVICE_MODE_ENTERPRISE);
 
-    // Replace the default device setting provider with the stub.
-    device_settings_provider_ = chromeos::CrosSettings::Get()->GetProvider(
-        chromeos::kReportDeviceVersionInfo);
-    EXPECT_TRUE(device_settings_provider_ != NULL);
-    EXPECT_TRUE(chromeos::CrosSettings::Get()->
-                RemoveSettingsProvider(device_settings_provider_));
-    chromeos::CrosSettings::Get()->
-        AddSettingsProvider(&stub_settings_provider_);
-
-    // Set the device settings.
-    stub_settings_provider_.Set(chromeos::kDeviceAttestationEnabled,
-                                base::FundamentalValue(true));
-  }
-
-  virtual ~EPKPChallengeKeyTestBase() {
-    EXPECT_TRUE(chromeos::CrosSettings::Get()->
-                RemoveSettingsProvider(&stub_settings_provider_));
-    chromeos::CrosSettings::Get()->
-        AddSettingsProvider(device_settings_provider_);
+    settings_helper_.ReplaceProvider(chromeos::kDeviceAttestationEnabled);
+    settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true);
   }
 
   virtual void SetUp() override {
@@ -206,10 +190,9 @@
   NiceMock<chromeos::MockCryptohomeClient> mock_cryptohome_client_;
   NiceMock<cryptohome::MockAsyncMethodCaller> mock_async_method_caller_;
   NiceMock<chromeos::attestation::MockAttestationFlow> mock_attestation_flow_;
+  chromeos::ScopedCrosSettingsTestHelper settings_helper_;
   scoped_refptr<extensions::Extension> extension_;
   policy::StubEnterpriseInstallAttributes stub_install_attributes_;
-  chromeos::CrosSettingsProvider* device_settings_provider_;
-  chromeos::StubCrosSettingsProvider stub_settings_provider_;
   PrefService* prefs_;
 };
 
@@ -260,8 +243,7 @@
 }
 
 TEST_F(EPKPChallengeMachineKeyTest, DevicePolicyDisabled) {
-  stub_settings_provider_.Set(chromeos::kDeviceAttestationEnabled,
-                              base::FundamentalValue(false));
+  settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false);
 
   EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError,
             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
@@ -397,8 +379,7 @@
 }
 
 TEST_F(EPKPChallengeUserKeyTest, DevicePolicyDisabled) {
-  stub_settings_provider_.Set(chromeos::kDeviceAttestationEnabled,
-                              base::FundamentalValue(false));
+  settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false);
 
   EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError,
             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
index 58f765b..c00dbc4 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -63,6 +63,11 @@
     content::BrowserContext* browser_context) {
 }
 
+void ExtensionActionAPI::Observer::OnExtensionActionVisibilityChanged(
+    const std::string& extension_id,
+    bool is_now_visible) {
+}
+
 void ExtensionActionAPI::Observer::OnPageActionsUpdated(
     content::WebContents* web_contents) {
 }
@@ -81,7 +86,8 @@
     g_factory = LAZY_INSTANCE_INITIALIZER;
 
 ExtensionActionAPI::ExtensionActionAPI(content::BrowserContext* context)
-    : browser_context_(context) {
+    : browser_context_(context),
+      extension_prefs_(nullptr) {
   ExtensionFunctionRegistry* registry =
       ExtensionFunctionRegistry::GetInstance();
 
@@ -123,11 +129,18 @@
   return BrowserContextKeyedAPIFactory<ExtensionActionAPI>::Get(context);
 }
 
-// static
+void ExtensionActionAPI::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void ExtensionActionAPI::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 bool ExtensionActionAPI::GetBrowserActionVisibility(
-    const ExtensionPrefs* prefs,
     const std::string& extension_id) {
   bool visible = false;
+  ExtensionPrefs* prefs = GetExtensionPrefs();
   if (!prefs || !prefs->ReadPrefAsBoolean(extension_id,
                                           kBrowserActionVisible,
                                           &visible)) {
@@ -136,29 +149,17 @@
   return visible;
 }
 
-// static
 void ExtensionActionAPI::SetBrowserActionVisibility(
-    ExtensionPrefs* prefs,
     const std::string& extension_id,
     bool visible) {
-  if (GetBrowserActionVisibility(prefs, extension_id) == visible)
+  if (GetBrowserActionVisibility(extension_id) == visible)
     return;
 
-  prefs->UpdateExtensionPref(extension_id,
-                             kBrowserActionVisible,
-                             new base::FundamentalValue(visible));
-  content::NotificationService::current()->Notify(
-      NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-      content::Source<ExtensionPrefs>(prefs),
-      content::Details<const std::string>(&extension_id));
-}
-
-void ExtensionActionAPI::AddObserver(Observer* observer) {
-  observers_.AddObserver(observer);
-}
-
-void ExtensionActionAPI::RemoveObserver(Observer* observer) {
-  observers_.RemoveObserver(observer);
+  GetExtensionPrefs()->UpdateExtensionPref(extension_id,
+                                           kBrowserActionVisible,
+                                           new base::FundamentalValue(visible));
+  FOR_EACH_OBSERVER(Observer, observers_, OnExtensionActionVisibilityChanged(
+      extension_id, visible));
 }
 
 ExtensionAction::ShowAction ExtensionActionAPI::ExecuteExtensionAction(
@@ -284,6 +285,15 @@
   }
 }
 
+ExtensionPrefs* ExtensionActionAPI::GetExtensionPrefs() {
+  // This lazy initialization is more than just an optimization, because it
+  // allows tests to associate a new ExtensionPrefs with the browser context
+  // before we access it.
+  if (!extension_prefs_)
+    extension_prefs_ = ExtensionPrefs::Get(browser_context_);
+  return extension_prefs_;
+}
+
 void ExtensionActionAPI::DispatchEventToExtension(
     content::BrowserContext* context,
     const std::string& extension_id,
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.h b/chrome/browser/extensions/api/extension_action/extension_action_api.h
index 5a1f6ce..63dccbd5 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.h
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.h
@@ -42,6 +42,11 @@
         content::WebContents* web_contents,
         content::BrowserContext* browser_context);
 
+    // Called when there is a change to the extension action's visibility.
+    virtual void OnExtensionActionVisibilityChanged(
+        const std::string& extension_id,
+        bool is_now_visible);
+
     // Called when the page actions have been refreshed do to a possible change
     // in count or visibility.
     virtual void OnPageActionsUpdated(content::WebContents* web_contents);
@@ -60,13 +65,6 @@
   // Convenience method to get the instance for a profile.
   static ExtensionActionAPI* Get(content::BrowserContext* context);
 
-  static bool GetBrowserActionVisibility(const ExtensionPrefs* prefs,
-                                         const std::string& extension_id);
-  static void SetBrowserActionVisibility(ExtensionPrefs* prefs,
-                                         const std::string& extension_id,
-                                         bool visible);
-
-  // BrowserContextKeyedAPI implementation.
   static BrowserContextKeyedAPIFactory<ExtensionActionAPI>*
       GetFactoryInstance();
 
@@ -74,6 +72,11 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
+  bool GetBrowserActionVisibility(const std::string& extension_id);
+  void SetBrowserActionVisibility(const std::string& extension_id,
+                                  bool visible);
+
+  // BrowserContextKeyedAPI implementation.
   // Executes the action of the given |extension| on the |browser|'s active
   // web contents. If |grant_tab_permissions| is true, this will also grant
   // activeTab to the extension (so this should only be done if this is through
@@ -109,9 +112,16 @@
   // changed, and signals the browser to update.
   void NotifyPageActionsChanged(content::WebContents* web_contents);
 
+  void set_prefs_for_testing(ExtensionPrefs* prefs) {
+    extension_prefs_ = prefs;
+  }
+
  private:
   friend class BrowserContextKeyedAPIFactory<ExtensionActionAPI>;
 
+  // Returns the associated extension prefs.
+  ExtensionPrefs* GetExtensionPrefs();
+
   // The DispatchEvent methods forward events to the |context|'s event router.
   void DispatchEventToExtension(content::BrowserContext* context,
                                 const std::string& extension_id,
@@ -132,6 +142,8 @@
 
   content::BrowserContext* browser_context_;
 
+  ExtensionPrefs* extension_prefs_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionActionAPI);
 };
 
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_prefs_unittest.cc b/chrome/browser/extensions/api/extension_action/extension_action_prefs_unittest.cc
index b69506a1..6925b98e 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_prefs_unittest.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_prefs_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/extension_prefs_unittest.h"
+#include "chrome/test/base/testing_profile.h"
 #include "extensions/common/extension.h"
 
 namespace extensions {
@@ -16,42 +17,47 @@
 // Tests force hiding browser actions.
 class ExtensionPrefsHidingBrowserActions : public ExtensionPrefsTest {
  public:
+  ExtensionPrefsHidingBrowserActions() {}
+  ~ExtensionPrefsHidingBrowserActions() override {}
+
   void Initialize() override {
+    profile_.reset(new TestingProfile());
+
     // Install 5 extensions.
     for (int i = 0; i < 5; i++) {
       std::string name = "test" + base::IntToString(i);
       extensions_.push_back(prefs_.AddExtension(name));
     }
 
-    ExtensionList::const_iterator iter;
-    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
-      EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-          prefs(), (*iter)->id()));
-    }
+    ExtensionActionAPI* action_api = ExtensionActionAPI::Get(profile_.get());
+    action_api->set_prefs_for_testing(prefs());
+    for (const scoped_refptr<const Extension>& extension : extensions_)
+      EXPECT_TRUE(action_api->GetBrowserActionVisibility(extension->id()));
 
-    ExtensionActionAPI::SetBrowserActionVisibility(
-        prefs(), extensions_[0]->id(), false);
-    ExtensionActionAPI::SetBrowserActionVisibility(
-        prefs(), extensions_[1]->id(), true);
+    action_api->SetBrowserActionVisibility(extensions_[0]->id(), false);
+    action_api->SetBrowserActionVisibility(extensions_[1]->id(), true);
   }
 
   void Verify() override {
+    ExtensionActionAPI* action_api = ExtensionActionAPI::Get(profile_.get());
+    action_api->set_prefs_for_testing(prefs());
     // Make sure the one we hid is hidden.
-    EXPECT_FALSE(ExtensionActionAPI::GetBrowserActionVisibility(
-        prefs(), extensions_[0]->id()));
+    EXPECT_FALSE(action_api->GetBrowserActionVisibility(extensions_[0]->id()));
 
     // Make sure the other id's are not hidden.
     ExtensionList::const_iterator iter = extensions_.begin() + 1;
     for (; iter != extensions_.end(); ++iter) {
       SCOPED_TRACE(base::StringPrintf("Loop %d ",
                        static_cast<int>(iter - extensions_.begin())));
-      EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-          prefs(), (*iter)->id()));
+      EXPECT_TRUE(action_api->GetBrowserActionVisibility((*iter)->id()));
     }
   }
 
  private:
+  scoped_ptr<TestingProfile> profile_;
   ExtensionList extensions_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionPrefsHidingBrowserActions);
 };
 
 TEST_F(ExtensionPrefsHidingBrowserActions, ForceHide) {}
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 77d6fb5..db85ab7 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -199,6 +199,10 @@
                              args.Pass());
   }
 
+  bool IsInterestedInKeyEvent() const override {
+    return ShouldForwardKeyEvent();
+  }
+
   void OnKeyEvent(const std::string& component_id,
                   const InputMethodEngineInterface::KeyboardEvent& event,
                   chromeos::input_method::KeyEventHandle* key_data) override {
diff --git a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
index e53007b1..5423b480 100644
--- a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
+++ b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
@@ -288,9 +288,10 @@
     return;
 
   write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
-  write_to_file_observer_->set_log_level(net::NetLog::LOG_ALL_BUT_BYTES);
+  write_to_file_observer_->set_capture_mode(
+      net::NetLogCaptureMode::IncludeCookiesAndCredentials());
   write_to_file_observer_->StartObserving(io_thread->net_log(), file->Pass(),
-                                  nullptr, nullptr);
+                                          nullptr, nullptr);
 }
 
 void LogPrivateAPI::MaybeStartNetInternalLogging(
@@ -304,7 +305,7 @@
     switch (event_sink_) {
       case api::log_private::EVENT_SINK_CAPTURE: {
         io_thread->net_log()->DeprecatedAddObserver(
-            this, net::NetLog::LOG_ALL_BUT_BYTES);
+            this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
         break;
       }
       case api::log_private::EVENT_SINK_FILE: {
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
index 91b71860..8f6cf682 100644
--- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
+++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -34,6 +34,7 @@
 #include "extensions/browser/extension_message_filter.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
+#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
 #include "extensions/browser/guest_view/guest_view_message_filter.h"
 #include "extensions/browser/info_map.h"
 #include "extensions/browser/io_thread_extension_message_filter.h"
@@ -378,6 +379,7 @@
   host->AddFilter(new ChromeExtensionMessageFilter(id, profile));
   host->AddFilter(new ExtensionMessageFilter(id, profile));
   host->AddFilter(new IOThreadExtensionMessageFilter(id, profile));
+  host->AddFilter(new ExtensionsGuestViewMessageFilter(id, profile));
   host->AddFilter(new GuestViewMessageFilter(id, profile));
   extension_web_request_api_helpers::SendExtensionWebRequestStatusToHost(host);
 }
diff --git a/chrome/browser/extensions/display_info_provider_chromeos.cc b/chrome/browser/extensions/display_info_provider_chromeos.cc
index 60c6e6c..fda4b63 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos.cc
@@ -318,7 +318,7 @@
 
   // Process 'mirroringSourceId' parameter.
   if (info.mirroring_source_id &&
-      info.mirroring_source_id->empty() == display_manager->IsMirrored()) {
+      info.mirroring_source_id->empty() == display_manager->IsInMirrorMode()) {
     display_controller->ToggleMirrorMode();
   }
 
@@ -361,9 +361,9 @@
   ash::DisplayManager* display_manager =
       ash::Shell::GetInstance()->display_manager();
   unit->name = display_manager->GetDisplayNameForId(display.id());
-  if (display_manager->IsMirrored()) {
+  if (display_manager->IsInMirrorMode()) {
     unit->mirroring_source_id =
-        base::Int64ToString(display_manager->mirrored_display_id());
+        base::Int64ToString(display_manager->mirroring_display_id());
   }
 
   // TODO(hshi): determine the DPI of the screen.
diff --git a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
index 493e54c..28d3eab 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
@@ -253,12 +253,12 @@
   ASSERT_TRUE(DisplayExists(display_id_secondary)) << display_id_secondary
                                                    << " not found";
 
-  ASSERT_FALSE(GetDisplayManager()->IsMirrored());
+  ASSERT_FALSE(GetDisplayManager()->IsInMirrorMode());
   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
 
   GetDisplayManager()->SetMirrorMode(true);
-  ASSERT_TRUE(GetDisplayManager()->IsMirrored());
+  ASSERT_TRUE(GetDisplayManager()->IsInMirrorMode());
 
   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
 
@@ -268,7 +268,7 @@
             result[0]->mirroring_source_id);
 
   GetDisplayManager()->SetMirrorMode(false);
-  ASSERT_FALSE(GetDisplayManager()->IsMirrored());
+  ASSERT_FALSE(GetDisplayManager()->IsInMirrorMode());
 
   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
 
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
index a54ac2c..f5b1409 100644
--- a/chrome/browser/extensions/extension_context_menu_model.cc
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -85,8 +85,8 @@
   } else {
     // With the redesign, we display "show" or "hide" based on the icon's
     // visibility.
-    bool visible = ExtensionActionAPI::GetBrowserActionVisibility(
-                       ExtensionPrefs::Get(profile), extension->id());
+    bool visible = ExtensionActionAPI::Get(profile)->GetBrowserActionVisibility(
+                       extension->id());
     string_id =
         visible ? IDS_EXTENSIONS_HIDE_BUTTON : IDS_EXTENSIONS_SHOW_BUTTON;
   }
@@ -206,11 +206,9 @@
       extensions::ExtensionTabUtil::OpenOptionsPage(extension, browser_);
       break;
     case TOGGLE_VISIBILITY: {
-      ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
-      bool visible = ExtensionActionAPI::GetBrowserActionVisibility(
-                         prefs, extension->id());
-      ExtensionActionAPI::SetBrowserActionVisibility(
-          prefs, extension->id(), !visible);
+      ExtensionActionAPI* api = ExtensionActionAPI::Get(profile_);
+      bool visible = api->GetBrowserActionVisibility(extension->id());
+      api->SetBrowserActionVisibility(extension->id(), !visible);
       break;
     }
     case UNINSTALL: {
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
index 16fb6959..e1976f8 100644
--- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc
+++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/test/base/test_browser_window.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/crx_file/id_util.h"
-#include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/test_management_policy.h"
 #include "extensions/common/extension_builder.h"
@@ -262,7 +261,6 @@
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_HIDE_BUTTON);
   base::string16 show_string =
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_BUTTON);
-  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
 
   int index = GetCommandIndex(menu, visibility_command);
   // Without the toolbar redesign switch, page action menus shouldn't have a
@@ -286,13 +284,13 @@
   index = GetCommandIndex(menu, visibility_command);
   // By default, browser actions should be visible (and therefore the button
   // should be to hide).
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, browser_action->id()));
+  ExtensionActionAPI* extension_action_api = ExtensionActionAPI::Get(profile());
+  EXPECT_TRUE(extension_action_api->GetBrowserActionVisibility(
+                  browser_action->id()));
   EXPECT_EQ(hide_string, menu->GetLabelAt(index));
 
   // Hide the browser action. This should mean the string is "show".
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, browser_action->id(), false);
+  extension_action_api->SetBrowserActionVisibility(browser_action->id(), false);
   menu = new ExtensionContextMenuModel(browser_action.get(), browser.get());
   index = GetCommandIndex(menu, visibility_command);
   EXPECT_NE(-1, index);
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index 5a61ea6..085936b 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -42,6 +42,7 @@
     : profile_(profile),
       extension_prefs_(extension_prefs),
       prefs_(profile_->GetPrefs()),
+      extension_action_api_(ExtensionActionAPI::Get(profile_)),
       extensions_initialized_(false),
       include_all_extensions_(
           FeatureSwitch::extension_action_redesign()->IsEnabled()),
@@ -160,6 +161,47 @@
   }
 }
 
+void ExtensionToolbarModel::OnExtensionActionVisibilityChanged(
+    const std::string& extension_id,
+    bool is_now_visible) {
+  const Extension* extension =
+      ExtensionRegistry::Get(profile_)->GetExtensionById(
+          extension_id, ExtensionRegistry::EVERYTHING);
+
+  // Hiding works differently with the new and old toolbars.
+  if (include_all_extensions_) {
+    // It's possible that we haven't added this extension yet, if its
+    // visibility was adjusted in the course of its initialization.
+    if (std::find(toolbar_items_.begin(), toolbar_items_.end(), extension) ==
+            toolbar_items_.end())
+      return;
+
+    int new_size = 0;
+    int new_index = 0;
+    if (is_now_visible) {
+      // If this action used to be hidden, we can't possibly be showing all.
+      DCHECK_LT(visible_icon_count(), toolbar_items_.size());
+      // Grow the bar by one and move the extension to the end of the visibles.
+      new_size = visible_icon_count() + 1;
+      new_index = new_size - 1;
+    } else {
+      // If we're hiding one, we must be showing at least one.
+      DCHECK_GE(visible_icon_count(), 0u);
+      // Shrink the bar by one and move the extension to the beginning of the
+      // overflow menu.
+      new_size = visible_icon_count() - 1;
+      new_index = new_size;
+    }
+    SetVisibleIconCount(new_size);
+    MoveExtensionIcon(extension->id(), new_index);
+  } else {  // Don't include all extensions.
+    if (is_now_visible)
+      AddExtension(extension);
+    else
+      RemoveExtension(extension);
+  }
+}
+
 void ExtensionToolbarModel::OnExtensionLoaded(
     content::BrowserContext* browser_context,
     const Extension* extension) {
@@ -197,52 +239,6 @@
   }
 }
 
-void ExtensionToolbarModel::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, type);
-  const Extension* extension =
-      ExtensionRegistry::Get(profile_)->GetExtensionById(
-          *content::Details<const std::string>(details).ptr(),
-          ExtensionRegistry::EVERYTHING);
-
-  bool visible = ExtensionActionAPI::GetBrowserActionVisibility(
-                     extension_prefs_, extension->id());
-  // Hiding works differently with the new and old toolbars.
-  if (include_all_extensions_) {
-    // It's possible that we haven't added this extension yet, if its
-    // visibility was adjusted in the course of its initialization.
-    if (std::find(toolbar_items_.begin(), toolbar_items_.end(), extension) ==
-            toolbar_items_.end())
-      return;
-
-    int new_size = 0;
-    int new_index = 0;
-    if (visible) {
-      // If this action used to be hidden, we can't possibly be showing all.
-      DCHECK_LT(visible_icon_count(), toolbar_items_.size());
-      // Grow the bar by one and move the extension to the end of the visibles.
-      new_size = visible_icon_count() + 1;
-      new_index = new_size - 1;
-    } else {
-      // If we're hiding one, we must be showing at least one.
-      DCHECK_GE(visible_icon_count(), 0u);
-      // Shrink the bar by one and move the extension to the beginning of the
-      // overflow menu.
-      new_size = visible_icon_count() - 1;
-      new_index = new_size;
-    }
-    SetVisibleIconCount(new_size);
-    MoveExtensionIcon(extension->id(), new_index);
-  } else {  // Don't include all extensions.
-    if (visible)
-      AddExtension(extension);
-    else
-      RemoveExtension(extension);
-  }
-}
-
 void ExtensionToolbarModel::OnReady() {
   ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
   InitializeExtensionList();
@@ -250,11 +246,7 @@
   // changes so that the toolbar buttons can be shown in their stable ordering
   // taken from prefs.
   extension_registry_observer_.Add(registry);
-  extension_action_observer_.Add(ExtensionActionAPI::Get(profile_));
-  registrar_.Add(
-      this,
-      extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-      content::Source<ExtensionPrefs>(extension_prefs_));
+  extension_action_observer_.Add(extension_action_api_);
 }
 
 size_t ExtensionToolbarModel::FindNewPositionFromLastKnownGood(
@@ -299,8 +291,7 @@
   }
 
   return action_manager->GetBrowserAction(*extension) &&
-         ExtensionActionAPI::GetBrowserActionVisibility(
-             extension_prefs_, extension->id());
+         extension_action_api_->GetBrowserActionVisibility(extension->id());
 }
 
 void ExtensionToolbarModel::AddExtension(const Extension* extension) {
@@ -476,8 +467,7 @@
   int hidden = 0;
   for (const scoped_refptr<const Extension>& extension : extensions) {
     if (!ShouldAddExtension(extension.get())) {
-      if (!ExtensionActionAPI::GetBrowserActionVisibility(extension_prefs_,
-                                                          extension->id()))
+      if (!extension_action_api_->GetBrowserActionVisibility(extension->id()))
         ++hidden;
       continue;
     }
@@ -570,27 +560,18 @@
   // overflow menu with the new toolbar design.
   if (include_all_extensions_ && !profile_->IsOffTheRecord()) {
     bool visible = index < visible_icon_count();
-    if (visible != ExtensionActionAPI::GetBrowserActionVisibility(
-                       extension_prefs_, extension->id())) {
+    if (visible != extension_action_api_->GetBrowserActionVisibility(
+                       extension->id())) {
       // Don't observe changes caused by ourselves.
       bool was_registered = false;
-      if (registrar_.IsRegistered(
-              this,
-              NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-              content::Source<ExtensionPrefs>(extension_prefs_))) {
+      if (extension_action_observer_.IsObserving(extension_action_api_)) {
         was_registered = true;
-        registrar_.Remove(
-            this,
-            NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-            content::Source<ExtensionPrefs>(extension_prefs_));
+        extension_action_observer_.RemoveAll();
       }
-      ExtensionActionAPI::SetBrowserActionVisibility(
-          extension_prefs_, extension->id(), visible);
-      if (was_registered) {
-        registrar_.Add(this,
-                       NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-                       content::Source<ExtensionPrefs>(extension_prefs_));
-      }
+      extension_action_api_->SetBrowserActionVisibility(extension->id(),
+                                                       visible);
+      if (was_registered)
+        extension_action_observer_.Add(extension_action_api_);
     }
   }
 }
@@ -720,9 +701,8 @@
     if (visible_icon_count() < extension_ids.size())
       SetVisibleIconCount(extension_ids.size());
 
-    // It's important that is_highlighting_ is changed right immediately before
-    // the observers are notified since it changes the result of
-    // toolbar_items().
+    // It's important that is_highlighting_ is changed immediately before the
+    // observers are notified since it changes the result of toolbar_items().
     is_highlighting_ = true;
     FOR_EACH_OBSERVER(Observer, observers_,
                       OnToolbarHighlightModeChanged(true));
@@ -738,16 +718,17 @@
 
 void ExtensionToolbarModel::StopHighlighting() {
   if (is_highlighting_) {
-    highlighted_items_.clear();
     if (old_visible_icon_count_ != visible_icon_count_)
       SetVisibleIconCount(old_visible_icon_count_);
 
-    // It's important that is_highlighting_ is changed right immediately before
-    // the observers are notified since it changes the result of
-    // toolbar_items().
+    // It's important that is_highlighting_ is changed immediately before the
+    // observers are notified since it changes the result of toolbar_items().
     is_highlighting_ = false;
     FOR_EACH_OBSERVER(Observer, observers_,
                       OnToolbarHighlightModeChanged(false));
+    // For the same reason, we don't clear highlighted_items_ until after the
+    // mode changed.
+    highlighted_items_.clear();
   }
 }
 
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
index f3025b7..cc53ea8 100644
--- a/chrome/browser/extensions/extension_toolbar_model.h
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -12,8 +12,6 @@
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/extension.h"
@@ -27,8 +25,7 @@
 class ExtensionSet;
 
 // Model for the browser actions toolbar.
-class ExtensionToolbarModel : public content::NotificationObserver,
-                              public ExtensionActionAPI::Observer,
+class ExtensionToolbarModel : public ExtensionActionAPI::Observer,
                               public ExtensionRegistryObserver,
                               public KeyedService {
  public:
@@ -160,11 +157,6 @@
   bool RedesignIsShowingNewIcons() const;
 
  private:
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   // Callback when extensions are ready.
   void OnReady();
 
@@ -183,6 +175,8 @@
       ExtensionAction* extension_action,
       content::WebContents* web_contents,
       content::BrowserContext* browser_context) override;
+  void OnExtensionActionVisibilityChanged(const std::string& extension_id,
+                                          bool is_now_visible) override;
 
   // To be called after the extension service is ready; gets loaded extensions
   // from the ExtensionRegistry and their saved order from the pref service
@@ -223,6 +217,9 @@
   ExtensionPrefs* extension_prefs_;
   PrefService* prefs_;
 
+  // The ExtensionActionAPI object, cached for convenience.
+  ExtensionActionAPI* extension_action_api_;
+
   // True if we've handled the initial EXTENSIONS_READY notification.
   bool extensions_initialized_;
 
@@ -255,8 +252,6 @@
   // visible, instead of overloading this one.
   int visible_icon_count_;
 
-  content::NotificationRegistrar registrar_;
-
   ScopedObserver<ExtensionActionAPI, ExtensionActionAPI::Observer>
       extension_action_observer_;
 
diff --git a/chrome/browser/extensions/extension_toolbar_model_unittest.cc b/chrome/browser/extensions/extension_toolbar_model_unittest.cc
index 922dc493..90c36f5 100644
--- a/chrome/browser/extensions/extension_toolbar_model_unittest.cc
+++ b/chrome/browser/extensions/extension_toolbar_model_unittest.cc
@@ -782,6 +782,8 @@
        ExtensionToolbarActionsVisibilityNoSwitch) {
   Init();
 
+  ExtensionActionAPI* action_api = ExtensionActionAPI::Get(profile());
+
   ASSERT_TRUE(AddBrowserActionExtensions());
   // Sanity check: Order should start as A B C.
   EXPECT_EQ(3u, num_toolbar_items());
@@ -789,21 +791,15 @@
   EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
 
-  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
-
   // By default, all actions should be visible.
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, browser_action_a()->id()));
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, browser_action_b()->id()));
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, browser_action_c()->id()));
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(browser_action_a()->id()));
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(browser_action_b()->id()));
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(browser_action_c()->id()));
 
   // Hiding an action should result in its removal from the toolbar.
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, browser_action_b()->id(), false);
-  EXPECT_FALSE(ExtensionActionAPI::GetBrowserActionVisibility(
-                   prefs, browser_action_b()->id()));
+  action_api->SetBrowserActionVisibility(browser_action_b()->id(), false);
+  EXPECT_FALSE(action_api->GetBrowserActionVisibility(
+      browser_action_b()->id()));
   // Thus, there should now only be two items on the toolbar - A and C.
   EXPECT_EQ(2u, num_toolbar_items());
   EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
@@ -811,10 +807,8 @@
 
   // Resetting the visibility to 'true' should result in the extension being
   // added back at its original position.
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, browser_action_b()->id(), true);
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, browser_action_b()->id()));
+  action_api->SetBrowserActionVisibility(browser_action_b()->id(), true);
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(browser_action_b()->id()));
   // So the toolbar order should be A B C.
   EXPECT_EQ(3u, num_toolbar_items());
   EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
@@ -1013,19 +1007,15 @@
   EXPECT_EQ(extension_b, GetExtensionAtIndex(1u));
   EXPECT_EQ(extension_c, GetExtensionAtIndex(2u));
 
-  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
+  ExtensionActionAPI* action_api = ExtensionActionAPI::Get(profile());
 
   // By default, all actions should be visible.
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, extension_a->id()));
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, extension_c->id()));
-  EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
-                  prefs, extension_b->id()));
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(extension_a->id()));
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(extension_c->id()));
+  EXPECT_TRUE(action_api->GetBrowserActionVisibility(extension_b->id()));
 
   // Hiding an action should result in it being sent to the overflow menu.
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, extension_b->id(), false);
+  action_api->SetBrowserActionVisibility(extension_b->id(), false);
 
   // Thus, the order should be A C B, with B in the overflow.
   EXPECT_EQ(3u, num_toolbar_items());
@@ -1036,8 +1026,7 @@
 
   // Hiding an extension's action should result in it being sent to the overflow
   // as well, but as the _first_ extension in the overflow.
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, extension_a->id(), false);
+  action_api->SetBrowserActionVisibility(extension_a->id(), false);
   // Thus, the order should be C A B, with A and B in the overflow.
   EXPECT_EQ(3u, num_toolbar_items());
   EXPECT_EQ(1u, toolbar_model()->visible_icon_count());
@@ -1048,8 +1037,7 @@
   // Resetting A's visibility to true should send it back to the visible icons
   // (and should grow visible icons by 1), but it should be added to the end of
   // the visible icon list (not to its original position).
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, extension_a->id(), true);
+  action_api->SetBrowserActionVisibility(extension_a->id(), true);
   // So order is C A B, with only B in the overflow.
   EXPECT_EQ(3u, num_toolbar_items());
   EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
@@ -1058,8 +1046,7 @@
   EXPECT_EQ(extension_b, GetExtensionAtIndex(2u));
 
   // Resetting B to be visible should make the order C A B, with no overflow.
-  ExtensionActionAPI::SetBrowserActionVisibility(
-      prefs, extension_b->id(), true);
+  action_api->SetBrowserActionVisibility(extension_b->id(), true);
   EXPECT_EQ(3u, num_toolbar_items());
   EXPECT_TRUE(toolbar_model()->all_icons_visible());
   EXPECT_EQ(extension_c, GetExtensionAtIndex(0u));
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client.cc b/chrome/browser/favicon/chrome_fallback_icon_client.cc
index 29651d2..292625e9 100644
--- a/chrome/browser/favicon/chrome_fallback_icon_client.cc
+++ b/chrome/browser/favicon/chrome_fallback_icon_client.cc
@@ -11,6 +11,10 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
 
+namespace {
+const char* kFallbackIconTextForIP = "IP";
+}  // namespace
+
 ChromeFallbackIconClient::ChromeFallbackIconClient() {
 #if defined(OS_CHROMEOS)
   font_list_.push_back("Noto Sans");
@@ -33,9 +37,17 @@
 // letter in a domain's name and make it upper case.
 base::string16 ChromeFallbackIconClient::GetFallbackIconText(const GURL& url)
     const {
-  // TODO(huangs): Handle non-ASCII ("xn--") domain names.
+  if (url.is_empty())
+    return base::string16();
   std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
       url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
-  return domain.empty() ? base::string16() :
-      base::i18n::ToUpper(base::ASCIIToUTF16(domain.substr(0, 1)));
+  if (domain.empty()) {  // E.g., http://localhost/ or http://192.168.0.1/
+    if (url.HostIsIPAddress())
+      return base::ASCIIToUTF16(kFallbackIconTextForIP);
+    domain = url.host();
+  }
+  if (domain.empty())
+    return base::string16();
+  // TODO(huangs): Handle non-ASCII ("xn--") domain names.
+  return base::i18n::ToUpper(base::ASCIIToUTF16(domain.substr(0, 1)));
 }
diff --git a/chrome/browser/favicon/chrome_fallback_icon_client_unittest.cc b/chrome/browser/favicon/chrome_fallback_icon_client_unittest.cc
new file mode 100644
index 0000000..81a6b894
--- /dev/null
+++ b/chrome/browser/favicon/chrome_fallback_icon_client_unittest.cc
@@ -0,0 +1,55 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/favicon/chrome_fallback_icon_client.h"
+
+#include "base/macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+TEST(ChromeFallbackIconClientTest, GetFontNameList) {
+  ChromeFallbackIconClient client;
+  // Just ensure non-empty, otherwise not checking the actual font.
+  EXPECT_FALSE(client.GetFontNameList().empty());
+}
+
+TEST(ChromeFallbackIconClientTest, GetFallbackIconText) {
+  struct {
+    const char* url_str;
+    const char* expected;
+  } test_cases[] = {
+    // Test vacuous or invalid cases.
+    {"", ""},
+    {"http:///", ""},
+    {"this is not an URL", ""},
+    {"!@#$%^&*()", ""},
+    // Test URLs with a domain in the registry.
+    {"http://www.google.com/", "G"},
+    {"ftp://GOogLE.com/", "G"},
+    {"https://www.google.com:8080/path?query#ref", "G"},
+    {"http://www.amazon.com", "A"},
+    {"http://zmzaon.co.uk/", "Z"},
+    {"http://w-3.137.org", "1"},
+    // Test URLs with a domian not in the registry.
+    {"http://localhost/", "L"},
+    {"chrome-search://local-ntp/local-ntp.html", "L"},
+    // Test IP URLs.
+    {"http://192.168.0.1/", "IP"},
+    {"http://[2001:4860:4860::8888]/", "IP"},
+    // Miscellaneous edge cases.
+    {"http://www..com/", "."},
+    {"http://ip.ip/", "I"},
+    // xn-- related cases: we're not supporint xn-- yet
+    {"http://xn--oogle-60a/", "X"},
+    {"http://xn-oogle-60a/", "X"},
+  };
+  for (size_t i = 0; i < arraysize(test_cases); ++i) {
+    ChromeFallbackIconClient client;
+    base::string16 expected = base::ASCIIToUTF16(test_cases[i].expected);
+    GURL url(test_cases[i].url_str);
+    EXPECT_EQ(expected, client.GetFallbackIconText(url))
+        << " for test_cases[" << i << "]";
+  }
+}
diff --git a/chrome/browser/favicon/large_icon_service_factory.cc b/chrome/browser/favicon/large_icon_service_factory.cc
new file mode 100644
index 0000000..56890cb
--- /dev/null
+++ b/chrome/browser/favicon/large_icon_service_factory.cc
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/favicon/large_icon_service_factory.h"
+
+#include "base/memory/singleton.h"
+#include "chrome/browser/favicon/favicon_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/favicon/core/favicon_service.h"
+#include "components/favicon/core/large_icon_service.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/browser_context.h"
+
+// static
+favicon::LargeIconService* LargeIconServiceFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<favicon::LargeIconService*>(
+      GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+LargeIconServiceFactory* LargeIconServiceFactory::GetInstance() {
+  return Singleton<LargeIconServiceFactory>::get();
+}
+
+LargeIconServiceFactory::LargeIconServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+        "LargeIconService",
+        BrowserContextDependencyManager::GetInstance()) {
+  DependsOn(FaviconServiceFactory::GetInstance());
+}
+
+LargeIconServiceFactory::~LargeIconServiceFactory() {}
+
+KeyedService* LargeIconServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  favicon::FaviconService* favicon_service =
+      FaviconServiceFactory::GetForProfile(Profile::FromBrowserContext(context),
+                                           ServiceAccessType::EXPLICIT_ACCESS);
+  return new favicon::LargeIconService(favicon_service);
+}
+
+bool LargeIconServiceFactory::ServiceIsNULLWhileTesting() const {
+  return true;
+}
diff --git a/chrome/browser/favicon/large_icon_service_factory.h b/chrome/browser/favicon/large_icon_service_factory.h
new file mode 100644
index 0000000..46a9e5bb
--- /dev/null
+++ b/chrome/browser/favicon/large_icon_service_factory.h
@@ -0,0 +1,43 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_FAVICON_LARGE_ICON_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_FAVICON_LARGE_ICON_SERVICE_FACTORY_H_
+
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+template <typename T> struct DefaultSingletonTraits;
+
+namespace content {
+class BrowserContext;
+}
+
+namespace favicon {
+class LargeIconService;
+}
+
+// Singleton that owns all LargeIconService and associates them with
+// BrowserContext instances.
+class LargeIconServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static favicon::LargeIconService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  static LargeIconServiceFactory* GetInstance();
+
+ private:
+  friend struct DefaultSingletonTraits<LargeIconServiceFactory>;
+
+  LargeIconServiceFactory();
+  ~LargeIconServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+  bool ServiceIsNULLWhileTesting() const override;
+
+  DISALLOW_COPY_AND_ASSIGN(LargeIconServiceFactory);
+};
+
+#endif  // CHROME_BROWSER_FAVICON_LARGE_ICON_SERVICE_FACTORY_H_
diff --git a/chrome/browser/history/top_sites_impl.cc b/chrome/browser/history/top_sites_impl.cc
index 92032e9..e904643e 100644
--- a/chrome/browser/history/top_sites_impl.cc
+++ b/chrome/browser/history/top_sites_impl.cc
@@ -32,7 +32,6 @@
 #include "components/history/core/browser/top_sites_cache.h"
 #include "components/history/core/browser/url_utils.h"
 #include "components/history/core/common/thumbnail_score.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
@@ -44,7 +43,6 @@
 #include "ui/gfx/image/image_util.h"
 
 using base::DictionaryValue;
-using content::BrowserThread;
 using content::NavigationController;
 
 namespace history {
@@ -136,7 +134,7 @@
 bool TopSitesImpl::SetPageThumbnail(const GURL& url,
                                     const gfx::Image& thumbnail,
                                     const ThumbnailScore& score) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   if (!loaded_) {
     // TODO(sky): I need to cache these and apply them after the load
@@ -175,7 +173,7 @@
     const GURL& url,
     const base::RefCountedMemory* memory,
     const ThumbnailScore& score) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   if (!loaded_) {
     // TODO(sky): I need to cache these and apply them after the load
@@ -310,7 +308,7 @@
 }
 
 void TopSitesImpl::SyncWithHistory() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   if (loaded_ && temp_images_.size()) {
     // If we have temporary thumbnails it means there isn't much data, and most
     // likely the user is first running Chrome. During this time we throttle
@@ -329,7 +327,7 @@
 }
 
 void TopSitesImpl::AddBlacklistedURL(const GURL& url) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   base::Value* dummy = base::Value::CreateNullValue();
   {
@@ -344,7 +342,7 @@
 }
 
 void TopSitesImpl::RemoveBlacklistedURL(const GURL& url) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   {
     DictionaryPrefUpdate update(profile_->GetPrefs(),
                                 prefs::kNtpMostVisitedURLsBlacklist);
@@ -356,14 +354,14 @@
 }
 
 bool TopSitesImpl::IsBlacklisted(const GURL& url) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   const base::DictionaryValue* blacklist =
       profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist);
   return blacklist && blacklist->HasKey(GetURLHash(url));
 }
 
 void TopSitesImpl::ClearBlacklistedURLs() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   {
     DictionaryPrefUpdate update(profile_->GetPrefs(),
                                 prefs::kNtpMostVisitedURLsBlacklist);
@@ -600,7 +598,7 @@
 }
 
 bool TopSitesImpl::AddForcedURL(const GURL& url, const base::Time& time) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   size_t num_forced = cache_->GetNumForcedURLs();
   MostVisitedURLList new_list(cache_->top_sites());
   MostVisitedURL new_url;
@@ -646,7 +644,7 @@
 }
 
 size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   // Add all the new URLs for quick lookup. Take that opportunity to count the
   // number of forced URLs in |new_list|.
   std::set<GURL> all_new_urls;
@@ -757,7 +755,7 @@
 
 void TopSitesImpl::SetTopSites(const MostVisitedURLList& new_top_sites,
                                const CallLocation location) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   MostVisitedURLList top_sites(new_top_sites);
   size_t num_forced_urls = MergeCachedForcedURLs(&top_sites);
@@ -826,7 +824,7 @@
 }
 
 int TopSitesImpl::num_results_to_request_from_history() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   const base::DictionaryValue* blacklist =
       profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist);
@@ -834,7 +832,7 @@
 }
 
 void TopSitesImpl::MoveStateToLoaded() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   MostVisitedURLList filtered_urls_all;
   MostVisitedURLList filtered_urls_nonforced;
@@ -896,7 +894,7 @@
 
 void TopSitesImpl::OnGotMostVisitedThumbnails(
     const scoped_refptr<MostVisitedThumbnails>& thumbnails) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   // Set the top sites directly in the cache so that SetTopSites diffs
   // correctly.
diff --git a/chrome/browser/history/top_sites_impl.h b/chrome/browser/history/top_sites_impl.h
index cef762a6..eb9a6ca8 100644
--- a/chrome/browser/history/top_sites_impl.h
+++ b/chrome/browser/history/top_sites_impl.h
@@ -18,6 +18,7 @@
 #include "base/scoped_observer.h"
 #include "base/synchronization/lock.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "components/history/core/browser/history_service.h"
@@ -244,6 +245,10 @@
                      const std::set<GURL>& favicon_urls) override;
   void HistoryServiceBeingDeleted(HistoryService* history_service) override;
 
+
+  // Ensures that non thread-safe methods are called on the correct thread.
+  base::ThreadChecker thread_checker_;
+
   scoped_refptr<TopSitesBackend> backend_;
 
   // The top sites data.
diff --git a/chrome/browser/image_decoder.cc b/chrome/browser/image_decoder.cc
index b0b9ce8..f8f736a 100644
--- a/chrome/browser/image_decoder.cc
+++ b/chrome/browser/image_decoder.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/image_decoder.h"
 
 #include "base/bind.h"
+#include "base/thread_task_runner_handle.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "chrome/grit/generated_resources.h"
@@ -36,12 +37,19 @@
 ImageDecoder::~ImageDecoder() {
 }
 
+ImageDecoder::ImageRequest::ImageRequest()
+    : task_runner_(base::ThreadTaskRunnerHandle::Get()) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+}
+
 ImageDecoder::ImageRequest::ImageRequest(
     const scoped_refptr<base::SequencedTaskRunner>& task_runner)
     : task_runner_(task_runner) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
 }
 
 ImageDecoder::ImageRequest::~ImageRequest() {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
   ImageDecoder::Cancel(this);
 }
 
@@ -56,13 +64,29 @@
                                     const std::string& image_data,
                                     ImageCodec image_codec,
                                     bool shrink_to_fit) {
+  g_decoder.Pointer()->StartWithOptionsImpl(image_request, image_data,
+                                            image_codec, shrink_to_fit);
+}
+
+void ImageDecoder::StartWithOptionsImpl(ImageRequest* image_request,
+                                        const std::string& image_data,
+                                        ImageCodec image_codec,
+                                        bool shrink_to_fit) {
   DCHECK(image_request);
   DCHECK(image_request->task_runner());
+
+  int request_id;
+  {
+    base::AutoLock lock(map_lock_);
+    request_id = image_request_id_counter_++;
+    image_request_id_map_.insert(std::make_pair(request_id, image_request));
+  }
+
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
       base::Bind(
           &ImageDecoder::DecodeImageInSandbox,
-          g_decoder.Pointer(), image_request,
+          g_decoder.Pointer(), request_id,
           std::vector<unsigned char>(image_data.begin(), image_data.end()),
           image_codec, shrink_to_fit));
 }
@@ -74,11 +98,17 @@
 }
 
 void ImageDecoder::DecodeImageInSandbox(
-    ImageRequest* image_request,
+    int request_id,
     const std::vector<unsigned char>& image_data,
     ImageCodec image_codec,
     bool shrink_to_fit) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  base::AutoLock lock(map_lock_);
+  const auto it = image_request_id_map_.find(request_id);
+  if (it == image_request_id_map_.end())
+    return;
+
+  ImageRequest* image_request = it->second;
   if (!utility_process_host_) {
     StartBatchMode();
   }
@@ -88,28 +118,23 @@
     // investigation is needed to determine why the utility process
     // is failing to start. See crbug.com/472272
     image_request->task_runner()->PostTask(
-        FROM_HERE, base::Bind(&ImageRequest::OnDecodeImageFailed,
-                              base::Unretained(image_request)));
+        FROM_HERE,
+        base::Bind(&ImageDecoder::RunOnDecodeImageFailed, this, request_id));
     return;
   }
 
   last_request_ = base::TimeTicks::Now();
-  base::AutoLock lock(map_lock_);
-  image_request_id_map_.insert(
-      std::make_pair(image_request_id_counter_, image_request));
 
   switch (image_codec) {
     case ROBUST_JPEG_CODEC:
       utility_process_host_->Send(new ChromeUtilityMsg_RobustJPEGDecodeImage(
-          image_data, image_request_id_counter_));
+          image_data, request_id));
       break;
     case DEFAULT_CODEC:
       utility_process_host_->Send(new ChromeUtilityMsg_DecodeImage(
-          image_data, shrink_to_fit, image_request_id_counter_));
+          image_data, shrink_to_fit, request_id));
       break;
   }
-
-  ++image_request_id_counter_;
 }
 
 void ImageDecoder::CancelImpl(ImageRequest* image_request) {
@@ -173,26 +198,58 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   base::AutoLock lock(map_lock_);
   auto it = image_request_id_map_.find(request_id);
-  if (it != image_request_id_map_.end()) {
-    ImageRequest* image_request = it->second;
-    image_request->task_runner()->PostTask(
-        FROM_HERE, base::Bind(&ImageRequest::OnImageDecoded,
-                              base::Unretained(image_request), decoded_image));
+  if (it == image_request_id_map_.end())
+    return;
 
-    image_request_id_map_.erase(it);
-  }
+  ImageRequest* image_request = it->second;
+  image_request->task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ImageDecoder::RunOnImageDecoded,
+                 this,
+                 decoded_image,
+                 request_id));
 }
 
 void ImageDecoder::OnDecodeImageFailed(int request_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   base::AutoLock lock(map_lock_);
   auto it = image_request_id_map_.find(request_id);
-  if (it != image_request_id_map_.end()) {
-    ImageRequest* image_request = it->second;
-    image_request->task_runner()->PostTask(
-        FROM_HERE, base::Bind(&ImageRequest::OnDecodeImageFailed,
-                              base::Unretained(image_request)));
+  if (it == image_request_id_map_.end())
+    return;
 
+  ImageRequest* image_request = it->second;
+  image_request->task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ImageDecoder::RunOnDecodeImageFailed, this, request_id));
+}
+
+void ImageDecoder::RunOnImageDecoded(const SkBitmap& decoded_image,
+                                     int request_id) {
+  ImageRequest* image_request;
+  {
+    base::AutoLock lock(map_lock_);
+    auto it = image_request_id_map_.find(request_id);
+    if (it == image_request_id_map_.end())
+      return;
+    image_request = it->second;
     image_request_id_map_.erase(it);
   }
+
+  DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread());
+  image_request->OnImageDecoded(decoded_image);
+}
+
+void ImageDecoder::RunOnDecodeImageFailed(int request_id) {
+  ImageRequest* image_request;
+  {
+    base::AutoLock lock(map_lock_);
+    auto it = image_request_id_map_.find(request_id);
+    if (it == image_request_id_map_.end())
+      return;
+    image_request = it->second;
+    image_request_id_map_.erase(it);
+  }
+
+  DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread());
+  image_request->OnDecodeImageFailed();
 }
diff --git a/chrome/browser/image_decoder.h b/chrome/browser/image_decoder.h
index 438622c4..ca76043 100644
--- a/chrome/browser/image_decoder.h
+++ b/chrome/browser/image_decoder.h
@@ -9,11 +9,11 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/lazy_instance.h"
 #include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
 #include "base/synchronization/lock.h"
-#include "base/threading/sequenced_worker_pool.h"
 #include "base/timer/timer.h"
 #include "content/public/browser/utility_process_host.h"
 #include "content/public/browser/utility_process_host_client.h"
@@ -32,6 +32,8 @@
 // to protect the data that is accessed from multiple threads.
 class ImageDecoder : public content::UtilityProcessHostClient {
  public:
+  // ImageRequest objects needs to be created and destroyed on the same
+  // SequencedTaskRunner.
   class ImageRequest {
    public:
     // Called when image is decoded.
@@ -46,14 +48,20 @@
     }
 
    protected:
+    // Creates an ImageRequest that runs on the thread creating it.
+    ImageRequest();
+    // Explicitly pass in |task_runner| if the current thread is part of a
+    // thread pool.
     explicit ImageRequest(
         const scoped_refptr<base::SequencedTaskRunner>& task_runner);
     virtual ~ImageRequest();
 
    private:
-    // The thread to post OnImageDecoded or OnDecodeImageFailed once the
+    // The thread to post OnImageDecoded() or OnDecodeImageFailed() once the
     // the image has been decoded.
     const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+    base::SequenceChecker sequence_checker_;
   };
 
   enum ImageCodec {
@@ -61,7 +69,7 @@
     ROBUST_JPEG_CODEC,  // Restrict decoding to robust jpeg codec.
   };
 
-  // Calls StartWithOptions with ImageCodec::DEFAULT_CODEC and
+  // Calls StartWithOptions() with ImageCodec::DEFAULT_CODEC and
   // shrink_to_fit = false.
   static void Start(ImageRequest* image_request,
                     const std::string& image_data);
@@ -73,13 +81,15 @@
                                ImageCodec image_codec,
                                bool shrink_to_fit);
 
-  // Removes all instances of image_request from |image_request_id_map_|,
+  // Removes all instances of |image_request| from |image_request_id_map_|,
   // ensuring callbacks are not made to the image_request after it is destroyed.
   static void Cancel(ImageRequest* image_request);
 
  private:
   friend struct base::DefaultLazyInstanceTraits<ImageDecoder>;
 
+  using RequestMap = std::map<int, ImageRequest*>;
+
   ImageDecoder();
   // It's a reference counted object, so destructor is private.
   ~ImageDecoder() override;
@@ -87,22 +97,24 @@
   // Sends a request to the sandboxed process to decode the image. Starts
   // batch mode if necessary. If the utility process fails to start,
   // an OnDecodeImageFailed task is posted to image_request's |task_runner_|.
-  void DecodeImageInSandbox(ImageRequest* image_request,
+  void DecodeImageInSandbox(int request_id,
                             const std::vector<unsigned char>& image_data,
                             ImageCodec image_codec,
                             bool shrink_to_fit);
 
+  void StartWithOptionsImpl(ImageRequest* image_request,
+                            const std::string& image_data,
+                            ImageCodec image_codec,
+                            bool shrink_to_fit);
   void CancelImpl(ImageRequest* image_request);
 
-  using RequestMap = std::map<int, ImageRequest*>;
-
   // Starts UtilityProcessHost in batch mode and starts |batch_mode_timer_|.
   // If the utility process fails to start, the method resets
   // |utility_process_host_| and returns.
   void StartBatchMode();
 
   // Stops batch mode if no requests have come in since
-  // kBatchModeTimeoutSeconds.
+  // |kBatchModeTimeoutSeconds|.
   void StopBatchMode();
 
   // Overidden from UtilityProcessHostClient.
@@ -112,7 +124,12 @@
   void OnDecodeImageSucceeded(const SkBitmap& decoded_image, int request_id);
   void OnDecodeImageFailed(int request_id);
 
-  // id to use for the next Start request that comes in.
+  // For the ImageRequest identified by |request_id|, call its OnImageDecoded()
+  // or OnDecodeImageFailed() method on its task runner thread.
+  void RunOnImageDecoded(const SkBitmap& decoded_image, int request_id);
+  void RunOnDecodeImageFailed(int request_id);
+
+  // id to use for the next Start() request that comes in.
   int image_request_id_counter_;
 
   // Map of request id's to ImageRequests.
@@ -124,10 +141,10 @@
   // The UtilityProcessHost requests are sent to.
   base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
 
-  // Calls StopBatchMode after kBatchModeTimeoutSeconds have elapsed.
+  // Calls StopBatchMode() after |kBatchModeTimeoutSeconds| have elapsed.
   base::RepeatingTimer<ImageDecoder> batch_mode_timer_;
 
-  // The time Start was last called.
+  // The time Start() was last called.
   base::TimeTicks last_request_;
 
   DISALLOW_COPY_AND_ASSIGN(ImageDecoder);
diff --git a/chrome/browser/image_decoder_browsertest.cc b/chrome/browser/image_decoder_browsertest.cc
new file mode 100644
index 0000000..5621815
--- /dev/null
+++ b/chrome/browser/image_decoder_browsertest.cc
@@ -0,0 +1,70 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/image_decoder.h"
+
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/test_utils.h"
+
+using content::BrowserThread;
+
+namespace {
+
+class TestImageRequest : public ImageDecoder::ImageRequest {
+ public:
+  explicit TestImageRequest(const base::Closure& quit_closure)
+      : quit_closure_(quit_closure),
+        quit_called_(false) {
+  }
+
+  ~TestImageRequest() override {
+    if (!quit_called_) {
+      quit_closure_.Run();
+    }
+  }
+
+ private:
+  void OnImageDecoded(const SkBitmap& decoded_image) override {
+    Quit();
+  }
+
+  void OnDecodeImageFailed() override {
+    Quit();
+  }
+
+  void Quit() {
+    EXPECT_FALSE(quit_called_);
+    quit_called_ = true;
+    quit_closure_.Run();
+  }
+
+  base::Closure quit_closure_;
+  bool quit_called_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestImageRequest);
+};
+
+}  // namespace
+
+class ImageDecoderBrowserTest : public InProcessBrowserTest {
+};
+
+IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, Basic) {
+  scoped_refptr<content::MessageLoopRunner> runner =
+      new content::MessageLoopRunner;
+  TestImageRequest test_request(runner->QuitClosure());
+  ImageDecoder::Start(&test_request, std::string());
+  runner->Run();
+}
+
+IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, StartAndDestroy) {
+  scoped_refptr<content::MessageLoopRunner> runner =
+      new content::MessageLoopRunner;
+  scoped_ptr<TestImageRequest> test_request(
+      new TestImageRequest(runner->QuitClosure()));
+  ImageDecoder::Start(test_request.get(), std::string());
+  test_request.reset();
+  runner->Run();
+}
diff --git a/chrome/browser/image_holder_unittest.cc b/chrome/browser/image_holder_unittest.cc
index 948f11e5..03da2ca3 100644
--- a/chrome/browser/image_holder_unittest.cc
+++ b/chrome/browser/image_holder_unittest.cc
@@ -5,6 +5,7 @@
 #include <string>
 
 #include "chrome/browser/image_holder.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -15,11 +16,20 @@
 class TestDelegate : public chrome::ImageHolderDelegate {
  public:
   TestDelegate() : on_fetch_complete_called_(false) {}
+
+  bool on_fetch_complete_called() const { return on_fetch_complete_called_; }
+
+  // chrome::ImageHolderDelegate
   void OnFetchComplete() override { on_fetch_complete_called_ = true; }
+
+ private:
+  content::TestBrowserThreadBundle thread_bundle_;
   bool on_fetch_complete_called_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestDelegate);
 };
 
-}  // namespace.
+}  // namespace
 
 namespace chrome {
 
@@ -27,22 +37,23 @@
 
 TEST_F(ImageHolderTest, CreateBitmapFetcherTest) {
   TestDelegate delegate;
-  ImageHolder image_holder(GURL(kIconUrl1), GURL(kIconUrl2), NULL, &delegate);
+  ImageHolder image_holder(GURL(kIconUrl1), GURL(kIconUrl2), nullptr,
+                           &delegate);
 
+  ASSERT_EQ(2U, image_holder.fetchers_.size());
   EXPECT_EQ(GURL(kIconUrl1), image_holder.fetchers_[0]->url());
   EXPECT_EQ(GURL(kIconUrl2), image_holder.fetchers_[1]->url());
-  EXPECT_EQ(static_cast<unsigned int>(2), image_holder.fetchers_.size());
 
   // Adding a dup of an existing URL shouldn't change anything.
   image_holder.CreateBitmapFetcher(GURL(kIconUrl2));
+  ASSERT_EQ(2U, image_holder.fetchers_.size());
   EXPECT_EQ(GURL(kIconUrl1), image_holder.fetchers_[0]->url());
   EXPECT_EQ(GURL(kIconUrl2), image_holder.fetchers_[1]->url());
-  EXPECT_EQ(static_cast<unsigned int>(2), image_holder.fetchers_.size());
 }
 
 TEST_F(ImageHolderTest, OnFetchCompleteTest) {
   TestDelegate delegate;
-  ImageHolder image_holder(GURL(kIconUrl1), GURL(), NULL, &delegate);
+  ImageHolder image_holder(GURL(kIconUrl1), GURL(), nullptr, &delegate);
 
   // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
   SkBitmap bitmap;
@@ -55,15 +66,16 @@
   EXPECT_FALSE(image_holder.low_dpi_image().IsEmpty());
 
   // Expect that we reported the fetch done to the delegate.
-  EXPECT_TRUE(delegate.on_fetch_complete_called_);
+  EXPECT_TRUE(delegate.on_fetch_complete_called());
 }
 
 TEST_F(ImageHolderTest, IsFetchingDoneTest) {
   TestDelegate delegate;
-  ImageHolder image_holder1(GURL(kIconUrl1), GURL(kIconUrl2), NULL, &delegate);
-  ImageHolder image_holder2(GURL(kIconUrl1), GURL(), NULL, &delegate);
-  ImageHolder image_holder3(GURL(), GURL(kIconUrl2), NULL, &delegate);
-  ImageHolder image_holder4(GURL(), GURL(), NULL, &delegate);
+  ImageHolder image_holder1(GURL(kIconUrl1), GURL(kIconUrl2), nullptr,
+                            &delegate);
+  ImageHolder image_holder2(GURL(kIconUrl1), GURL(), nullptr, &delegate);
+  ImageHolder image_holder3(GURL(), GURL(kIconUrl2), nullptr, &delegate);
+  ImageHolder image_holder4(GURL(), GURL(), nullptr, &delegate);
 
   // Initially, image holder 4 with no URLs should report done, but no others.
   EXPECT_FALSE(image_holder1.IsFetchingDone());
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 097e8a6..34fe6b88 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -781,10 +781,30 @@
       new net::ChannelIDService(
           new net::DefaultChannelIDStore(NULL),
           base::WorkerPool::GetTaskRunner(true)));
+  // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466432
+  // is fixed.
+  tracked_objects::ScopedTracker tracking_profile12_1(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "466432 IOThread::InitAsync::CreateDnsProbeService"));
   globals_->dns_probe_service.reset(new chrome_browser_net::DnsProbeService());
+  // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466432
+  // is fixed.
+  tracked_objects::ScopedTracker tracking_profile12_2(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "466432 IOThread::InitAsync::CreateHostMappingRules"));
   globals_->host_mapping_rules.reset(new net::HostMappingRules());
+  // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466432
+  // is fixed.
+  tracked_objects::ScopedTracker tracking_profile12_3(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "466432 IOThread::InitAsync::CreateHTTPUserAgentSettings"));
   globals_->http_user_agent_settings.reset(
       new net::StaticHttpUserAgentSettings(std::string(), GetUserAgent()));
+  // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466432
+  // is fixed.
+  tracked_objects::ScopedTracker tracking_profile12_4(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "466432 IOThread::InitAsync::CommandLineConfiguration"));
   if (command_line.HasSwitch(switches::kHostRules)) {
     TRACE_EVENT_BEGIN0("startup", "IOThread::InitAsync:SetRulesFromString");
     globals_->host_mapping_rules->SetRulesFromString(
@@ -803,6 +823,11 @@
     globals_->testing_fixed_https_port =
         GetSwitchValueAsInt(command_line, switches::kTestingFixedHttpsPort);
   }
+  // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466432
+  // is fixed.
+  tracked_objects::ScopedTracker tracking_profile12_5(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "466432 IOThread::InitAsync::QuicConfiguration"));
   ConfigureQuic(command_line);
   if (command_line.HasSwitch(
           switches::kEnableUserAlternateProtocolPorts)) {
diff --git a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
index f7079817..41b733e 100644
--- a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
@@ -480,6 +480,14 @@
   return wav_filename;
 }
 
+void DeleteFileUnlessTestFailed(const base::FilePath& path, bool recursive) {
+  if (::testing::Test::HasFailure())
+    printf("Test failed; keeping recording(s) at\n\t%" PRFilePath ".\n",
+           path.value().c_str());
+  else
+    EXPECT_TRUE(base::DeleteFile(path, recursive));
+}
+
 std::vector<base::FilePath> ListWavFilesInDir(const base::FilePath& dir) {
   base::FileEnumerator files(dir, false, base::FileEnumerator::FILES,
                              FILE_PATH_LITERAL("*.wav"));
@@ -503,7 +511,7 @@
 
   ASSERT_TRUE(SplitFileOnSilence(
       trimmed_audio, workdir.Append(FILE_PATH_LITERAL("output.wav"))));
-  ASSERT_TRUE(base::DeleteFile(trimmed_audio, false));
+  DeleteFileUnlessTestFailed(trimmed_audio, false);
 }
 
 // Computes the difference between the actual and reference segment. A positive
@@ -575,16 +583,18 @@
 
   std::string raw_mos;
   std::string mos_lqo;
-  ASSERT_TRUE(RunPesq(trimmed_reference, trimmed_recording, 16000,
-                      &raw_mos, &mos_lqo));
+  bool succeeded = RunPesq(trimmed_reference, trimmed_recording, 16000,
+                           &raw_mos, &mos_lqo);
+  EXPECT_TRUE(succeeded) << "Failed to run PESQ.";
+  if (succeeded) {
+    perf_test::PrintResult(
+        "audio_pesq", perf_modifier, "raw_mos", raw_mos, "score", true);
+    perf_test::PrintResult(
+        "audio_pesq", perf_modifier, "mos_lqo", mos_lqo, "score", true);
+  }
 
-  perf_test::PrintResult(
-      "audio_pesq", perf_modifier, "raw_mos", raw_mos, "score", true);
-  perf_test::PrintResult(
-      "audio_pesq", perf_modifier, "mos_lqo", mos_lqo, "score", true);
-
-  EXPECT_TRUE(base::DeleteFile(trimmed_reference, false));
-  EXPECT_TRUE(base::DeleteFile(trimmed_recording, false));
+  DeleteFileUnlessTestFailed(trimmed_reference, false);
+  DeleteFileUnlessTestFailed(trimmed_recording, false);
 }
 
 }  // namespace
@@ -649,9 +659,9 @@
   ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall(
       reference_file, recording, kAudioOnlyCallConstraints,
       base::TimeDelta::FromSeconds(25)));
-  ComputeAndPrintPesqResults(reference_file, recording, "_getusermedia");
 
-  EXPECT_TRUE(base::DeleteFile(recording, false));
+  ComputeAndPrintPesqResults(reference_file, recording, "_getusermedia");
+  DeleteFileUnlessTestFailed(recording, false);
 }
 
 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
@@ -744,8 +754,6 @@
       reference_file, recording, constraints,
       base::TimeDelta::FromSeconds(25)));
 
-  // Call Take() on the scoped temp dirs if you want to look at the files after
-  // the test exits (the default is to delete the files).
   base::ScopedTempDir split_ref_files;
   ASSERT_TRUE(split_ref_files.CreateUniqueTempDir());
   ASSERT_NO_FATAL_FAILURE(
@@ -757,13 +765,17 @@
   ASSERT_TRUE(split_actual_files.CreateUniqueTempDir());
   ASSERT_NO_FATAL_FAILURE(
       SplitFileOnSilenceIntoDir(recording, split_actual_files.path()));
+
+  // Keep the recording and split files if the analysis fails.
+  base::FilePath actual_files_dir = split_actual_files.Take();
   std::vector<base::FilePath> actual_segments =
-      ListWavFilesInDir(split_actual_files.path());
+      ListWavFilesInDir(actual_files_dir);
 
-  AnalyzeSegmentsAndPrintResult(ref_segments, actual_segments, reference_file,
-                                perf_modifier);
+  AnalyzeSegmentsAndPrintResult(
+      ref_segments, actual_segments, reference_file, perf_modifier);
 
-  EXPECT_TRUE(base::DeleteFile(recording, false));
+  DeleteFileUnlessTestFailed(recording, false);
+  DeleteFileUnlessTestFailed(actual_files_dir, true);
 }
 
 // The AGC should apply non-zero gain here.
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 ac590cd..2e83a76 100644
--- a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
+++ b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
@@ -52,9 +52,7 @@
   ImageDecoderDelegateAdapter(
       scoped_ptr<std::string> data,
       const storage::CopyOrMoveFileValidator::ResultCallback& callback)
-      : ImageRequest(content::BrowserThread::GetMessageLoopProxyForThread(
-            BrowserThread::IO)),
-        data_(data.Pass()),
+      : data_(data.Pass()),
         callback_(callback) {
     DCHECK(data_);
   }
diff --git a/chrome/browser/net/certificate_error_reporter.cc b/chrome/browser/net/certificate_error_reporter.cc
index 8d5b5d8..279209c 100644
--- a/chrome/browser/net/certificate_error_reporter.cc
+++ b/chrome/browser/net/certificate_error_reporter.cc
@@ -48,7 +48,7 @@
       break;
     case REPORT_TYPE_EXTENDED_REPORTING:
       // TODO(estark): Encrypt the report if not sending over HTTPS.
-      DCHECK(upload_url_.SchemeUsesTLS());
+      DCHECK(upload_url_.SchemeIsCryptographic());
       SendCertLoggerRequest(request);
       break;
     default:
diff --git a/chrome/browser/net/chrome_net_log.cc b/chrome/browser/net/chrome_net_log.cc
index 1dda8cce..674ee64 100644
--- a/chrome/browser/net/chrome_net_log.cc
+++ b/chrome/browser/net/chrome_net_log.cc
@@ -19,14 +19,52 @@
 #include "net/log/trace_net_log_observer.h"
 #include "net/log/write_to_file_net_log_observer.h"
 
+namespace {
+
+net::NetLogCaptureMode GetCaptureModeFromCommandLine(
+    const base::CommandLine& command_line) {
+  const net::NetLogCaptureMode kDefault = net::NetLogCaptureMode::Default();
+
+  // TODO(eroman): The NetLog "capture mode" used to be called the "log
+  // level". To preserve backwards compatibility the log level of old is
+  // converted into a capture mode.
+  if (!command_line.HasSwitch(switches::kNetLogLevel))
+    return kDefault;
+
+  std::string log_level_string =
+      command_line.GetSwitchValueASCII(switches::kNetLogLevel);
+
+  int level;
+  if (!base::StringToInt(log_level_string, &level))
+    return kDefault;
+
+  switch (level) {
+    case 0:
+      return net::NetLogCaptureMode::IncludeSocketBytes();
+    case 1:
+      return net::NetLogCaptureMode::IncludeCookiesAndCredentials();
+    case 2:
+      return net::NetLogCaptureMode::Default();
+    case 3:
+      return net::NetLogCaptureMode::None();
+    default:
+      LOG(ERROR) << "Unrecognized --" << switches::kNetLogLevel;
+      break;
+  }
+
+  return kDefault;
+}
+
+}  // namespace
+
 ChromeNetLog::ChromeNetLog()
     : net_log_temp_file_(new NetLogTempFile(this)) {
-  const base::CommandLine* command_line =
-      base::CommandLine::ForCurrentProcess();
+  const base::CommandLine& command_line =
+      *base::CommandLine::ForCurrentProcess();
 
-  if (command_line->HasSwitch(switches::kLogNetLog)) {
+  if (command_line.HasSwitch(switches::kLogNetLog)) {
     base::FilePath log_path =
-        command_line->GetSwitchValuePath(switches::kLogNetLog);
+        command_line.GetSwitchValuePath(switches::kLogNetLog);
     // Much like logging.h, bypass threading restrictions by using fopen
     // directly.  Have to write on a thread that's shutdown to handle events on
     // shutdown properly, and posting events to another thread as they occur
@@ -46,17 +84,11 @@
     } else {
       scoped_ptr<base::Value> constants(NetInternalsUI::GetConstants());
       net_log_logger_.reset(new net::WriteToFileNetLogObserver());
-      if (command_line->HasSwitch(switches::kNetLogLevel)) {
-        std::string log_level_string =
-            command_line->GetSwitchValueASCII(switches::kNetLogLevel);
-        int command_line_log_level;
-        if (base::StringToInt(log_level_string, &command_line_log_level) &&
-            command_line_log_level >= LOG_ALL &&
-            command_line_log_level <= LOG_NONE) {
-          net_log_logger_->set_log_level(
-              static_cast<LogLevel>(command_line_log_level));
-        }
-      }
+
+      net::NetLogCaptureMode capture_mode =
+          GetCaptureModeFromCommandLine(command_line);
+      net_log_logger_->set_capture_mode(capture_mode);
+
       net_log_logger_->StartObserving(this, file.Pass(), constants.get(),
                                       nullptr);
     }
diff --git a/chrome/browser/net/net_log_temp_file.cc b/chrome/browser/net/net_log_temp_file.cc
index 3674b2b..99f29aa 100644
--- a/chrome/browser/net/net_log_temp_file.cc
+++ b/chrome/browser/net/net_log_temp_file.cc
@@ -93,19 +93,20 @@
   return dict;
 }
 
-net::NetLog::LogLevel NetLogTempFile::GetLogLevelForLogType(LogType log_type) {
+net::NetLogCaptureMode NetLogTempFile::GetCaptureModeForLogType(
+    LogType log_type) {
   switch (log_type) {
   case LOG_TYPE_LOG_BYTES:
-    return net::NetLog::LOG_ALL;
+    return net::NetLogCaptureMode::IncludeSocketBytes();
   case LOG_TYPE_NORMAL:
-    return net::NetLog::LOG_ALL_BUT_BYTES;
+    return net::NetLogCaptureMode::IncludeCookiesAndCredentials();
   case LOG_TYPE_STRIP_PRIVATE_DATA:
-    return net::NetLog::LOG_STRIP_PRIVATE_DATA;
+    return net::NetLogCaptureMode::Default();
   case LOG_TYPE_NONE:
   case LOG_TYPE_UNKNOWN:
     NOTREACHED();
   }
-  return net::NetLog::LOG_STRIP_PRIVATE_DATA;
+  return net::NetLogCaptureMode::Default();
 }
 
 bool NetLogTempFile::EnsureInit() {
@@ -145,7 +146,7 @@
 
   scoped_ptr<base::Value> constants(NetInternalsUI::GetConstants());
   net_log_logger_.reset(new net::WriteToFileNetLogObserver());
-  net_log_logger_->set_log_level(GetLogLevelForLogType(log_type));
+  net_log_logger_->set_capture_mode(GetCaptureModeForLogType(log_type));
   net_log_logger_->StartObserving(chrome_net_log_, file.Pass(), constants.get(),
                                   nullptr);
 }
diff --git a/chrome/browser/net/net_log_temp_file.h b/chrome/browser/net/net_log_temp_file.h
index 46598e3..2b96276 100644
--- a/chrome/browser/net/net_log_temp_file.h
+++ b/chrome/browser/net/net_log_temp_file.h
@@ -113,8 +113,8 @@
     LOG_TYPE_STRIP_PRIVATE_DATA,
   };
 
-  // Returns the NetLog::LogLevel corresponding to a LogType.
-  static net::NetLog::LogLevel GetLogLevelForLogType(LogType log_type);
+  // Returns the NetLog::CaptureMode corresponding to a LogType.
+  static net::NetLogCaptureMode GetCaptureModeForLogType(LogType log_type);
 
   // Initializes the |state_| to STATE_NOT_LOGGING and |log_type_| to
   // LOG_TYPE_NONE (if there is no temporary file from earlier run) or
@@ -123,8 +123,9 @@
   bool EnsureInit();
 
   // Start collecting NetLog data into chrome-net-export-log.json file in
-  // base::GetTempDir() directory, using the specified log level. It is a no-op
-  // if we are already collecting data into a file, and |log_level| is ignored.
+  // base::GetTempDir() directory, using the specified capture mode. It is a
+  // no-op if we are already collecting data into a file, and |capture_mode| is
+  // ignored.
   // TODO(mmenke):  That's rather weird behavior, think about improving it.
   void StartNetLog(LogType log_type);
 
diff --git a/chrome/browser/net/net_log_temp_file_unittest.cc b/chrome/browser/net/net_log_temp_file_unittest.cc
index 89b0b62..572f12c 100644
--- a/chrome/browser/net/net_log_temp_file_unittest.cc
+++ b/chrome/browser/net/net_log_temp_file_unittest.cc
@@ -148,19 +148,21 @@
   // initialized by a DO_START command of the given type.
 
   void VerifyFileAndStateAfterDoStart() {
-    VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_NORMAL, "NORMAL",
-                                 net::NetLog::LOG_ALL_BUT_BYTES);
+    VerifyFileAndStateAfterStart(
+        NetLogTempFile::LOG_TYPE_NORMAL, "NORMAL",
+        net::NetLogCaptureMode::IncludeCookiesAndCredentials());
   }
 
   void VerifyFileAndStateAfterDoStartStripPrivateData() const {
     VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_STRIP_PRIVATE_DATA,
                                  "STRIP_PRIVATE_DATA",
-                                 net::NetLog::LOG_STRIP_PRIVATE_DATA);
+                                 net::NetLogCaptureMode::Default());
   }
 
   void VerifyFileAndStateAfterDoStartLogBytes() const {
     VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_LOG_BYTES,
-                                 "LOG_BYTES", net::NetLog::LOG_ALL);
+                                 "LOG_BYTES",
+                                 net::NetLogCaptureMode::IncludeSocketBytes());
   }
 
   // Make sure the export file has been successfully initialized after DO_STOP
@@ -191,13 +193,13 @@
   void VerifyFileAndStateAfterStart(
       NetLogTempFile::LogType expected_log_type,
       const std::string& expected_log_type_string,
-      net::NetLog::LogLevel expected_log_level) const {
+      net::NetLogCaptureMode expected_capture_mode) const {
     EXPECT_EQ(NetLogTempFile::STATE_LOGGING, net_log_temp_file_->state());
     EXPECT_EQ("LOGGING", GetStateString());
     EXPECT_EQ(expected_log_type, net_log_temp_file_->log_type());
     EXPECT_EQ(expected_log_type_string, GetLogTypeString());
 
-    EXPECT_EQ(expected_log_level, net_log_->GetLogLevel());
+    EXPECT_EQ(expected_capture_mode, net_log_->GetCaptureMode());
 
     // Check GetFilePath returns false when still writing to the file.
     base::FilePath net_export_file_path;
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc
index 48b9d66..c0ff9590 100644
--- a/chrome/browser/net/predictor_browsertest.cc
+++ b/chrome/browser/net/predictor_browsertest.cc
@@ -121,7 +121,7 @@
 
   void Attach() {
     g_browser_process->net_log()->DeprecatedAddObserver(
-        this, net::NetLog::LOG_ALL_BUT_BYTES);
+        this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
   }
 
   void Detach() {
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
index 66cbc15..319969e9 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.h"
 
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
+#include "chrome/common/chrome_content_client.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 
@@ -52,7 +53,7 @@
       data_reduction_proxy_io_data(
           new data_reduction_proxy::DataReductionProxyIOData(
               DataReductionProxyChromeSettings::GetClient(), flags, net_log,
-              io_task_runner, ui_task_runner, enable_quic));
+              io_task_runner, ui_task_runner, enable_quic, GetUserAgent()));
   data_reduction_proxy_io_data->InitOnUIThread(prefs);
 
 #if defined(ENABLE_DATA_REDUCTION_PROXY_DEBUGGING)
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index 78b24257..7acd80d 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -103,6 +103,12 @@
          !profile_sync_service->IsUsingSecondaryPassphrase();
 }
 
+bool ShouldPropagatingPasswordChangesToWebCredentialsBeEnabled() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  return password_manager::IsPropagatingPasswordChangesToWebCredentialsEnabled(
+      *command_line);
+}
+
 void ActivateAffiliationBasedMatching(PasswordStore* password_store,
                                       Profile* profile) {
   DCHECK(password_store);
@@ -124,6 +130,8 @@
                                                   affiliation_service.Pass()));
   affiliated_match_helper->Initialize();
   password_store->SetAffiliatedMatchHelper(affiliated_match_helper.Pass());
+  password_store->enable_propagating_password_changes_to_web_credentials(
+      ShouldPropagatingPasswordChangesToWebCredentialsBeEnabled());
 }
 
 }  // namespace
diff --git a/chrome/browser/plugins/plugin_info_message_filter.cc b/chrome/browser/plugins/plugin_info_message_filter.cc
index 29cd4c3..03c30a5 100644
--- a/chrome/browser/plugins/plugin_info_message_filter.cc
+++ b/chrome/browser/plugins/plugin_info_message_filter.cc
@@ -364,6 +364,7 @@
                           plugin_metadata->identifier(), &plugin_setting,
                           &uses_default_content_setting, &is_managed);
 
+  bool legacy_ask_user = plugin_setting == CONTENT_SETTING_ASK;
   plugin_setting = content_settings::PluginsFieldTrial::EffectiveContentSetting(
       CONTENT_SETTINGS_TYPE_PLUGINS, plugin_setting);
 
@@ -431,7 +432,9 @@
   if (plugin_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT) {
     *status = ChromeViewHostMsg_GetPluginInfo_Status::kPlayImportantContent;
   } else if (plugin_setting == CONTENT_SETTING_BLOCK) {
-    *status = is_managed
+    // For managed users with the ASK policy, we allow manually running plugins
+    // via context menu. This is the closest to admin intent.
+    *status = is_managed && !legacy_ask_user
                   ? ChromeViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy
                   : ChromeViewHostMsg_GetPluginInfo_Status::kBlocked;
   }
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 05c0b3a..db6e9f6 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -434,8 +434,7 @@
       const content::Referrer& referrer,
       Origin origin,
       FinalStatus expected_final_status)
-      : PrerenderContents(prerender_manager, profile, url,
-                          referrer, origin, PrerenderManager::kNoExperiment),
+      : PrerenderContents(prerender_manager, profile, url, referrer, origin),
         expected_final_status_(expected_final_status),
         new_render_view_host_(NULL),
         was_hidden_(false),
@@ -666,8 +665,7 @@
       Profile* profile,
       const GURL& url,
       const content::Referrer& referrer,
-      Origin origin,
-      uint8 experiment_id) override {
+      Origin origin) override {
     ExpectedContents expected;
     if (!expected_contents_queue_.empty()) {
       expected = expected_contents_queue_.front();
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 44c67f2..fbf9d0a 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -70,10 +70,9 @@
       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);
+      Origin origin) override {
+    return new PrerenderContents(prerender_manager, profile, url, referrer,
+                                 origin);
   }
 };
 
@@ -189,8 +188,7 @@
     Profile* profile,
     const GURL& url,
     const content::Referrer& referrer,
-    Origin origin,
-    uint8 experiment_id)
+    Origin origin)
     : prerendering_has_started_(false),
       session_storage_namespace_id_(-1),
       prerender_manager_(prerender_manager),
@@ -206,14 +204,13 @@
       child_id_(-1),
       route_id_(-1),
       origin_(origin),
-      experiment_id_(experiment_id),
       network_bytes_(0) {
   DCHECK(prerender_manager != NULL);
 }
 
 PrerenderContents* PrerenderContents::CreateMatchCompleteReplacement() {
   PrerenderContents* new_contents = prerender_manager_->CreatePrerenderContents(
-      prerender_url(), referrer(), origin(), experiment_id());
+      prerender_url(), referrer(), origin());
 
   new_contents->load_start_time_ = load_start_time_;
   new_contents->session_storage_namespace_id_ = session_storage_namespace_id_;
@@ -274,7 +271,7 @@
   // Everything after this point sets up the WebContents object and associated
   // RenderView for the prerender page. Don't do this for members of the
   // control group.
-  if (prerender_manager_->IsControlGroup(experiment_id()))
+  if (prerender_manager_->IsControlGroup())
     return;
 
   prerendering_has_started_ = true;
@@ -363,7 +360,7 @@
   DCHECK_NE(ORIGIN_MAX, origin());
 
   prerender_manager_->RecordFinalStatusWithMatchCompleteStatus(
-      origin(), experiment_id(), match_complete_status(), final_status());
+      origin(), match_complete_status(), final_status());
 
   bool used = final_status() == FINAL_STATUS_USED ||
               final_status() == FINAL_STATUS_WOULD_HAVE_BEEN_USED;
@@ -633,7 +630,7 @@
   // not reach the PrerenderHandle. Rather
   // OnPrerenderCreatedMatchCompleteReplacement will propogate that
   // information to the referer.
-  if (!prerender_manager_->IsControlGroup(experiment_id()) &&
+  if (!prerender_manager_->IsControlGroup() &&
       (prerendering_has_started() ||
        match_complete_status() == MATCH_COMPLETE_REPLACEMENT)) {
     NotifyPrerenderStop();
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index b31f7e7..138e01d 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -62,8 +62,7 @@
         Profile* profile,
         const GURL& url,
         const content::Referrer& referrer,
-        Origin origin,
-        uint8 experiment_id) = 0;
+        Origin origin) = 0;
 
    private:
     DISALLOW_COPY_AND_ASSIGN(Factory);
@@ -183,7 +182,6 @@
   FinalStatus final_status() const { return final_status_; }
 
   Origin origin() const { return origin_; }
-  uint8 experiment_id() const { return experiment_id_; }
 
   base::TimeTicks load_start_time() const { return load_start_time_; }
 
@@ -273,8 +271,7 @@
                     Profile* profile,
                     const GURL& url,
                     const content::Referrer& referrer,
-                    Origin origin,
-                    uint8 experiment_id);
+                    Origin origin);
 
   // Set the final status for how the PrerenderContents was used. This
   // should only be called once, and should be called before the prerender
@@ -391,9 +388,6 @@
   // Origin for this prerender.
   Origin origin_;
 
-  // Experiment during which this prerender is performed.
-  uint8 experiment_id_;
-
   // The size of the WebView from the launching page.
   gfx::Size size_;
 
diff --git a/chrome/browser/prerender/prerender_histograms.cc b/chrome/browser/prerender/prerender_histograms.cc
index f70e847..46a35ff 100644
--- a/chrome/browser/prerender/prerender_histograms.cc
+++ b/chrome/browser/prerender/prerender_histograms.cc
@@ -32,21 +32,11 @@
   return std::string("Prerender.") + prefix_type + std::string("_") + name;
 }
 
-std::string GetHistogramName(Origin origin, uint8 experiment_id,
-                             bool is_wash, const std::string& name) {
+std::string GetHistogramName(Origin origin, bool is_wash,
+                             const std::string& name) {
   if (is_wash)
     return ComposeHistogramName("wash", name);
 
-  if (origin == ORIGIN_GWS_PRERENDER) {
-    if (experiment_id == kNoExperiment)
-      return ComposeHistogramName("gws", name);
-    return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'),
-                                name);
-  }
-
-  if (experiment_id != kNoExperiment)
-    return ComposeHistogramName("wash", name);
-
   switch (origin) {
     case ORIGIN_OMNIBOX:
       return ComposeHistogramName("omnibox", name);
@@ -62,7 +52,8 @@
       return ComposeHistogramName("Instant", name);
     case ORIGIN_LINK_REL_NEXT:
       return ComposeHistogramName("webnext", name);
-    case ORIGIN_GWS_PRERENDER:  // Handled above.
+    case ORIGIN_GWS_PRERENDER:
+      return ComposeHistogramName("gws", name);
     default:
       NOTREACHED();
       break;
@@ -79,44 +70,27 @@
 
 }  // namespace
 
-// Helper macros for experiment-based and origin-based histogram reporting.
-// All HISTOGRAM arguments must be UMA_HISTOGRAM... macros that contain an
-// argument "name" which these macros will eventually substitute for the
-// actual name used.
+// Helper macros for origin-based histogram reporting. All HISTOGRAM arguments
+// must be UMA_HISTOGRAM... macros that contain an argument "name" which these
+// macros will eventually substitute for the actual name used.
 #define PREFIXED_HISTOGRAM(histogram_name, origin, HISTOGRAM)           \
-  PREFIXED_HISTOGRAM_INTERNAL(origin, GetCurrentExperimentId(),         \
-                              IsOriginExperimentWash(), HISTOGRAM, \
-                              histogram_name)
+  PREFIXED_HISTOGRAM_INTERNAL(origin, IsOriginWash(), HISTOGRAM, histogram_name)
 
 #define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(histogram_name, origin, \
-                                             experiment, HISTOGRAM) \
-  PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, HISTOGRAM, \
-                              histogram_name)
+                                             HISTOGRAM) \
+  PREFIXED_HISTOGRAM_INTERNAL(origin, false, HISTOGRAM, histogram_name)
 
-#define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, HISTOGRAM, \
-                                    histogram_name) do { \
+#define PREFIXED_HISTOGRAM_INTERNAL(origin, wash, HISTOGRAM, histogram_name) \
+do { \
   { \
     /* Do not rename.  HISTOGRAM expects a local variable "name". */           \
     std::string name = ComposeHistogramName(std::string(), histogram_name);    \
     HISTOGRAM;                                                                 \
   } \
   /* Do not rename.  HISTOGRAM expects a local variable "name". */ \
-  std::string name = GetHistogramName(origin, experiment, wash, \
-                                      histogram_name); \
-  /* Usually, a browsing session should only have a single experiment. */ \
-  /* Therefore, when there is a second experiment ID other than the one */ \
-  /* being recorded, don't record anything. */ \
-  /* Furthermore, experiments only apply if the origin is GWS. Should there */ \
-  /* somehow be an experiment ID if the origin is not GWS, ignore the */ \
-  /* experiment ID. */ \
-  static uint8 recording_experiment = kNoExperiment; \
-  if (recording_experiment == kNoExperiment && experiment != kNoExperiment) \
-    recording_experiment = experiment; \
+  std::string name = GetHistogramName(origin, wash, histogram_name); \
   if (wash) { \
     HISTOGRAM; \
-  } else if (experiment != kNoExperiment && \
-             (origin != ORIGIN_GWS_PRERENDER || \
-              experiment != recording_experiment)) { \
   } else if (origin == ORIGIN_OMNIBOX) { \
     HISTOGRAM; \
   } else if (origin == ORIGIN_NONE) { \
@@ -131,41 +105,33 @@
     HISTOGRAM; \
   } else if (origin == ORIGIN_LINK_REL_NEXT) { \
     HISTOGRAM; \
-  } else if (experiment != kNoExperiment) { \
-    HISTOGRAM; \
   } else { \
     HISTOGRAM; \
   } \
 } while (0)
 
 PrerenderHistograms::PrerenderHistograms()
-    : last_experiment_id_(kNoExperiment),
-      last_origin_(ORIGIN_MAX),
-      origin_experiment_wash_(false),
+    : last_origin_(ORIGIN_MAX),
+      origin_wash_(false),
       seen_any_pageload_(true),
       seen_pageload_started_after_prerender_(true) {
 }
 
 void PrerenderHistograms::RecordPrerender(Origin origin, const GURL& url) {
-  // Check if we are doing an experiment.
-  uint8 experiment = GetQueryStringBasedExperiment(url);
-
-  // We need to update last_experiment_id_, last_origin_, and
-  // origin_experiment_wash_.
+  // We need to update last_origin_ and origin_wash_.
   if (!WithinWindow()) {
     // If we are outside a window, this is a fresh start and we are fine,
     // and there is no mix.
-    origin_experiment_wash_ = false;
+    origin_wash_ = false;
   } else {
-    // If we are inside the last window, there is a mish mash of origins
-    // and experiments if either there was a mish mash before, or the current
-    // experiment/origin does not match the previous one.
-    if (experiment != last_experiment_id_ || origin != last_origin_)
-      origin_experiment_wash_ = true;
+    // If we are inside the last window, there is a mish mash of origins if
+    // either there was a mish mash before, or the current origin does not match
+    // the previous one.
+    if (origin != last_origin_)
+      origin_wash_ = true;
   }
 
   last_origin_ = origin;
-  last_experiment_id_ = experiment;
 
   // If we observe multiple tags within the 30 second window, we will still
   // reset the window to begin at the most recent occurrence, so that we will
@@ -374,7 +340,6 @@
 
 void PrerenderHistograms::RecordFinalStatus(
     Origin origin,
-    uint8 experiment_id,
     PrerenderContents::MatchCompleteStatus mc_status,
     FinalStatus final_status) const {
   DCHECK(final_status != FINAL_STATUS_MAX);
@@ -382,14 +347,14 @@
   if (mc_status == PrerenderContents::MATCH_COMPLETE_DEFAULT ||
       mc_status == PrerenderContents::MATCH_COMPLETE_REPLACED) {
     PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(
-        "FinalStatus", origin, experiment_id,
+        "FinalStatus", origin,
         UMA_HISTOGRAM_ENUMERATION(name, final_status, FINAL_STATUS_MAX));
   }
   if (mc_status == PrerenderContents::MATCH_COMPLETE_DEFAULT ||
       mc_status == PrerenderContents::MATCH_COMPLETE_REPLACEMENT ||
       mc_status == PrerenderContents::MATCH_COMPLETE_REPLACEMENT_PENDING) {
     PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(
-        "FinalStatusMatchComplete", origin, experiment_id,
+        "FinalStatusMatchComplete", origin,
         UMA_HISTOGRAM_ENUMERATION(name, final_status, FINAL_STATUS_MAX));
   }
 }
@@ -426,16 +391,10 @@
   }
 }
 
-uint8 PrerenderHistograms::GetCurrentExperimentId() const {
-  if (!WithinWindow())
-    return kNoExperiment;
-  return last_experiment_id_;
-}
-
-bool PrerenderHistograms::IsOriginExperimentWash() const {
+bool PrerenderHistograms::IsOriginWash() const {
   if (!WithinWindow())
     return false;
-  return origin_experiment_wash_;
+  return origin_wash_;
 }
 
 }  // namespace prerender
diff --git a/chrome/browser/prerender/prerender_histograms.h b/chrome/browser/prerender/prerender_histograms.h
index c161e0a..0f7bc40 100644
--- a/chrome/browser/prerender/prerender_histograms.h
+++ b/chrome/browser/prerender/prerender_histograms.h
@@ -77,7 +77,6 @@
 
   // Record a final status of a prerendered page in a histogram.
   void RecordFinalStatus(Origin origin,
-                         uint8 experiment_id,
                          PrerenderContents::MatchCompleteStatus mc_status,
                          FinalStatus final_status) const;
 
@@ -117,23 +116,15 @@
   // observed.
   bool WithinWindow() const;
 
-  // Returns the current experiment.
-  uint8 GetCurrentExperimentId() const;
-
-  // Returns whether or not there is currently an origin/experiment wash.
-  bool IsOriginExperimentWash() const;
-
-  // An integer indicating a Prerendering Experiment being currently conducted.
-  // (The last experiment ID seen).
-  uint8 last_experiment_id_;
+  // Returns whether or not there is currently an origin wash.
+  bool IsOriginWash() const;
 
   // Origin of the last prerender seen.
   Origin last_origin_;
 
   // A boolean indicating that we have recently encountered a combination of
-  // different experiments and origins, making an attribution of PPLT's to
-  // experiments / origins impossible.
-  bool origin_experiment_wash_;
+  // different origins, making an attribution of PPLT's to origins impossible.
+  bool origin_wash_;
 
   // The time when we last saw a prerender request coming from a renderer.
   // This is used to record perceived PLT's for a certain amount of time
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 1a77ef9..0c144f4 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -367,9 +367,6 @@
     return NULL;
   }
 
-  if (IsNoSwapInExperiment(prerender_data->contents()->experiment_id()))
-    return NULL;
-
   if (WebContents* new_web_contents =
       prerender_data->contents()->prerender_contents()) {
     if (web_contents == new_web_contents)
@@ -624,13 +621,12 @@
 
 // static
 bool PrerenderManager::ActuallyPrerendering() {
-  return IsPrerenderingPossible() && !IsControlGroup(kNoExperiment);
+  return IsPrerenderingPossible() && !IsControlGroup();
 }
 
 // static
-bool PrerenderManager::IsControlGroup(uint8 experiment_id) {
-  return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP ||
-      IsControlGroupExperiment(experiment_id);
+bool PrerenderManager::IsControlGroup() {
+  return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP;
 }
 
 // static
@@ -774,7 +770,7 @@
   dict_value->SetBoolean("omnibox_enabled", IsOmniboxEnabled(profile_));
   // If prerender is disabled via a flag this method is not even called.
   std::string enabled_note;
-  if (IsControlGroup(kNoExperiment))
+  if (IsControlGroup())
     enabled_note += "(Control group: Not actually prerendering) ";
   if (IsNoUseGroup())
     enabled_note += "(No-use group: Not swapping in prerendered pages) ";
@@ -797,13 +793,9 @@
 
 void PrerenderManager::RecordFinalStatusWithMatchCompleteStatus(
     Origin origin,
-    uint8 experiment_id,
     PrerenderContents::MatchCompleteStatus mc_status,
     FinalStatus final_status) const {
-  histograms_->RecordFinalStatus(origin,
-                                 experiment_id,
-                                 mc_status,
-                                 final_status);
+  histograms_->RecordFinalStatus(origin, mc_status, final_status);
 }
 
 void PrerenderManager::RecordNavigation(const GURL& url) {
@@ -916,11 +908,8 @@
 
   GURL url = url_arg;
   GURL alias_url;
-  uint8 experiment = GetQueryStringBasedExperiment(url_arg);
-  if (IsControlGroup(experiment) &&
-      MaybeGetQueryStringBasedAliasURL(url, &alias_url)) {
+  if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url))
     url = alias_url;
-  }
 
   // From here on, we will record a FinalStatus so we need to register with the
   // histogram tracking.
@@ -929,7 +918,7 @@
   if (PrerenderData* preexisting_prerender_data =
           FindPrerenderData(url, session_storage_namespace)) {
     RecordFinalStatusWithoutCreatingPrerenderContents(
-        url, origin, experiment, FINAL_STATUS_DUPLICATE);
+        url, origin, FINAL_STATUS_DUPLICATE);
     return new PrerenderHandle(preexisting_prerender_data);
   }
 
@@ -948,7 +937,7 @@
           profile_, url) &&
       !content::RenderProcessHost::run_renderer_in_process()) {
     RecordFinalStatusWithoutCreatingPrerenderContents(
-        url, origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES);
+        url, origin, FINAL_STATUS_TOO_MANY_PROCESSES);
     return NULL;
   }
 
@@ -958,12 +947,12 @@
     // this doesn't make sense as the next prerender request will be triggered
     // by a navigation and is unlikely to be the same site.
     RecordFinalStatusWithoutCreatingPrerenderContents(
-        url, origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
+        url, origin, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
     return NULL;
   }
 
-  PrerenderContents* prerender_contents = CreatePrerenderContents(
-      url, referrer, origin, experiment);
+  PrerenderContents* prerender_contents = CreatePrerenderContents(url, referrer,
+                                                                  origin);
   DCHECK(prerender_contents);
   active_prerenders_.push_back(
       new PrerenderData(this, prerender_contents,
@@ -989,8 +978,7 @@
   prerender_contents->StartPrerendering(contents_size,
                                         session_storage_namespace);
 
-  DCHECK(IsControlGroup(experiment) ||
-         prerender_contents->prerendering_has_started());
+  DCHECK(IsControlGroup() || prerender_contents->prerendering_has_started());
 
   if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP)
     histograms_->RecordConcurrency(active_prerenders_.size());
@@ -1092,11 +1080,10 @@
 PrerenderContents* PrerenderManager::CreatePrerenderContents(
     const GURL& url,
     const content::Referrer& referrer,
-    Origin origin,
-    uint8 experiment_id) {
+    Origin origin) {
   DCHECK(CalledOnValidThread());
   return prerender_contents_factory_->CreatePrerenderContents(
-      this, profile_, url, referrer, origin, experiment_id);
+      this, profile_, url, referrer, origin);
 }
 
 void PrerenderManager::SortActivePrerenders() {
@@ -1209,21 +1196,17 @@
   prerender_contents->set_match_complete_status(
       PrerenderContents::MATCH_COMPLETE_REPLACED);
   histograms_->RecordFinalStatus(prerender_contents->origin(),
-                                 prerender_contents->experiment_id(),
                                  PrerenderContents::MATCH_COMPLETE_REPLACEMENT,
                                  FINAL_STATUS_WOULD_HAVE_BEEN_USED);
   prerender_contents->Destroy(final_status);
 }
 
 void PrerenderManager::RecordFinalStatusWithoutCreatingPrerenderContents(
-    const GURL& url, Origin origin, uint8 experiment_id,
-    FinalStatus final_status) const {
+    const GURL& url, Origin origin, FinalStatus final_status) const {
   PrerenderHistory::Entry entry(url, final_status, origin, base::Time::Now());
   prerender_history_->AddEntry(entry);
   RecordFinalStatusWithMatchCompleteStatus(
-      origin, experiment_id,
-      PrerenderContents::MATCH_COMPLETE_DEFAULT,
-      final_status);
+      origin, PrerenderContents::MATCH_COMPLETE_DEFAULT, final_status);
 }
 
 void PrerenderManager::Observe(int type,
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 00f638b4..2ba76b4 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -87,9 +87,6 @@
     CLEAR_MAX = 0x1 << 2
   };
 
-  // ID indicating that no experiment is active.
-  static const uint8 kNoExperiment = 0;
-
   // Owned by a Profile object for the lifetime of the profile.
   explicit PrerenderManager(Profile* profile);
 
@@ -178,7 +175,7 @@
   static const char* GetModeString();
   static bool IsPrerenderingPossible();
   static bool ActuallyPrerendering();
-  static bool IsControlGroup(uint8 experiment_id);
+  static bool IsControlGroup();
   static bool IsNoUseGroup();
 
   // Query the list of current prerender pages to see if the given web contents
@@ -243,7 +240,6 @@
   // (necessary to flag MatchComplete dummies).
   void RecordFinalStatusWithMatchCompleteStatus(
       Origin origin,
-      uint8 experiment_id,
       PrerenderContents::MatchCompleteStatus mc_status,
       FinalStatus final_status) const;
 
@@ -419,8 +415,7 @@
   virtual PrerenderContents* CreatePrerenderContents(
       const GURL& url,
       const content::Referrer& referrer,
-      Origin origin,
-      uint8 experiment_id);
+      Origin origin);
 
   // Insures the |active_prerenders_| are sorted by increasing expiry time. Call
   // after every mutation of active_prerenders_ that can possibly make it
@@ -476,8 +471,7 @@
   // This is a helper function which will ultimately call
   // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT.
   void RecordFinalStatusWithoutCreatingPrerenderContents(
-      const GURL& url, Origin origin, uint8 experiment_id,
-      FinalStatus final_status) const;
+      const GURL& url, Origin origin, FinalStatus final_status) const;
 
 
   // Swaps a prerender |prerender_data| for |url| into the tab, replacing
diff --git a/chrome/browser/prerender/prerender_resource_throttle_unittest.cc b/chrome/browser/prerender/prerender_resource_throttle_unittest.cc
index ed8798e..a66296e 100644
--- a/chrome/browser/prerender/prerender_resource_throttle_unittest.cc
+++ b/chrome/browser/prerender/prerender_resource_throttle_unittest.cc
@@ -38,8 +38,7 @@
   TestPrerenderContents(PrerenderManager* prerender_manager,
                         int child_id, int route_id)
       : PrerenderContents(prerender_manager, static_cast<Profile*>(NULL),
-                          GURL(), content::Referrer(), ORIGIN_NONE,
-                          PrerenderManager::kNoExperiment),
+                          GURL(), content::Referrer(), ORIGIN_NONE),
         child_id_(child_id),
         route_id_(route_id) {
     PrerenderResourceThrottle::OverridePrerenderContentsForTesting(this);
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index 9d226155..b0e37e1 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -232,8 +232,7 @@
 
   PrerenderContents* CreatePrerenderContents(const GURL& url,
                                              const Referrer& referrer,
-                                             Origin origin,
-                                             uint8 experiment_id) override {
+                                             Origin origin) override {
     CHECK(next_prerender_contents_.get());
     EXPECT_EQ(url, next_prerender_contents_->prerender_url());
     EXPECT_EQ(origin, next_prerender_contents_->origin());
@@ -269,8 +268,7 @@
     Origin origin,
     FinalStatus expected_final_status)
     : PrerenderContents(test_prerender_manager,
-                        NULL, url, Referrer(), origin,
-                        PrerenderManager::kNoExperiment),
+                        NULL, url, Referrer(), origin),
       route_id_(g_next_route_id_++),
       test_prerender_manager_(test_prerender_manager),
       expected_final_status_(expected_final_status) {
@@ -289,7 +287,7 @@
   // but it will early exit before actually creating a new RenderView if
   // |is_control_group| is true;
   load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks();
-  if (!test_prerender_manager_->IsControlGroup(experiment_id())) {
+  if (!test_prerender_manager_->IsControlGroup()) {
     prerendering_has_started_ = true;
     test_prerender_manager_->DummyPrerenderContentsStarted(-1, route_id_, this);
     NotifyPrerenderStart();
diff --git a/chrome/browser/prerender/prerender_util.cc b/chrome/browser/prerender/prerender_util.cc
index 26f84ce..f779907 100644
--- a/chrome/browser/prerender/prerender_util.cc
+++ b/chrome/browser/prerender/prerender_util.cc
@@ -71,26 +71,6 @@
   return false;
 }
 
-uint8 GetQueryStringBasedExperiment(const GURL& url) {
-  url::Parsed parsed;
-  url::ParseStandardURL(url.spec().c_str(), url.spec().length(), &parsed);
-  url::Component query = parsed.query;
-  url::Component key, value;
-  while (url::ExtractQueryKeyValue(url.spec().c_str(), &query, &key, &value)) {
-    if (key.len != 3 || strncmp(url.spec().c_str() + key.begin, "lpe", key.len))
-      continue;
-
-    // We found a lpe= query string component.
-    if (value.len != 1)
-      continue;
-    uint8 exp = *(url.spec().c_str() + value.begin) - '0';
-    if (exp < 1 || exp > 9)
-      continue;
-    return exp;
-  }
-  return kNoExperiment;
-}
-
 bool IsGoogleDomain(const GURL& url) {
   return StartsWithASCII(url.host(), std::string("www.google."), true);
 }
@@ -104,16 +84,6 @@
           StartsWithASCII(url.path(), std::string("/webhp"), true));
 }
 
-bool IsNoSwapInExperiment(uint8 experiment_id) {
-  // Currently, experiments 5 and 6 fall in this category.
-  return experiment_id == 5 || experiment_id == 6;
-}
-
-bool IsControlGroupExperiment(uint8 experiment_id) {
-  // Currently, experiments 7 and 8 fall in this category.
-  return experiment_id == 7 || experiment_id == 8;
-}
-
 void ReportPrerenderExternalURL() {
   ReportPrerenderSchemeCancelReason(
       PRERENDER_SCHEME_CANCEL_REASON_EXTERNAL_PROTOCOL);
diff --git a/chrome/browser/prerender/prerender_util.h b/chrome/browser/prerender/prerender_util.h
index 2d7e3c2..3a9ec1f 100644
--- a/chrome/browser/prerender/prerender_util.h
+++ b/chrome/browser/prerender/prerender_util.h
@@ -10,36 +10,17 @@
 
 namespace prerender {
 
-// ID indicating that no experiment is active.
-const uint8 kNoExperiment = 0;
-
 // Extracts a urlencoded URL stored in a url= query parameter from a URL
 // supplied, if available, and stores it in alias_url.  Returns whether or not
 // the operation succeeded (i.e. a valid URL was found).
 bool MaybeGetQueryStringBasedAliasURL(const GURL& url, GURL* alias_url);
 
-// Extracts an experiment stored in the query parameter
-// lpe= from the URL supplied, and returns it.
-// Returns kNoExperiment if no experiment ID is found, or if the ID
-// is not an integer in the range 1 to 9.
-uint8 GetQueryStringBasedExperiment(const GURL& url);
-
 // Indicates whether the URL provided has a Google domain
 bool IsGoogleDomain(const GURL& url);
 
 // Indicates whether the URL provided could be a Google search result page.
 bool IsGoogleSearchResultURL(const GURL& url);
 
-// The prerender contents of some experiments should never be swapped in
-// by pretending to never match on the URL.  This function will return true
-// iff this is the case for the experiment_id specified.
-bool IsNoSwapInExperiment(uint8 experiment_id);
-
-// The prerender contents of some experiments should behave identical to the
-// control group, regardless of the field trial.  This function will return true
-// iff this is the case for the experiment_id specified.
-bool IsControlGroupExperiment(uint8 experiment_id);
-
 // Report a URL was canceled due to trying to handle an external URL.
 void ReportPrerenderExternalURL();
 
diff --git a/chrome/browser/prerender/prerender_util_unittest.cc b/chrome/browser/prerender/prerender_util_unittest.cc
index ebfea81..3e316cbb 100644
--- a/chrome/browser/prerender/prerender_util_unittest.cc
+++ b/chrome/browser/prerender/prerender_util_unittest.cc
@@ -35,29 +35,6 @@
   ASSERT_EQ(GURL("http://validURLSareGREAT.com").spec(), result.spec());
 }
 
-// Ensure that extracting an experiment in the lpe= query string component
-// works.
-TEST(PrerenderUtilTest, ExtractExperimentInQueryStringTest) {
-  EXPECT_EQ(
-      GetQueryStringBasedExperiment(GURL(
-          "http://www.google.com/url?sa=t&source=web&cd=1&ved=0CBcQFjAA&url=h"
-          "ttp%3A%2F%2Fwww.abercrombie.com%2Fwebapp%2Fwcs%2Fstores%2Fservlet%"
-          "2FStoreLocator%3FcatalogId%3D%26storeId%3D10051%26langId%3D-1&rct="
-          "j&q=allinurl%3A%26&ei=KLyUTYGSEdTWiAKUmLCdCQ&usg=AFQjCNF8nJ2MpBFfr"
-          "1ijO39_f22bcKyccw&sig2=2ymyGpO0unJwU1d4kdCUjQ&lpe=4&asdf=test")),
-      4);
-  EXPECT_EQ(GetQueryStringBasedExperiment(
-      GURL("http://www.google.com/test.php?a=b")), kNoExperiment);
-  EXPECT_EQ(GetQueryStringBasedExperiment(
-      GURL("http://www.google.com/test.php?lpe=5")), 5);
-  EXPECT_EQ(GetQueryStringBasedExperiment(
-      GURL("http://www.google.com/test.php?lpe=50")), kNoExperiment);
-  EXPECT_EQ(GetQueryStringBasedExperiment(
-      GURL("http://www.google.com/test.php?lpe=0")), kNoExperiment);
-  EXPECT_EQ(GetQueryStringBasedExperiment(
-      GURL("http://www.google.com/test.php?lpe=10")), kNoExperiment);
-}
-
 // Ensure that we detect Google search result URLs correctly.
 TEST(PrerenderUtilTest, DetectGoogleSearchREsultURLTest) {
   EXPECT_TRUE(IsGoogleSearchResultURL(GURL("http://www.google.com/#asdf")));
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index 1a729381..5dfc021 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -602,8 +602,7 @@
 
 void CloudPrintWebDialogDelegate::OnCloseContents(WebContents* source,
                                                   bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool CloudPrintWebDialogDelegate::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index 6f92e20..618c3834 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -139,8 +139,7 @@
 
 void PrintPreviewDialogDelegate::OnCloseContents(WebContents* /* source */,
                                                  bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool PrintPreviewDialogDelegate::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/printing/printer_manager_dialog_linux.cc b/chrome/browser/printing/printer_manager_dialog_linux.cc
index 8513fa7a..a568b99 100644
--- a/chrome/browser/printing/printer_manager_dialog_linux.cc
+++ b/chrome/browser/printing/printer_manager_dialog_linux.cc
@@ -35,9 +35,9 @@
     case base::nix::DESKTOP_ENVIRONMENT_KDE3:
     case base::nix::DESKTOP_ENVIRONMENT_KDE4:
     case base::nix::DESKTOP_ENVIRONMENT_UNITY:
+    case base::nix::DESKTOP_ENVIRONMENT_XFCE:
       command = kGNOMEPrinterConfigCommand;
       break;
-    case base::nix::DESKTOP_ENVIRONMENT_XFCE:
     case base::nix::DESKTOP_ENVIRONMENT_OTHER:
       break;
   }
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 9c33815c..d1b3b97a 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -15,6 +15,8 @@
 #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
 #include "chrome/browser/domain_reliability/service_factory.h"
 #include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/engagement/site_engagement_service_factory.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h"
 #include "chrome/browser/google/google_url_tracker_factory.h"
@@ -276,6 +278,10 @@
 #endif
   ShortcutsBackendFactory::GetInstance();
   SigninManagerFactory::GetInstance();
+
+  if (SiteEngagementService::IsEnabled())
+    SiteEngagementServiceFactory::GetInstance();
+
 #if defined(ENABLE_SPELLCHECK)
   SpellcheckServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
index 2377772..ab7237b 100644
--- a/chrome/browser/profiles/profile_downloader.cc
+++ b/chrome/browser/profiles/profile_downloader.cc
@@ -193,9 +193,7 @@
 }
 
 ProfileDownloader::ProfileDownloader(ProfileDownloaderDelegate* delegate)
-    : ImageRequest(
-          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
-      OAuth2TokenService::Consumer("profile_downloader"),
+    : OAuth2TokenService::Consumer("profile_downloader"),
       delegate_(delegate),
       picture_status_(PICTURE_FAILED) {
   DCHECK(delegate_);
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 721cdc5..e82ef90f 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -132,7 +132,11 @@
   if (io_data_->http_server_properties_manager_)
     io_data_->http_server_properties_manager_->ShutdownOnPrefThread();
 
-  io_data_->data_reduction_proxy_io_data()->ShutdownOnUIThread();
+  // io_data_->data_reduction_proxy_io_data() might be NULL if Init() was
+  // never called.
+  if (io_data_->data_reduction_proxy_io_data())
+    io_data_->data_reduction_proxy_io_data()->ShutdownOnUIThread();
+
   io_data_->ShutdownOnUIThread(GetAllContextGetters().Pass());
 }
 
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc
index 9a1b15ca..024749f 100644
--- a/chrome/browser/push_messaging/push_messaging_browsertest.cc
+++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -153,10 +153,10 @@
   void SetUpOnMainThread() override {
     gcm_service_ = static_cast<gcm::FakeGCMProfileService*>(
         gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-            browser()->profile(), &gcm::FakeGCMProfileService::Build));
+            GetBrowser()->profile(), &gcm::FakeGCMProfileService::Build));
     gcm_service_->set_collect(true);
     push_service_ =
-        PushMessagingServiceFactory::GetForProfile(browser()->profile());
+        PushMessagingServiceFactory::GetForProfile(GetBrowser()->profile());
 
     LoadTestPage();
 
@@ -173,7 +173,7 @@
   }
 
   void LoadTestPage(const std::string& path) {
-    ui_test_utils::NavigateToURL(browser(), https_server_->GetURL(path));
+    ui_test_utils::NavigateToURL(GetBrowser(), https_server_->GetURL(path));
   }
 
   void LoadTestPage() {
@@ -187,14 +187,14 @@
   bool RunScript(const std::string& script, std::string* result,
                  content::WebContents* web_contents) {
     if (!web_contents)
-      web_contents = browser()->tab_strip_model()->GetActiveWebContents();
+      web_contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
     return content::ExecuteScriptAndExtractString(web_contents->GetMainFrame(),
                                                   script,
                                                   result);
   }
 
-  void TryToRegisterSuccessfully(
-      const std::string& expected_push_registration_id);
+  void TryToSubscribeSuccessfully(
+      const std::string& expected_push_subscription_id);
 
   PushMessagingApplicationId GetServiceWorkerAppId(
       int64 service_worker_registration_id);
@@ -220,6 +220,8 @@
     return "files/push_messaging/test.html";
   }
 
+  virtual Browser* GetBrowser() const { return browser(); }
+
  private:
   scoped_ptr<net::SpawnedTestServer> https_server_;
   gcm::FakeGCMProfileService* gcm_service_;
@@ -236,44 +238,44 @@
 };
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBadManifestBrowserTest,
-                       RegisterFailsNotVisibleMessages) {
+                       SubscribeFailsNotVisibleMessages) {
   std::string script_result;
 
   ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
-  ASSERT_TRUE(RunScript("registerPush()", &script_result));
+  ASSERT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ("AbortError - Registration failed - permission denied",
             script_result);
 }
 
-void PushMessagingBrowserTest::TryToRegisterSuccessfully(
-    const std::string& expected_push_registration_id) {
+void PushMessagingBrowserTest::TryToSubscribeSuccessfully(
+    const std::string& expected_push_subscription_id) {
   std::string script_result;
 
   EXPECT_TRUE(RunScript("registerServiceWorker()", &script_result));
   EXPECT_EQ("ok - service worker registered", script_result);
 
-  InfoBarResponder accepting_responder(browser(), true);
+  InfoBarResponder accepting_responder(GetBrowser(), true);
   EXPECT_TRUE(RunScript("requestNotificationPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
 
-  EXPECT_TRUE(RunScript("registerPush()", &script_result));
+  EXPECT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ(std::string(kPushMessagingEndpoint) + " - "
-            + expected_push_registration_id, script_result);
+            + expected_push_subscription_id, script_result);
 }
 
 PushMessagingApplicationId PushMessagingBrowserTest::GetServiceWorkerAppId(
     int64 service_worker_registration_id) {
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
   PushMessagingApplicationId application_id = PushMessagingApplicationId::Get(
-      browser()->profile(), origin, service_worker_registration_id);
+      GetBrowser()->profile(), origin, service_worker_registration_id);
   EXPECT_TRUE(application_id.IsValid());
   return application_id;
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       RegisterSuccessNotificationsGranted) {
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+                       SubscribeSuccessNotificationsGranted) {
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id.app_id_guid(), gcm_service()->last_registered_app_id());
@@ -281,14 +283,14 @@
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       RegisterSuccessNotificationsPrompt) {
+                       SubscribeSuccessNotificationsPrompt) {
   std::string script_result;
 
   ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
 
-  InfoBarResponder accepting_responder(browser(), true);
-  ASSERT_TRUE(RunScript("registerPush()", &script_result));
+  InfoBarResponder accepting_responder(GetBrowser(), true);
+  ASSERT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ(std::string(kPushMessagingEndpoint) + " - 1-0", script_result);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
@@ -297,50 +299,50 @@
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       RegisterFailureNotificationsBlocked) {
+                       SubscribeFailureNotificationsBlocked) {
   std::string script_result;
 
   ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
 
-  InfoBarResponder cancelling_responder(browser(), false);
+  InfoBarResponder cancelling_responder(GetBrowser(), false);
   ASSERT_TRUE(RunScript("requestNotificationPermission();", &script_result));
   ASSERT_EQ("permission status - denied", script_result);
 
-  ASSERT_TRUE(RunScript("registerPush()", &script_result));
+  ASSERT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ("AbortError - Registration failed - permission denied",
             script_result);
 }
 
-IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, RegisterFailureNoManifest) {
+IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, SubscribeFailureNoManifest) {
   std::string script_result;
 
   ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
 
-  InfoBarResponder accepting_responder(browser(), true);
+  InfoBarResponder accepting_responder(GetBrowser(), true);
   ASSERT_TRUE(RunScript("requestNotificationPermission();", &script_result));
   ASSERT_EQ("permission status - granted", script_result);
 
   ASSERT_TRUE(RunScript("removeManifest()", &script_result));
   ASSERT_EQ("manifest removed", script_result);
 
-  ASSERT_TRUE(RunScript("registerPush()", &script_result));
+  ASSERT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ("AbortError - Registration failed - no sender id provided",
             script_result);
 }
 
-// TODO(johnme): Test registering from a worker - see https://crbug.com/437298.
+// TODO(johnme): Test subscribing from a worker - see https://crbug.com/437298.
 
-IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, RegisterPersisted) {
+IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, SubscribePersisted) {
   std::string script_result;
 
   // First, test that Service Worker registration IDs are assigned in order of
-  // registering the Service Workers, and the (fake) push registration ids are
-  // assigned in order of push registration (even when these orders are
+  // registering the Service Workers, and the (fake) push subscription ids are
+  // assigned in order of push subscription (even when these orders are
   // different).
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
   PushMessagingApplicationId app_id_sw0 = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id_sw0.app_id_guid(), gcm_service()->last_registered_app_id());
 
@@ -356,16 +358,16 @@
   // navigator.serviceWorker.ready is going to be resolved with the parent
   // Service Worker which still controls the page.
   LoadTestPage("files/push_messaging/subscope2/test.html");
-  TryToRegisterSuccessfully("1-1" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-1" /* expected_push_subscription_id */);
   PushMessagingApplicationId app_id_sw2 = GetServiceWorkerAppId(2LL);
   EXPECT_EQ(app_id_sw2.app_id_guid(), gcm_service()->last_registered_app_id());
 
   LoadTestPage("files/push_messaging/subscope1/test.html");
-  TryToRegisterSuccessfully("1-2" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-2" /* expected_push_subscription_id */);
   PushMessagingApplicationId app_id_sw1 = GetServiceWorkerAppId(1LL);
   EXPECT_EQ(app_id_sw1.app_id_guid(), gcm_service()->last_registered_app_id());
 
-  // Now test that the Service Worker registration IDs and push registration IDs
+  // Now test that the Service Worker registration IDs and push subscription IDs
   // generated above were persisted to SW storage, by checking that they are
   // unchanged despite requesting them in a different order.
   // TODO(johnme): Ideally we would restart the browser at this point to check
@@ -374,22 +376,22 @@
   // so we wouldn't be able to load the test pages with the same origin.
 
   LoadTestPage("files/push_messaging/subscope1/test.html");
-  TryToRegisterSuccessfully("1-2" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-2" /* expected_push_subscription_id */);
   EXPECT_EQ(app_id_sw1.app_id_guid(), gcm_service()->last_registered_app_id());
 
   LoadTestPage("files/push_messaging/subscope2/test.html");
-  TryToRegisterSuccessfully("1-1" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-1" /* expected_push_subscription_id */);
   EXPECT_EQ(app_id_sw1.app_id_guid(), gcm_service()->last_registered_app_id());
 
   LoadTestPage();
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
   EXPECT_EQ(app_id_sw1.app_id_guid(), gcm_service()->last_registered_app_id());
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, PushEventSuccess) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id.app_id_guid(), gcm_service()->last_registered_app_id());
@@ -414,7 +416,7 @@
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, PushEventNoServiceWorker) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id.app_id_guid(), gcm_service()->last_registered_app_id());
@@ -456,7 +458,7 @@
                        PushEventEnforcesUserVisibleNotification) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id.app_id_guid(), gcm_service()->last_registered_app_id());
@@ -476,7 +478,7 @@
   // We'll need to specify the web_contents in which to eval script, since we're
   // going to run script in a background tab.
   content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+      GetBrowser()->tab_strip_model()->GetActiveWebContents();
 
   // If the site is visible in an active tab, we should not force a notification
   // to be shown. Try it twice, since we allow one mistake per 10 push events.
@@ -492,7 +494,7 @@
 
   // Open a blank foreground tab so site is no longer visible.
   ui_test_utils::NavigateToURLWithDisposition(
-      browser(), GURL("about:blank"), NEW_FOREGROUND_TAB,
+      GetBrowser(), GURL("about:blank"), NEW_FOREGROUND_TAB,
       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
 
   // If the Service Worker push event handler does not show a notification, we
@@ -552,9 +554,9 @@
                        PushEventNotificationWithoutEventWaitUntil) {
   std::string script_result;
   content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+      GetBrowser()->tab_strip_model()->GetActiveWebContents();
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id.app_id_guid(), gcm_service()->last_registered_app_id());
@@ -608,11 +610,11 @@
   ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
 
-  InfoBarResponder accepting_responder(browser(), true);
+  InfoBarResponder accepting_responder(GetBrowser(), true);
   ASSERT_TRUE(RunScript("requestNotificationPermission();", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
 
-  ASSERT_TRUE(RunScript("registerPush()", &script_result));
+  ASSERT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ(std::string(kPushMessagingEndpoint) + " - 1-0", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
@@ -625,11 +627,11 @@
   ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
 
-  InfoBarResponder cancelling_responder(browser(), false);
+  InfoBarResponder cancelling_responder(GetBrowser(), false);
   ASSERT_TRUE(RunScript("requestNotificationPermission();", &script_result));
   EXPECT_EQ("permission status - denied", script_result);
 
-  ASSERT_TRUE(RunScript("registerPush()", &script_result));
+  ASSERT_TRUE(RunScript("subscribePush()", &script_result));
   EXPECT_EQ("AbortError - Registration failed - permission denied",
             script_result);
 
@@ -637,56 +639,56 @@
   EXPECT_EQ("permission status - denied", script_result);
 }
 
-IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, UnregisterSuccess) {
+IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, UnsubscribeSuccess) {
   std::string script_result;
 
   EXPECT_TRUE(RunScript("registerServiceWorker()", &script_result));
   EXPECT_EQ("ok - service worker registered", script_result);
 
   // Resolves true if there was a subscription.
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
   gcm_service()->AddExpectedUnregisterResponse(gcm::GCMClient::SUCCESS);
-  ASSERT_TRUE(RunScript("unregister()", &script_result));
-  EXPECT_EQ("unregister result: true", script_result);
+  ASSERT_TRUE(RunScript("unsubscribePush()", &script_result));
+  EXPECT_EQ("unsubscribe result: true", script_result);
 
   // Resolves false if there was no longer a subscription.
-  ASSERT_TRUE(RunScript("unregister()", &script_result));
-  EXPECT_EQ("unregister result: false", script_result);
+  ASSERT_TRUE(RunScript("unsubscribePush()", &script_result));
+  EXPECT_EQ("unsubscribe result: false", script_result);
 
   // Doesn't reject if there was a network error (deactivates subscription
   // locally anyway).
-  TryToRegisterSuccessfully("1-1" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-1" /* expected_push_subscription_id */);
   gcm_service()->AddExpectedUnregisterResponse(gcm::GCMClient::NETWORK_ERROR);
-  ASSERT_TRUE(RunScript("unregister()", &script_result));
-  EXPECT_EQ("unregister result: true", script_result);
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("unsubscribePush()", &script_result));
+  EXPECT_EQ("unsubscribe result: true", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 
   // Doesn't reject if there were other push service errors (deactivates
   // subscription locally anyway).
-  TryToRegisterSuccessfully("1-2" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-2" /* expected_push_subscription_id */);
   gcm_service()->AddExpectedUnregisterResponse(
       gcm::GCMClient::INVALID_PARAMETER);
-  ASSERT_TRUE(RunScript("unregister()", &script_result));
-  EXPECT_EQ("unregister result: true", script_result);
+  ASSERT_TRUE(RunScript("unsubscribePush()", &script_result));
+  EXPECT_EQ("unsubscribe result: true", script_result);
 
   // Unsubscribing (with an existing reference to a PushSubscription), after
   // unregistering the Service Worker, just means push subscription isn't found.
-  TryToRegisterSuccessfully("1-3" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-3" /* expected_push_subscription_id */);
   ASSERT_TRUE(RunScript("unregisterServiceWorker()", &script_result));
   ASSERT_EQ("service worker unregistration status: true", script_result);
-  ASSERT_TRUE(RunScript("unregister()", &script_result));
-  EXPECT_EQ("unregister result: false", script_result);
+  ASSERT_TRUE(RunScript("unsubscribePush()", &script_result));
+  EXPECT_EQ("unsubscribe result: false", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       GlobalResetPushPermissionUnregisters) {
+                       GlobalResetPushPermissionUnsubscribes) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -696,7 +698,7 @@
   push_service()->SetContentSettingChangedCallbackForTesting(
       message_loop_runner->QuitClosure());
 
-  browser()->profile()->GetHostContentSettingsMap()->
+  GetBrowser()->profile()->GetHostContentSettingsMap()->
       ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
 
   message_loop_runner->Run();
@@ -704,18 +706,18 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - default", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       LocalResetPushPermissionUnregisters) {
+                       LocalResetPushPermissionUnsubscribes) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -726,7 +728,7 @@
       message_loop_runner->QuitClosure());
 
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::FromURLNoWildcard(origin),
       CONTENT_SETTINGS_TYPE_PUSH_MESSAGING,
@@ -738,18 +740,18 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - default", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       DenyPushPermissionUnregisters) {
+                       DenyPushPermissionUnsubscribes) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -760,7 +762,7 @@
       message_loop_runner->QuitClosure());
 
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::FromURLNoWildcard(origin),
       CONTENT_SETTINGS_TYPE_PUSH_MESSAGING,
@@ -772,18 +774,18 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - denied", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       GlobalResetNotificationsPermissionUnregisters) {
+                       GlobalResetNotificationsPermissionUnsubscribes) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -793,7 +795,7 @@
   push_service()->SetContentSettingChangedCallbackForTesting(
       message_loop_runner->QuitClosure());
 
-  browser()->profile()->GetHostContentSettingsMap()->
+  GetBrowser()->profile()->GetHostContentSettingsMap()->
       ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
 
   message_loop_runner->Run();
@@ -801,18 +803,18 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - default", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       LocalResetNotificationsPermissionUnregisters) {
+                       LocalResetNotificationsPermissionUnsubscribes) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -823,7 +825,7 @@
       message_loop_runner->QuitClosure());
 
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::Wildcard(),
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
@@ -835,18 +837,18 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - default", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       DenyNotificationsPermissionUnregisters) {
+                       DenyNotificationsPermissionUnsubscribes) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -857,7 +859,7 @@
       message_loop_runner->QuitClosure());
 
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::Wildcard(),
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
@@ -869,18 +871,18 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - denied", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("false - not registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("false - not subscribed", script_result);
 }
 
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       GrantAlreadyGrantedPermissionDoesNotUnregister) {
+                       GrantAlreadyGrantedPermissionDoesNotUnsubscribe) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -891,13 +893,13 @@
       base::BarrierClosure(2, message_loop_runner->QuitClosure()));
 
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::Wildcard(),
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
       std::string(),
       CONTENT_SETTING_ALLOW);
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::FromURLNoWildcard(origin),
       CONTENT_SETTINGS_TYPE_PUSH_MESSAGING,
@@ -909,22 +911,22 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 }
 
 // This test is testing some non-trivial content settings rules and make sure
-// that they are respected with regards to automatic unregistration. In other
-// words, it checks that the push service does not end up unregistering origins
+// that they are respected with regards to automatic unsubscription. In other
+// words, it checks that the push service does not end up unsubscribing origins
 // that have push permission with some non-common rules.
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
-                       AutomaticUnregistrationFollowsContentSettingRules) {
+                       AutomaticUnsubscriptionFollowsContentSettingRules) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
@@ -935,25 +937,25 @@
       base::BarrierClosure(4, message_loop_runner->QuitClosure()));
 
   GURL origin = https_server()->GetURL(std::string()).GetOrigin();
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::Wildcard(),
       ContentSettingsPattern::Wildcard(),
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
       std::string(),
       CONTENT_SETTING_ALLOW);
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromString("https://*"),
       ContentSettingsPattern::FromString("https://*"),
       CONTENT_SETTINGS_TYPE_PUSH_MESSAGING,
       std::string(),
       CONTENT_SETTING_ALLOW);
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::Wildcard(),
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
       std::string(),
       CONTENT_SETTING_DEFAULT);
-  browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+  GetBrowser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
       ContentSettingsPattern::FromURLNoWildcard(origin),
       ContentSettingsPattern::FromURLNoWildcard(origin),
       CONTENT_SETTINGS_TYPE_PUSH_MESSAGING,
@@ -970,27 +972,27 @@
   ASSERT_TRUE(RunScript("hasPermission()", &script_result));
   EXPECT_EQ("permission status - granted", script_result);
 
-  ASSERT_TRUE(RunScript("hasRegistration()", &script_result));
-  EXPECT_EQ("true - registered", script_result);
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  EXPECT_EQ("true - subscribed", script_result);
 }
 
 // Checks that automatically unsubscribing due to a revoked permission is
-// handled well if the sender ID needed to unregister was already deleted.
+// handled well if the sender ID needed to unsubscribe was already deleted.
 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
                        ResetPushPermissionAfterClearingSiteData) {
   std::string script_result;
 
-  TryToRegisterSuccessfully("1-0" /* expected_push_registration_id */);
+  TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */);
 
   PushMessagingApplicationId app_id = GetServiceWorkerAppId(0LL);
   EXPECT_EQ(app_id.app_id_guid(), gcm_service()->last_registered_app_id());
   PushMessagingApplicationId stored_app_id = PushMessagingApplicationId::Get(
-      browser()->profile(), app_id.app_id_guid());
+      GetBrowser()->profile(), app_id.app_id_guid());
   EXPECT_TRUE(stored_app_id.IsValid());
 
   // Simulate a user clearing site data (including Service Workers, crucially).
   BrowsingDataRemover* remover =
-      BrowsingDataRemover::CreateForUnboundedRange(browser()->profile());
+      BrowsingDataRemover::CreateForUnboundedRange(GetBrowser()->profile());
   BrowsingDataRemoverCompletionObserver observer(remover);
   remover->Remove(BrowsingDataRemover::REMOVE_SITE_DATA,
                   BrowsingDataHelper::UNPROTECTED_WEB);
@@ -1003,14 +1005,46 @@
 
   // This shouldn't (asynchronously) cause a DCHECK.
   // TODO(johnme): Get this test running on Android, which has a different
-  // codepath due to sender_id being required for unregistering there.
-  browser()->profile()->GetHostContentSettingsMap()->
+  // codepath due to sender_id being required for unsubscribeing there.
+  GetBrowser()->profile()->GetHostContentSettingsMap()->
       ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
 
   run_loop.Run();
 
   // app_id should no longer be stored in prefs
   PushMessagingApplicationId stored_app_id2 = PushMessagingApplicationId::Get(
-      browser()->profile(), app_id.app_id_guid());
+      GetBrowser()->profile(), app_id.app_id_guid());
   EXPECT_FALSE(stored_app_id2.IsValid());
 }
+
+class PushMessagingIncognitoBrowserTest : public PushMessagingBrowserTest {
+ public:
+  ~PushMessagingIncognitoBrowserTest() override {}
+
+  // PushMessagingBrowserTest:
+  void SetUpOnMainThread() override {
+    incognito_browser_ = CreateIncognitoBrowser();
+    PushMessagingBrowserTest::SetUpOnMainThread();
+  }
+
+  Browser* GetBrowser() const override { return incognito_browser_; }
+
+ private:
+  Browser* incognito_browser_ = nullptr;
+};
+
+// Regression test for https://crbug.com/476474
+IN_PROC_BROWSER_TEST_F(PushMessagingIncognitoBrowserTest,
+                       IncognitoGetSubscriptionDoesNotHang) {
+  ASSERT_TRUE(GetBrowser()->profile()->IsOffTheRecord());
+
+  std::string script_result;
+
+  ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
+  ASSERT_EQ("ok - service worker registered", script_result);
+
+  // In Incognito mode the promise returned by getSubscription should not hang,
+  // it should just fulfill with null.
+  ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
+  ASSERT_EQ("false - not subscribed", script_result);
+}
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 3e494c81..3244504 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -372,7 +372,7 @@
     if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
       throttles->push_back(
           InterceptNavigationDelegate::CreateThrottleFor(request));
-    } else if (resource_type == content::RESOURCE_TYPE_XHR) {
+    } else {
       InterceptNavigationDelegate::UpdateUserGestureCarryoverInfo(request);
     }
   }
diff --git a/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.cc
index ef8480b..9af20a8c 100644
--- a/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.cc
@@ -75,6 +75,10 @@
   *display_id = display.id();
   return true;
 }
+
+void DoNothing(bool status) {
+}
+
 #endif
 
 }  // namespace
@@ -85,6 +89,12 @@
 class PepperOutputProtectionMessageFilter::Delegate
     : public aura::WindowObserver {
  public:
+  typedef base::Callback<void(int32_t /* result */,
+                              uint32_t /* link_mask */,
+                              uint32_t /* protection_mask*/)>
+      QueryStatusCallback;
+  typedef base::Callback<void(int32_t /* result */)> EnableProtectionCallback;
+
   Delegate(int render_process_id, int render_frame_id);
   ~Delegate() override;
 
@@ -93,12 +103,19 @@
       const aura::WindowObserver::HierarchyChangeParams& params) override;
   void OnWindowDestroying(aura::Window* window) override;
 
-  int32_t OnQueryStatus(uint32_t* link_mask, uint32_t* protection_mask);
-  int32_t OnEnableProtection(uint32_t desired_method_mask);
+  void QueryStatus(const QueryStatusCallback& callback);
+  void EnableProtection(uint32_t desired_method_mask,
+                        const EnableProtectionCallback& callback);
 
  private:
   ui::DisplayConfigurator::ContentProtectionClientId GetClientId();
 
+  void QueryStatusComplete(
+      const QueryStatusCallback& callback,
+      const ui::DisplayConfigurator::QueryProtectionResponse& response);
+  void EnableProtectionComplete(const EnableProtectionCallback& callback,
+                                bool success);
+
   // Used to lookup the WebContents associated with this PP_Instance.
   int render_process_id_;
   int render_frame_id_;
@@ -114,6 +131,9 @@
   // The last desired method mask. Will enable this mask on new display if
   // renderer changes display.
   uint32_t desired_method_mask_;
+
+  base::WeakPtrFactory<PepperOutputProtectionMessageFilter::Delegate>
+      weak_ptr_factory_;
 };
 
 PepperOutputProtectionMessageFilter::Delegate::Delegate(int render_process_id,
@@ -122,7 +142,8 @@
       render_frame_id_(render_frame_id),
       window_(NULL),
       client_id_(ui::DisplayConfigurator::kInvalidClientId),
-      display_id_(0) {
+      display_id_(0),
+      weak_ptr_factory_(this) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
 }
 
@@ -158,25 +179,56 @@
   return client_id_;
 }
 
-int32_t PepperOutputProtectionMessageFilter::Delegate::OnQueryStatus(
-    uint32_t* link_mask,
-    uint32_t* protection_mask) {
+void PepperOutputProtectionMessageFilter::Delegate::QueryStatus(
+    const QueryStatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
   content::RenderFrameHost* rfh =
       content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
   if (!rfh) {
     LOG(WARNING) << "RenderFrameHost is not alive.";
-    return PP_ERROR_FAILED;
+    callback.Run(PP_ERROR_FAILED, 0, 0);
+    return;
   }
 
   ui::DisplayConfigurator* configurator =
       ash::Shell::GetInstance()->display_configurator();
-  bool result = configurator->QueryContentProtectionStatus(
-      GetClientId(), display_id_, link_mask, protection_mask);
+  configurator->QueryContentProtectionStatus(
+      GetClientId(), display_id_,
+      base::Bind(
+          &PepperOutputProtectionMessageFilter::Delegate::QueryStatusComplete,
+          weak_ptr_factory_.GetWeakPtr(), callback));
+}
 
+void PepperOutputProtectionMessageFilter::Delegate::EnableProtection(
+    uint32_t desired_method_mask,
+    const EnableProtectionCallback& callback) {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+  ui::DisplayConfigurator* configurator =
+      ash::Shell::GetInstance()->display_configurator();
+  configurator->EnableContentProtection(
+      GetClientId(), display_id_, desired_method_mask,
+      base::Bind(&PepperOutputProtectionMessageFilter::Delegate::
+                     EnableProtectionComplete,
+                 weak_ptr_factory_.GetWeakPtr(), callback));
+  desired_method_mask_ = desired_method_mask;
+}
+
+void PepperOutputProtectionMessageFilter::Delegate::QueryStatusComplete(
+    const QueryStatusCallback& callback,
+    const ui::DisplayConfigurator::QueryProtectionResponse& response) {
+  content::RenderFrameHost* rfh =
+      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
+  if (!rfh) {
+    LOG(WARNING) << "RenderFrameHost is not alive.";
+    callback.Run(PP_ERROR_FAILED, 0, 0);
+    return;
+  }
+
+  uint32_t link_mask = response.link_mask;
   // If we successfully retrieved the device level status, check for capturers.
-  if (result) {
+  if (response.success) {
     const bool capture_detected =
         // Check for tab capture on the current tab.
         content::WebContents::FromRenderFrameHost(rfh)->GetCapturerCount() >
@@ -185,22 +237,17 @@
         MediaCaptureDevicesDispatcher::GetInstance()
             ->IsDesktopCaptureInProgress();
     if (capture_detected)
-      *link_mask |= ui::DISPLAY_CONNECTION_TYPE_NETWORK;
+      link_mask |= ui::DISPLAY_CONNECTION_TYPE_NETWORK;
   }
 
-  return result ? PP_OK : PP_ERROR_FAILED;
+  callback.Run(response.success ? PP_OK : PP_ERROR_FAILED, link_mask,
+               response.protection_mask);
 }
 
-int32_t PepperOutputProtectionMessageFilter::Delegate::OnEnableProtection(
-    uint32_t desired_method_mask) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
-  ui::DisplayConfigurator* configurator =
-      ash::Shell::GetInstance()->display_configurator();
-  bool result = configurator->EnableContentProtection(
-      GetClientId(), display_id_, desired_method_mask);
-  desired_method_mask_ = desired_method_mask;
-  return result ? PP_OK : PP_ERROR_FAILED;
+void PepperOutputProtectionMessageFilter::Delegate::EnableProtectionComplete(
+    const EnableProtectionCallback& callback,
+    bool result) {
+  callback.Run(result ? PP_OK : PP_ERROR_FAILED);
 }
 
 void PepperOutputProtectionMessageFilter::Delegate::OnWindowHierarchyChanged(
@@ -222,10 +269,12 @@
     // Display changed and should enable output protections on new display.
     ui::DisplayConfigurator* configurator =
         ash::Shell::GetInstance()->display_configurator();
-    configurator->EnableContentProtection(
-        GetClientId(), new_display_id, desired_method_mask_);
-    configurator->EnableContentProtection(
-        GetClientId(), display_id_, ui::CONTENT_PROTECTION_METHOD_NONE);
+    configurator->EnableContentProtection(GetClientId(), new_display_id,
+                                          desired_method_mask_,
+                                          base::Bind(&DoNothing));
+    configurator->EnableContentProtection(GetClientId(), display_id_,
+                                          ui::CONTENT_PROTECTION_METHOD_NONE,
+                                          base::Bind(&DoNothing));
   }
   display_id_ = new_display_id;
 }
@@ -240,7 +289,8 @@
 
 PepperOutputProtectionMessageFilter::PepperOutputProtectionMessageFilter(
     content::BrowserPpapiHost* host,
-    PP_Instance instance) {
+    PP_Instance instance)
+    : weak_ptr_factory_(this) {
 #if defined(OS_CHROMEOS)
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   int render_process_id = 0;
@@ -283,15 +333,11 @@
 int32_t PepperOutputProtectionMessageFilter::OnQueryStatus(
     ppapi::host::HostMessageContext* context) {
 #if defined(OS_CHROMEOS)
-  uint32_t link_mask = 0, protection_mask = 0;
-  int32_t result = delegate_->OnQueryStatus(&link_mask, &protection_mask);
-
   ppapi::host::ReplyMessageContext reply_context =
       context->MakeReplyMessageContext();
-  reply_context.params.set_result(result);
-  SendReply(reply_context,
-            PpapiPluginMsg_OutputProtection_QueryStatusReply(link_mask,
-                                                             protection_mask));
+  delegate_->QueryStatus(
+      base::Bind(&PepperOutputProtectionMessageFilter::OnQueryStatusComplete,
+                 weak_ptr_factory_.GetWeakPtr(), reply_context));
   return PP_OK_COMPLETIONPENDING;
 #else
   NOTIMPLEMENTED();
@@ -305,10 +351,11 @@
 #if defined(OS_CHROMEOS)
   ppapi::host::ReplyMessageContext reply_context =
       context->MakeReplyMessageContext();
-  int32_t result = delegate_->OnEnableProtection(desired_method_mask);
-  reply_context.params.set_result(result);
-  SendReply(reply_context,
-            PpapiPluginMsg_OutputProtection_EnableProtectionReply());
+  delegate_->EnableProtection(
+      desired_method_mask,
+      base::Bind(
+          &PepperOutputProtectionMessageFilter::OnEnableProtectionComplete,
+          weak_ptr_factory_.GetWeakPtr(), reply_context));
   return PP_OK_COMPLETIONPENDING;
 #else
   NOTIMPLEMENTED();
@@ -316,4 +363,22 @@
 #endif
 }
 
+void PepperOutputProtectionMessageFilter::OnQueryStatusComplete(
+    ppapi::host::ReplyMessageContext reply_context,
+    int32_t result,
+    uint32_t link_mask,
+    uint32_t protection_mask) {
+  reply_context.params.set_result(result);
+  SendReply(reply_context, PpapiPluginMsg_OutputProtection_QueryStatusReply(
+                               link_mask, protection_mask));
+}
+
+void PepperOutputProtectionMessageFilter::OnEnableProtectionComplete(
+    ppapi::host::ReplyMessageContext reply_context,
+    int32_t result) {
+  reply_context.params.set_result(result);
+  SendReply(reply_context,
+            PpapiPluginMsg_OutputProtection_EnableProtectionReply());
+}
+
 }  // namespace chrome
diff --git a/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h b/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h
index c9e575e..bb6004f 100644
--- a/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h
+++ b/chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_OUTPUT_PROTECTION_MESSAGE_FILTER_H_
 #define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_OUTPUT_PROTECTION_MESSAGE_FILTER_H_
 
+#include "base/memory/weak_ptr.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/host/resource_message_filter.h"
 
@@ -44,11 +45,22 @@
   int32_t OnEnableProtection(ppapi::host::HostMessageContext* context,
                              uint32_t desired_method_mask);
 
+  void OnQueryStatusComplete(ppapi::host::ReplyMessageContext reply_context,
+                             int32_t result,
+                             uint32_t link_mask,
+                             uint32_t protection_mask);
+
+  void OnEnableProtectionComplete(
+      ppapi::host::ReplyMessageContext reply_context,
+      int32_t result);
+
 #if defined(OS_CHROMEOS)
   // Delegator. Should be deleted in UI thread.
   Delegate* delegate_;
 #endif
 
+  base::WeakPtrFactory<PepperOutputProtectionMessageFilter> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(PepperOutputProtectionMessageFilter);
 };
 
diff --git a/chrome/browser/resources/chromeos/login/header_bar.js b/chrome/browser/resources/chromeos/login/header_bar.js
index cc718ce8..6a07090 100644
--- a/chrome/browser/resources/chromeos/login/header_bar.js
+++ b/chrome/browser/resources/chromeos/login/header_bar.js
@@ -327,12 +327,24 @@
           (Oobe.getInstance().displayType == DISPLAY_TYPE.USER_ADDING);
       var isLockScreen =
           (Oobe.getInstance().displayType == DISPLAY_TYPE.LOCK);
+      var isNewGaiaScreenWithBackButton =
+           gaiaIsActive &&
+           this.isNewGaiaFlow_ &&
+           !($('back-button-item').hidden);
+      var supervisedUserCreationDialogIsActiveAndNotIntro =
+          supervisedUserCreationDialogIsActive &&
+          $('supervised-user-creation').currentPage_ != 'intro';
 
       $('add-user-button').hidden =
-          !accountPickerIsActive || isMultiProfilesUI || isLockScreen;
-      $('more-settings-header-bar-item').hidden = !this.isNewGaiaFlow_ ||
+          (!this.isNewGaiaFlow_ && !accountPickerIsActive) ||
+          (this.isNewGaiaFlow_ && gaiaIsActive) ||
+          isMultiProfilesUI ||
+          isLockScreen ||
+          supervisedUserCreationDialogIsActiveAndNotIntro;
+      $('more-settings-header-bar-item').hidden =
           !this.showCreateSupervised_ ||
-          !accountPickerIsActive;
+          isNewGaiaScreenWithBackButton ||
+          supervisedUserCreationDialogIsActive;
       $('cancel-add-user-button').hidden =
           (gaiaIsActive && this.isNewGaiaFlow_) ||
           accountPickerIsActive ||
@@ -341,11 +353,12 @@
           isMultiProfilesUI;
       $('guest-user-header-bar-item').hidden =
           (gaiaIsActive && !this.isNewGaiaFlow_) ||
-          supervisedUserCreationDialogIsActive ||
+          supervisedUserCreationDialogIsActiveAndNotIntro ||
           !this.showGuest_ ||
           wrongHWIDWarningIsActive ||
           isSamlPasswordConfirm ||
-          isMultiProfilesUI;
+          isMultiProfilesUI ||
+          isNewGaiaScreenWithBackButton;
       $('restart-header-bar-item').hidden = !this.showReboot_;
       $('shutdown-header-bar-item').hidden = !this.showShutdown_;
       $('sign-out-user-item').hidden = !isLockScreen;
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index 9e1bfef..2da77e3 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -11,6 +11,11 @@
   // lazy portal check should be fired.
   /** @const */ var GAIA_LOADING_PORTAL_SUSSPECT_TIME_SEC = 7;
 
+  // GAIA animation guard timer. Started when GAIA page is loaded
+  // (Authenticator 'ready' event) and is intended to guard against edge cases
+  // when 'showView' message is not generated/received.
+  /** @const */ var GAIA_ANIMATION_GUARD_MILLISEC = 300;
+
   // Maximum Gaia loading time in seconds.
   /** @const */ var MAX_GAIA_LOADING_TIME_SEC = 60;
 
@@ -78,6 +83,22 @@
     loadingTimer_: undefined,
 
     /**
+     * Timer id of a guard timer that is fired in case 'showView' message
+     * is not received from GAIA.
+     * @type {number}
+     * @private
+     */
+    loadAnimationGuardTimer_: undefined,
+
+    /**
+     * Whether we've processed 'showView' message - either from GAIA or from
+     * guard timer.
+     * @type {boolean}
+     * @private
+     */
+    showViewProcessed_: undefined,
+
+    /**
      * Whether user can cancel Gaia screen.
      * @type {boolean}
      * @private
@@ -220,6 +241,7 @@
       $('enterprise-info-container').hidden = show;
       $('gaia-signin-divider').hidden = show;
       this.classList.toggle('loading', show);
+      $('signin-frame').classList.remove('show');
       if (!show)
         this.classList.remove('auth-completed');
     },
@@ -232,7 +254,7 @@
       if (this != Oobe.getInstance().currentScreen)
         return;
       chrome.send('showLoadingTimeoutError');
-      this.loadingTimer_ = window.setTimeout(
+      this.loadingTimer_ = setTimeout(
           this.onLoadingTimeOut_.bind(this),
           (MAX_GAIA_LOADING_TIME_SEC - GAIA_LOADING_PORTAL_SUSSPECT_TIME_SEC) *
           1000);
@@ -253,7 +275,7 @@
      */
     clearLoadingTimer_: function() {
       if (this.loadingTimer_) {
-        window.clearTimeout(this.loadingTimer_);
+        clearTimeout(this.loadingTimer_);
         this.loadingTimer_ = undefined;
       }
     },
@@ -264,12 +286,43 @@
      */
     startLoadingTimer_: function() {
       this.clearLoadingTimer_();
-      this.loadingTimer_ = window.setTimeout(
+      this.loadingTimer_ = setTimeout(
           this.onLoadingSuspiciouslyLong_.bind(this),
           GAIA_LOADING_PORTAL_SUSSPECT_TIME_SEC * 1000);
     },
 
     /**
+     * Handler for GAIA animation guard timer.
+     * @private
+     */
+    onLoadAnimationGuardTimer_: function() {
+      this.loadAnimationGuardTimer_ = undefined;
+      this.onShowView_();
+    },
+
+    /**
+     * Clears GAIA animation guard timer.
+     * @private
+     */
+    clearLoadAnimationGuardTimer_: function() {
+      if (this.loadAnimationGuardTimer_) {
+        clearTimeout(this.loadAnimationGuardTimer_);
+        this.loadAnimationGuardTimer_ = undefined;
+      }
+    },
+
+    /**
+     * Sets up GAIA animation guard timer.
+     * @private
+     */
+    startLoadAnimationGuardTimer_: function() {
+      this.clearLoadAnimationGuardTimer_();
+      this.loadAnimationGuardTimer_ = setTimeout(
+          this.onLoadAnimationGuardTimer_.bind(this),
+          GAIA_ANIMATION_GUARD_MILLISEC);
+    },
+
+    /**
      * Whether Gaia is loading.
      * @type {boolean}
      */
@@ -496,17 +549,15 @@
      * @private
      */
     onAuthReady_: function() {
-      this.loading = false;
+      showViewProcessed_ = false;
+      if (this.isNewGaiaFlow)
+        this.startLoadAnimationGuardTimer_();
+
       this.clearLoadingTimer_();
+      this.loading = false;
 
-      // Show deferred error bubble.
-      if (this.errorBubble_) {
-        this.showErrorBubble(this.errorBubble_[0], this.errorBubble_[1]);
-        this.errorBubble_ = undefined;
-      }
-
-      chrome.send('loginWebuiReady');
-      chrome.send('loginVisible', ['gaia-signin']);
+      if (!this.isNewGaiaFlow)
+        this.onLoginUIVisible_();
 
       // Warm up the user images screen.
       Oobe.getInstance().preloadScreen({id: SCREEN_USER_IMAGE_PICKER});
@@ -536,14 +587,37 @@
      */
     onBackButton_: function(e) {
       $('back-button-item').hidden = !e.detail;
+      $('login-header-bar').updateUI_();
     },
 
     /**
-     * Invoked when the auth host emits 'showView' event.
+     * Invoked when the auth host emits 'showView' event or when corresponding
+     * guard time fires.
      * @private
      */
     onShowView_: function(e) {
+      if (showViewProcessed_)
+        return;
+
+      showViewProcessed_ = true;
+      this.clearLoadAnimationGuardTimer_();
       $('signin-frame').classList.add('show');
+      this.onLoginUIVisible_();
+    },
+
+    /**
+     * Called when UI is shown.
+     * @private
+     */
+    onLoginUIVisible_: function() {
+      // Show deferred error bubble.
+      if (this.errorBubble_) {
+        this.showErrorBubble(this.errorBubble_[0], this.errorBubble_[1]);
+        this.errorBubble_ = undefined;
+      }
+
+      chrome.send('loginWebuiReady');
+      chrome.send('loginVisible', ['gaia-signin']);
     },
 
     /**
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
index d3a7f89..be8f355 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
@@ -1123,7 +1123,7 @@
       var pagesWithCancel = ['intro', 'manager', 'username', 'import-password',
           'error', 'import'];
       $('login-header-bar').allowCancel =
-          pagesWithCancel.indexOf(visiblePage) > 0;
+          pagesWithCancel.indexOf(visiblePage) > -1;
       $('cancel-add-user-button').disabled = false;
 
       this.getScreenElement('import-link').hidden = true;
@@ -1139,6 +1139,7 @@
             'password-error');
         if (this.managerList_.pods.length > 0)
           this.managerList_.selectPod(this.managerList_.pods[0]);
+        $('login-header-bar').updateUI_();
       }
 
       if (visiblePage == 'username' || visiblePage == 'import-password') {
@@ -1342,6 +1343,8 @@
       var notSignedInPages = ['intro', 'manager'];
       var postCreationPages = ['created'];
       if (notSignedInPages.indexOf(this.currentPage_) >= 0) {
+        chrome.send('hideLocalSupervisedUserCreation');
+
         // Make sure no manager password is kept:
         this.managerList_.clearPods();
 
diff --git a/chrome/browser/resources/chromeos/login/throbber_notice.css b/chrome/browser/resources/chromeos/login/throbber_notice.css
new file mode 100644
index 0000000..8086a06
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/throbber_notice.css
@@ -0,0 +1,21 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+paper-spinner::shadow .circle {
+  border-color: rgb(66, 133, 244);
+}
+
+paper-spinner {
+  height: 36px;
+  width: 36px;
+}
+
+#spinner-container {
+  margin-bottom: 25px;
+}
+
+#spinner-comment {
+  color: grey;
+}
diff --git a/chrome/browser/resources/chromeos/login/throbber_notice.html b/chrome/browser/resources/chromeos/login/throbber_notice.html
index 0844dd2..243432de 100644
--- a/chrome/browser/resources/chromeos/login/throbber_notice.html
+++ b/chrome/browser/resources/chromeos/login/throbber_notice.html
@@ -3,25 +3,10 @@
 
 <polymer-element name="throbber-notice" attributes="text" noscript>
   <template>
-    <style>
-      paper-spinner::shadow .circle {
-        border-color: #4285f4;
-      }
-
-      paper-spinner {
-        height: 36px;
-        width: 36px;
-      }
-      #spinner-container {
-        margin-bottom: 25px;
-      }
-      #spinner-comment {
-        color: grey;
-      }
-    </style>
+    <link rel="stylesheet" href="throbber_notice.css">
     <div id="spinner-container" vertical layout center>
-      <paper-spinner active></paper-spinner>
+      <paper-spinner dir="ltr" active></paper-spinner>
     </div>
     <div id="spinner-comment">{{text}}</div>
   </template>
-</polymer-element>
\ No newline at end of file
+</polymer-element>
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index d5f5374..7e2b0344 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -174,6 +174,7 @@
         <include name="IDR_PDF_VIEWPORT_SCROLLER_JS" file="pdf/viewport_scroller.js" type="BINDATA" />
         <include name="IDR_PDF_PDF_SCRIPTING_API_JS" file="pdf/pdf_scripting_api.js" type="BINDATA" />
         <include name="IDR_PDF_ZOOM_MANAGER_JS" file="pdf/zoom_manager.js" type="BINDATA" />
+        <include name="IDR_PDF_BROWSER_API_JS" file="pdf/browser_api.js" type="BINDATA" />
         <include name="IDR_PDF_CONTENT_SCRIPT_JS" file="pdf/content_script.js" type="BINDATA" />
 
         <include name="IDR_PDF_VIEWER_BOOKMARK_CSS" file="pdf/elements/viewer-bookmark/viewer-bookmark.css" type="BINDATA" />
diff --git a/chrome/browser/resources/extensions/extension_error.js b/chrome/browser/resources/extensions/extension_error.js
index 6e3418d..7b9b7a1 100644
--- a/chrome/browser/resources/extensions/extension_error.js
+++ b/chrome/browser/resources/extensions/extension_error.js
@@ -37,7 +37,7 @@
   function ExtensionError(error, boundary) {
     var div = cloneTemplate('extension-error-metadata');
     div.__proto__ = ExtensionError.prototype;
-    div.decorate(error, boundary);
+    div.decorateWithError_(error, boundary);
     return div;
   }
 
@@ -51,12 +51,12 @@
 
     /**
      * @param {(RuntimeError|ManifestError)} error The error the element should
-     *     represent
+     *     represent.
      * @param {Element} boundary The boundary for the FocusGrid.
-     * @override
+     * @private
      */
-    decorate: function(error, boundary) {
-      cr.ui.FocusRow.prototype.decorate.call(this, boundary);
+    decorateWithError_: function(error, boundary) {
+      this.decorate(boundary);
 
       // Add an additional class for the severity level.
       if (error.type == chrome.developerPrivate.ErrorType.RUNTIME) {
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js
index bb126d5..fe1cec3 100644
--- a/chrome/browser/resources/extensions/extension_list.js
+++ b/chrome/browser/resources/extensions/extension_list.js
@@ -245,6 +245,7 @@
           case EventType.LOADED:
           case EventType.UNLOADED:
           case EventType.ERROR_ADDED:
+          case EventType.PREFS_CHANGED:
             if (eventData.extensionInfo)
               this.updateExtension_(eventData.extensionInfo);
             break;
@@ -666,14 +667,14 @@
                              !extension.optionsPage.openInTab);
 
       // The 'View in Web Store/View Web Site' link.
-      var siteLinkEnabled = !!extension.homepageUrl &&
+      var siteLinkEnabled = !!extension.homePage.url &&
                             !this.enableAppInfoDialog_;
       this.updateVisibility_(row, '.site-link', siteLinkEnabled,
                              function(item) {
-        item.href = extension.homepageUrl;
+        item.href = extension.homePage.url;
         item.textContent = loadTimeData.getString(
-            extension.homepageProvided ? 'extensionSettingsVisitWebsite' :
-                                         'extensionSettingsVisitWebStore');
+            extension.homePage.specified ? 'extensionSettingsVisitWebsite' :
+                                           'extensionSettingsVisitWebStore');
       });
 
       var isUnpacked =
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js
index f1843d312..06b62379 100644
--- a/chrome/browser/resources/extensions/extensions.js
+++ b/chrome/browser/resources/extensions/extensions.js
@@ -150,6 +150,9 @@
         extensionList.updateFocusableElements();
         chrome.developerPrivate.updateProfileConfiguration(
             {inDeveloperMode: e.target.checked});
+        var suffix = $('toggle-dev-on').checked ? 'Enabled' : 'Disabled';
+        chrome.send('metricsHandler:recordAction',
+                    ['Options_ToggleDeveloperMode_' + suffix]);
       }.bind(this));
 
       window.addEventListener('resize', function() {
@@ -158,6 +161,8 @@
 
       // Set up the three dev mode buttons (load unpacked, pack and update).
       $('load-unpacked').addEventListener('click', function(e) {
+        chrome.send('metricsHandler:recordAction',
+                    ['Options_LoadUnpackedExtension']);
         extensionLoader.loadUnpacked();
       });
       $('pack-extension').addEventListener('click',
@@ -187,6 +192,16 @@
       extensions.ExtensionOptionsOverlay.getInstance().initializePage(
           extensions.ExtensionSettings.showOverlay);
 
+      // Add user action logging for bottom links.
+      var moreExtensionLink =
+          document.getElementsByClassName('more-extensions-link');
+      for (var i = 0; i < moreExtensionLink.length; i++) {
+        moreExtensionLink[i].addEventListener('click', function(e) {
+          chrome.send('metricsHandler:recordAction',
+                      ['Options_GetMoreExtensions']);
+        });
+      }
+
       // Initialize the kiosk overlay.
       if (cr.isChromeOS) {
         var kioskOverlay = extensions.KioskAppsOverlay.getInstance();
@@ -304,6 +319,8 @@
      */
     handleUpdateExtensionNow_: function(e) {
       chrome.developerPrivate.autoUpdate();
+      chrome.send('metricsHandler:recordAction',
+                  ['Options_UpdateExtensions']);
     },
 
     /**
diff --git a/chrome/browser/resources/history/history.css b/chrome/browser/resources/history/history.css
index 7a356bb..a1d191b 100644
--- a/chrome/browser/resources/history/history.css
+++ b/chrome/browser/resources/history/history.css
@@ -417,6 +417,11 @@
   border-radius: 2px;
 }
 
+.entry-box > div,
+.site-domain-row > div {
+  min-width: 0;
+}
+
 .active :-webkit-any(.entry-box, .site-domain-row) {
   background-color: rgba(0, 0, 0, .05);
 }
diff --git a/chrome/browser/resources/net_internals/bandwidth_view.js b/chrome/browser/resources/net_internals/bandwidth_view.js
index d5c7c62..2c4767a 100644
--- a/chrome/browser/resources/net_internals/bandwidth_view.js
+++ b/chrome/browser/resources/net_internals/bandwidth_view.js
@@ -220,6 +220,7 @@
      */
     updateDataReductionProxyConfig_: function() {
       $(BandwidthView.PROXY_CONFIG_ID).innerHTML = '';
+      $(BandwidthView.BYPASS_STATE_ID).innerHTML = '';
       setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), false);
 
       if (this.data_reduction_proxy_config_) {
@@ -257,8 +258,6 @@
         if (hasBypassedProxy) {
           this.createEventTable_(this.last_bypass_.params,
                                  $(BandwidthView.BYPASS_STATE_ID));
-        } else {
-          $(BandwidthView.BYPASS_STATE_ID).innerHtml = '';
         }
 
         this.createEventTable_(this.data_reduction_proxy_config_,
diff --git a/chrome/browser/resources/net_internals/browser_bridge.js b/chrome/browser/resources/net_internals/browser_bridge.js
index 20315821..2b976a4c 100644
--- a/chrome/browser/resources/net_internals/browser_bridge.js
+++ b/chrome/browser/resources/net_internals/browser_bridge.js
@@ -215,8 +215,8 @@
       this.send('enableIPv6');
     },
 
-    setLogLevel: function(logLevel) {
-      this.send('setLogLevel', ['' + logLevel]);
+    setCaptureMode: function(captureMode) {
+      this.send('setCaptureMode', ['' + captureMode]);
     },
 
     importONCFile: function(fileContent, passcode) {
diff --git a/chrome/browser/resources/net_internals/capture_view.js b/chrome/browser/resources/net_internals/capture_view.js
index 4b0a20f6..244dc1ce 100644
--- a/chrome/browser/resources/net_internals/capture_view.js
+++ b/chrome/browser/resources/net_internals/capture_view.js
@@ -85,7 +85,7 @@
       var byteLoggingCheckbox = $(CaptureView.BYTE_LOGGING_CHECKBOX_ID);
 
       if (byteLoggingCheckbox.checked) {
-        g_browser.setLogLevel(LogLevelType.LOG_ALL);
+        g_browser.setCaptureMode('IncludeSocketBytes');
 
         // Once we enable byte logging, all bets are off on what gets captured.
         // Have the export view warn that the "strip cookies" option is
@@ -97,7 +97,7 @@
         // reload.
         ExportView.getInstance().showPrivacyWarning();
       } else {
-        g_browser.setLogLevel(LogLevelType.LOG_ALL_BUT_BYTES);
+        g_browser.setCaptureMode('IncludeCookiesAndCredentials');
       }
     },
 
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index 0b49ad7..ab87b14 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -12,7 +12,6 @@
 var EventPhase = null;
 var EventSourceType = null;
 var EventSourceTypeNames = null;
-var LogLevelType = null;
 var ClientInfo = null;
 var NetError = null;
 var QuicError = null;
@@ -300,7 +299,6 @@
   EventPhase = Constants.logEventPhase;
   EventSourceType = Constants.logSourceType;
   EventSourceTypeNames = makeInverseMap(EventSourceType);
-  LogLevelType = Constants.logLevelType;
   ClientInfo = Constants.clientInfo;
   LoadFlag = Constants.loadFlag;
   NetError = Constants.netError;
@@ -331,7 +329,6 @@
          typeof(receivedConstants.clientInfo) == 'object' &&
          typeof(receivedConstants.logEventPhase) == 'object' &&
          typeof(receivedConstants.logSourceType) == 'object' &&
-         typeof(receivedConstants.logLevelType) == 'object' &&
          typeof(receivedConstants.loadFlag) == 'object' &&
          typeof(receivedConstants.netError) == 'object' &&
          typeof(receivedConstants.addressFamily) == 'object' &&
diff --git a/chrome/browser/resources/options/autofill_options_list.js b/chrome/browser/resources/options/autofill_options_list.js
index 004f6213..7db223b 100644
--- a/chrome/browser/resources/options/autofill_options_list.js
+++ b/chrome/browser/resources/options/autofill_options_list.js
@@ -495,11 +495,9 @@
   AutofillValuesList.prototype = {
     __proto__: InlineEditableItemList.prototype,
 
-    /**
-     * @override
-     * @param {string} entry
-     */
+    /** @override */
     createItem: function(entry) {
+      assert(entry === null || typeof entry == 'string');
       return new ValuesListItem(this, entry);
     },
 
@@ -540,10 +538,11 @@
 
     /**
      * @override
-     * @param {Array<string>} entry
+     * @param {?string|Array<string>} entry
      */
     createItem: function(entry) {
-      return new NameListItem(this, entry);
+      var arrayOrNull = entry ? assertInstanceof(entry, Array) : null;
+      return new NameListItem(this, arrayOrNull);
     },
   };
 
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 5cbe5c4..2f6aad4 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -241,13 +241,17 @@
 <if expr="not chromeos">
       <div id="profiles-enable-guest" class="checkbox">
         <label>
-          <input pref="profile.browser_guest_enabled" type="checkbox">
+          <input pref="profile.browser_guest_enabled"
+                 type="checkbox"
+                 metric="Options_BrowserGuestEnabled">
           <span i18n-content="profileBrowserGuestEnable"></span>
         </label>
       </div>
       <div id="profiles-enable-add-person" class="checkbox">
         <label>
-          <input pref="profile.add_person_enabled" type="checkbox">
+          <input pref="profile.add_person_enabled"
+                 type="checkbox"
+                 metric="Options_AddPersonEnabled">
           <span i18n-content="profileAddPersonEnable"></span>
         </label>
       </div>
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index b161c32..f104402a 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -204,8 +204,6 @@
           networkIndicator.setAttribute('controlled-by', 'shared');
           networkIndicator.location = cr.ui.ArrowLocation.TOP_START;
         }
-        options.network.NetworkList.refreshNetworkData(
-            loadTimeData.getValue('networkData'));
       }
 
       // On Startup section.
@@ -345,6 +343,8 @@
         profilesList.addEventListener('change',
             this.setProfileViewButtonsStatus_);
         $('profiles-create').onclick = function(event) {
+          chrome.send('metricsHandler:recordAction',
+                      ['Options_ShowCreateProfileDlg']);
           ManageProfileOverlay.showCreateDialog();
         };
         if (OptionsPage.isSettingsApp()) {
@@ -354,12 +354,17 @@
           };
         }
         $('profiles-manage').onclick = function(event) {
+          chrome.send('metricsHandler:recordAction',
+                      ['Options_ShowEditProfileDlg']);
           ManageProfileOverlay.showManageDialog();
         };
         $('profiles-delete').onclick = function(event) {
           var selectedProfile = self.getSelectedProfileItem_();
-          if (selectedProfile)
+          if (selectedProfile) {
+            chrome.send('metricsHandler:recordAction',
+                        ['Options_ShowDeleteProfileDlg']);
             ManageProfileOverlay.showDeleteDialog(selectedProfile);
+          }
         };
         if (loadTimeData.getBoolean('profileIsSupervised')) {
           $('profiles-create').disabled = true;
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js
index a077fbd..449ee372 100644
--- a/chrome/browser/resources/options/chromeos/internet_detail.js
+++ b/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -235,6 +235,10 @@
     initializePage: function() {
       Page.prototype.initializePage.call(this);
       this.initializePageContents_();
+
+      chrome.networkingPrivate.onNetworksChanged.addListener(
+          this.onNetworksChanged_.bind(this));
+
       this.showNetworkDetails_();
     },
 
@@ -252,6 +256,22 @@
     },
 
     /**
+     * networkingPrivate callback when networks change.
+     * @param {Array<string>} changes List of GUIDs whose properties have
+     *     changed.
+     * @private
+     */
+    onNetworksChanged_: function(changes) {
+      if (!this.onc_)
+        return;
+      var guid = this.onc_.guid();
+      if (changes.indexOf(guid) != -1) {
+        chrome.networkingPrivate.getManagedProperties(
+          guid, DetailsInternetPage.updateConnectionData);
+      }
+    },
+
+    /**
      * Initializes the contents of the page.
      */
     initializePageContents_: function() {
@@ -1011,9 +1031,7 @@
      * Event Listener for the cellular-apn-cancel button.
      * @private
      */
-    cancelApn_: function() {
-      this.initializeApnList_();
-    },
+    cancelApn_: function() { this.initializeApnList_(); },
 
     /**
      * Event Listener for the select-apn button.
@@ -1421,9 +1439,6 @@
     detailsPage.updateConnectionButtonVisibilty_();
     detailsPage.updateDetails_();
 
-    // Inform chrome which network to pass events for in InternetOptionsHandler.
-    chrome.send('setNetworkGuid', [detailsPage.onc_.guid()]);
-
     // TODO(stevenjb): Some of the setup below should be moved to
     // updateDetails_() so that updates are reflected in the UI.
 
diff --git a/chrome/browser/resources/options/chromeos/network_list.js b/chrome/browser/resources/options/chromeos/network_list.js
index 8a1b99c..2dd366a 100644
--- a/chrome/browser/resources/options/chromeos/network_list.js
+++ b/chrome/browser/resources/options/chromeos/network_list.js
@@ -3,19 +3,23 @@
 // found in the LICENSE file.
 
 /**
- * This partially describes the network list entries passed to
- * refreshNetworkData. The contents of those lists actually match
- * chrome.networkingPrivate.NetworkStateProperties with the addition of the
- * policyManaged property. TODO(stevenjb): Use networkingPrivate.getNetworks.
+ * Partial definition of the result of networkingPrivate.getProperties()).
  * @typedef {{
  *   ConnectionState: string,
+ *   Cellular: {
+ *     Family: ?string,
+ *     SIMPresent: ?boolean,
+ *     SIMLockStatus: { LockType: ?string },
+ *     SupportNetworkScan: ?boolean
+ *   },
  *   GUID: string,
- *   Type: string,
- *   policyManaged: boolean
+ *   Name: string,
+ *   Source: string,
+ *   Type: string
  * }}
- * @see chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+ * @see extensions/common/api/networking_private.idl
  */
-var NetworkInfo;
+var NetworkProperties;
 
 cr.define('options.network', function() {
   var ArrayDataModel = cr.ui.ArrayDataModel;
@@ -68,42 +72,35 @@
    * @type {string|undefined}
    * @private
    */
-  var cellularState_ = undefined;
+  var cellularDeviceState_ = undefined;
 
   /**
-   * Indicates if cellular device supports network scanning.
-   * @type {boolean}
+   * The active cellular network or null if none.
+   * @type {?NetworkProperties}
    * @private
    */
-  var cellularSupportsScan_ = false;
+  var cellularNetwork_ = null;
 
   /**
-   * Indicates the current SIM lock type of the cellular device.
-   * @type {string}
+   * The active ethernet network or null if none.
+   * @type {?NetworkProperties}
    * @private
    */
-  var cellularSimLockType_ = '';
-
-  /**
-   * Indicates whether the SIM card is absent on the cellular device.
-   * @type {boolean}
-   * @private
-   */
-  var cellularSimAbsent_ = false;
+  var ethernetNetwork_ = null;
 
   /**
    * The state of the WiFi device or undefined if not available.
    * @type {string|undefined}
    * @private
    */
-  var wifiState_ = undefined;
+  var wifiDeviceState_ = undefined;
 
   /**
    * The state of the WiMAX device or undefined if not available.
    * @type {string|undefined}
    * @private
    */
-  var wimaxState_ = undefined;
+  var wimaxDeviceState_ = undefined;
 
   /**
    * Indicates if mobile data roaming is enabled.
@@ -113,36 +110,8 @@
   var enableDataRoaming_ = false;
 
   /**
-   * List of wired networks.
-   * @type {Array<!NetworkInfo>}
-   * @private
-   */
-  var wiredList_ = [];
-
-  /**
-   * List of WiFi, Cellular, and WiMAX networks.
-   * @type {Array<!NetworkInfo>}
-   * @private
-   */
-  var wirelessList_ = [];
-
-  /**
-   * List of VPN networks.
-   * @type {Array<!NetworkInfo>}
-   * @private
-   */
-  var vpnList_ = [];
-
-  /**
-   * List of remembered (favorite) networks.
-   * @type {Array<!NetworkInfo>}
-   * @private
-   */
-  var rememberedList_ = [];
-
-  /**
    * Returns the display name for 'network'.
-   * @param {Object} data The network data dictionary.
+   * @param {NetworkProperties} data The network data dictionary.
    */
   function getNetworkName(data) {
     if (data.Type == 'Ethernet')
@@ -236,7 +205,7 @@
 
     /**
      * Sets the icon based on a network state object.
-     * @param {!Object} data Object containing network state data.
+     * @param {!NetworkProperties} data Network state properties.
      */
     set iconData(data) {
       if (!isNetworkType(data.Type))
@@ -459,8 +428,8 @@
   /**
    * Creates a control for selecting or configuring a network connection based
    * on the type of connection (e.g. wifi versus vpn).
-   * @param {{key: string, networkList: Array<NetworkInfo>}} data Description
-   *     of the network.
+   * @param {{key: string, networkList: Array<!NetworkProperties>}} data
+   *     An object containing the network type (key) and an array of networks.
    * @constructor
    * @extends {NetworkMenuItem}
    */
@@ -471,13 +440,59 @@
     return el;
   }
 
+  /**
+   * Returns true if |source| is a policy managed source.
+   * @param {string} source The ONC source of a network.
+   * @return {boolean} Whether |source| is a managed source.
+   */
+  function isManaged(source) {
+    return (source == 'DevicePolicy' || source == 'UserPolicy');
+  }
+
+  /**
+   * Returns true if |network| is visible.
+   * @param {!chrome.networkingPrivate.NetworkStateProperties} network The
+   *     network state properties.
+   * @return {boolean} Whether |network| is visible.
+   */
+  function networkIsVisible(network) {
+    if (network.Type == 'WiFi')
+      return !!(network.WiFi && (network.WiFi.SignalStrength > 0));
+    if (network.Type == 'WiMAX')
+      return !!(network.WiMAX && (network.WiMAX.SignalStrength > 0));
+    // Other network types are always considered 'visible'.
+    return true;
+  }
+
+  /**
+   * Returns true if |cellular| is a GSM network with no sim present.
+   * @param {?NetworkProperties} cellular The network state properties.
+   * @return {boolean} Whether |network| is missing a SIM card.
+   */
+  function isCellularSimAbsent(cellular) {
+    if (!cellular || !cellular.Cellular)
+      return false;
+    return cellular.Cellular.Family == 'GSM' && !cellular.Cellular.SIMPresent;
+  }
+
+  /**
+   * Returns true if |cellular| has a locked SIM card.
+   * @param {?NetworkProperties} cellular The network state properties.
+   * @return {boolean} Whether |network| has a locked SIM card.
+   */
+  function isCellularSimLocked(cellular) {
+    if (!cellular || !cellular.Cellular)
+      return false;
+    var simLockStatus = cellular.Cellular.SIMLockStatus;
+    return !!(simLockStatus && simLockStatus.LockType);
+  }
+
   NetworkSelectorItem.prototype = {
     __proto__: NetworkMenuItem.prototype,
 
     /** @override */
     decorate: function() {
       // TODO(kevers): Generalize method of setting default label.
-      var policyManaged = false;
       this.subtitle = loadTimeData.getString('OncConnectionStateNotConnected');
       var list = this.data_.networkList;
       var candidateData = null;
@@ -487,7 +502,6 @@
             networkDetails.ConnectionState == 'Connected') {
           this.subtitle = getNetworkName(networkDetails);
           this.setSubtitleDirection('ltr');
-          policyManaged = networkDetails.policyManaged;
           candidateData = networkDetails;
           // Only break when we see a connecting network as it is possible to
           // have a connected network and a connecting network at the same
@@ -503,7 +517,7 @@
 
       this.showSelector();
 
-      if (policyManaged)
+      if (candidateData && isManaged(candidateData.Source))
         this.showManagedNetworkIndicator();
 
       if (activeMenu_ == this.getMenuName()) {
@@ -536,7 +550,9 @@
           data: {}
         });
       } else if (this.data_.key == 'Cellular') {
-        if (cellularState_ == 'Enabled' && cellularSupportsScan_) {
+        if (cellularDeviceState_ == 'Enabled' &&
+            cellularNetwork_ && cellularNetwork_.Cellular &&
+            cellularNetwork_.Cellular.SupportNetworkScan) {
           addendum.push({
             label: loadTimeData.getString('otherCellularNetworks'),
             command: createAddNonVPNConnectionCallback_('Cellular'),
@@ -737,7 +753,7 @@
     /**
      * Adds a menu item for showing network details.
      * @param {!Element} parent The parent element.
-     * @param {Object} data Description of the network.
+     * @param {NetworkProperties} data Description of the network.
      * @private
      */
     createNetworkOptionsCallback_: function(parent, data) {
@@ -745,7 +761,7 @@
                                      data,
                                      getNetworkName(data),
                                      showDetails.bind(null, data.GUID));
-      if (data.policyManaged)
+      if (isManaged(data.Source))
         menuItem.appendChild(new ManagedNetworkIndicator());
       if (data.ConnectionState == 'Connected' ||
           data.ConnectionState == 'Connecting') {
@@ -785,7 +801,7 @@
         this.iconData = this.data.iconData;
       else if (this.data.iconType)
         this.iconType = this.data.iconType;
-      if (this.data.policyManaged)
+      if (isManaged(this.data.Source))
         this.showManagedNetworkIndicator();
     },
   };
@@ -793,7 +809,7 @@
   /**
    * Adds a command to a menu for modifying network settings.
    * @param {!Element} menu Parent menu.
-   * @param {Object} data Description of the network.
+   * @param {?NetworkProperties} data Description of the network.
    * @param {!string} label Display name for the menu item.
    * @param {!Function} command Callback function.
    * @return {!Element} The created menu item.
@@ -876,10 +892,30 @@
           });
       this.endBatchUpdates();
 
+      this.onNetworkListChanged_();  // Trigger an initial network update
+
+      chrome.networkingPrivate.onNetworkListChanged.addListener(
+          this.onNetworkListChanged_.bind(this));
+
+      chrome.networkingPrivate.requestNetworkScan();
+
       options.VPNProviders.addObserver(this.onVPNProvidersChanged_.bind(this));
     },
 
     /**
+     * networkingPrivate event called when the network list has changed.
+     */
+    onNetworkListChanged_: function() {
+      var networkList = this;
+      chrome.networkingPrivate.getDeviceStates(function(deviceStates) {
+        var filter = { networkType: 'All' };
+        chrome.networkingPrivate.getNetworks(filter, function(networkStates) {
+          networkList.updateNetworkStates(deviceStates, networkStates);
+        });
+      });
+    },
+
+    /**
      * Called when the list of VPN providers changes. Refreshes the contents of
      * menus that list VPN providers.
      * @private
@@ -995,7 +1031,7 @@
 
     /**
      * Updates a network control.
-     * @param {Object<string,string>} data Description of the entry.
+     * @param {Object} data Description of the entry.
      */
     update: function(data) {
       this.startBatchUpdates();
@@ -1043,8 +1079,8 @@
     createItem: function(entry) {
       if (entry.networkList)
         return new NetworkSelectorItem(
-            /** @type {{key: string, networkList: Array<NetworkInfo>}} */(
-                entry));
+            /** @type {{key: string, networkList: Array<!NetworkProperties>}} */
+            (entry));
       if (entry.command)
         return new NetworkButtonItem(
             /** @type {{key: string, subtitle: string, command: Function}} */(
@@ -1076,105 +1112,122 @@
         entry.iconType = active ? 'control-active' : 'control-inactive';
         this.update(entry);
       }
-    }
-  };
+    },
 
-  /**
-   * Chrome callback for updating network controls.
-   * @param {{cellularSimAbsent: boolean,
-   *          cellularSimLockType: string,
-   *          cellularSupportsScan: boolean,
-   *          rememberedList: Array<NetworkInfo>,
-   *          vpnList: Array<NetworkInfo>,
-   *          wiredList: Array<NetworkInfo>,
-   *          wirelessList: Array<NetworkInfo>}} data Description of available
-   *     network devices and their corresponding state.
-   */
-  NetworkList.refreshNetworkData = function(data) {
-    cellularSupportsScan_ = data.cellularSupportsScan;
-    cellularSimAbsent_ = data.cellularSimAbsent;
-    cellularSimLockType_ = data.cellularSimLockType;
-    wiredList_ = data.wiredList;
-    wirelessList_ = data.wirelessList;
-    vpnList_ = data.vpnList;
-    rememberedList_ = data.rememberedList;
+    /**
+     * Updates the state of network devices and services.
+     * @param {!Array<{State: string, Type: string}>} deviceStates The result
+     *     from networkingPrivate.getDeviceStates.
+     * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>}
+     *     networkStates The result from networkingPrivate.getNetworks.
+     */
+    updateNetworkStates: function(deviceStates, networkStates) {
+      // Update device states.
+      cellularDeviceState_ = undefined;
+      wifiDeviceState_ = undefined;
+      wimaxDeviceState_ = undefined;
+      for (var i = 0; i < deviceStates.length; ++i) {
+        var device = deviceStates[i];
+        var type = device.Type;
+        var state = device.State;
+        if (type == 'Cellular')
+          cellularDeviceState_ = cellularDeviceState_ || state;
+        else if (type == 'WiFi')
+          wifiDeviceState_ = wifiDeviceState_ || state;
+        else if (type == 'WiMAX')
+          wimaxDeviceState_ = wimaxDeviceState_ || state;
+      }
 
-    // Request device states.
-    chrome.networkingPrivate.getDeviceStates(
-        NetworkList.onGetDeviceStates.bind(this));
-  };
+      // Update active network states.
+      cellularNetwork_ = null;
+      ethernetNetwork_ = null;
+      for (var i = 0; i < networkStates.length; i++) {
+        // Note: This cast is valid since
+        // networkingPrivate.NetworkStateProperties is a subset of
+        // NetworkProperties and all missing properties are optional.
+        var entry = /** @type {NetworkProperties} */ (networkStates[i]);
+        switch (entry.Type) {
+          case 'Cellular':
+            cellularNetwork_ = cellularNetwork_ || entry;
+            break;
+          case 'Ethernet':
+            ethernetNetwork_ = ethernetNetwork_ || entry;
+            break;
+        }
+        if (cellularNetwork_ && ethernetNetwork_)
+          break;
+      }
 
-  /**
-   * Callback from getDeviceStates. Updates network controls.
-   * @param {Array<{State: string, Type: string}>} deviceStates The result
-   *     from getDeviceStates.
-   */
-  NetworkList.onGetDeviceStates = function(deviceStates) {
-    var networkList = $('network-list');
-    networkList.startBatchUpdates();
+      if (cellularNetwork_ && cellularNetwork_.GUID) {
+        // Get the complete set of cellular properties which includes SIM and
+        // Scan properties.
+        var networkList = this;
+        chrome.networkingPrivate.getProperties(
+            cellularNetwork_.GUID, function(cellular) {
+              cellularNetwork_ = /** @type {NetworkProperties} */ (cellular);
+              networkList.updateControls(networkStates);
+            });
+      } else {
+        this.updateControls(networkStates);
+      }
+    },
 
-    cellularState_ = undefined;
-    wifiState_ = undefined;
-    wimaxState_ = undefined;
-    for (var i = 0; i < deviceStates.length; ++i) {
-      var device = deviceStates[i];
-      var type = device.Type;
-      var state = device.State;
-      if (type == 'Cellular')
-        cellularState_ = cellularState_ || state;
-      else if (type == 'WiFi')
-        wifiState_ = wifiState_ || state;
-      else if (type == 'WiMAX')
-        wimaxState_ = wimaxState_ || state;
-    }
+    /**
+     * Updates network controls.
+     * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>}
+     *     networkStates The result from networkingPrivate.getNetworks.
+     */
+    updateControls: function(networkStates) {
+      this.startBatchUpdates();
 
-    // Only show Ethernet control if connected.
-    var ethernetConnection = getConnection_(wiredList_);
-    if (ethernetConnection) {
-      var type = String('Ethernet');
-      var ethernetOptions = showDetails.bind(null, ethernetConnection.GUID);
-      networkList.update(
+      // Only show Ethernet control if connected.
+      if (ethernetNetwork_ && ethernetNetwork_.ConnectionState == 'Connected') {
+        var ethernetOptions = showDetails.bind(null, ethernetNetwork_.GUID);
+        this.update(
           { key: 'Ethernet',
             subtitle: loadTimeData.getString('OncConnectionStateConnected'),
-            iconData: ethernetConnection,
+            iconData: ethernetNetwork_,
             command: ethernetOptions,
-            policyManaged: ethernetConnection.policyManaged }
-          );
-    } else {
-      networkList.deleteItem('Ethernet');
-    }
+            Source: ethernetNetwork_.Source }
+        );
+      } else {
+        this.deleteItem('Ethernet');
+      }
 
-    if (wifiState_ == 'Enabled')
-      loadData_('WiFi', wirelessList_, rememberedList_);
-    else
-      addEnableNetworkButton_('WiFi');
-
-    // Only show cellular control if available.
-    if (cellularState_) {
-      if (cellularState_ == 'Enabled')
-        loadData_('Cellular', wirelessList_, rememberedList_);
+      if (wifiDeviceState_ == 'Enabled')
+        loadData_('WiFi', networkStates);
       else
-        addEnableNetworkButton_('Cellular');
-    } else {
-      networkList.deleteItem('Cellular');
-    }
+        addEnableNetworkButton_('WiFi');
 
-    // Only show wimax control if available. Uses cellular icons.
-    if (wimaxState_) {
-      if (wimaxState_ == 'Enabled')
-        loadData_('WiMAX', wirelessList_, rememberedList_);
-      else
-        addEnableNetworkButton_('WiMAX');
-    } else {
-      networkList.deleteItem('WiMAX');
-    }
+      // Only show cellular control if available.
+      if (cellularDeviceState_) {
+        if (cellularDeviceState_ == 'Enabled' &&
+            !isCellularSimLocked(cellularNetwork_) &&
+            !isCellularSimAbsent(cellularNetwork_)) {
+          loadData_('Cellular', networkStates);
+        } else {
+          addEnableNetworkButton_('Cellular');
+        }
+      } else {
+        this.deleteItem('Cellular');
+      }
 
-    // Only show VPN control if there is at least one VPN configured.
-    if (vpnList_.length > 0)
-      loadData_('VPN', vpnList_, rememberedList_);
-    else
-      networkList.deleteItem('VPN');
-    networkList.endBatchUpdates();
+      // Only show wimax control if available. Uses cellular icons.
+      if (wimaxDeviceState_) {
+        if (wimaxDeviceState_ == 'Enabled')
+          loadData_('WiMAX', networkStates);
+        else
+          addEnableNetworkButton_('WiMAX');
+      } else {
+        this.deleteItem('WiMAX');
+      }
+
+      // Only show VPN control if there is at least one VPN configured.
+      if (loadData_('VPN', networkStates) == 0)
+        this.deleteItem('VPN');
+
+      this.endBatchUpdates();
+    }
   };
 
   /**
@@ -1188,10 +1241,10 @@
       if (type == 'WiFi')
         sendChromeMetricsAction('Options_NetworkWifiToggle');
       if (type == 'Cellular') {
-        if (cellularSimLockType_) {
+        if (isCellularSimLocked(cellularNetwork_)) {
           chrome.send('simOperation', ['unlock']);
           return;
-        } else if (cellularState_ == 'Enabled' && cellularSimAbsent_) {
+        } else if (isCellularSimAbsent(cellularNetwork_)) {
           chrome.send('simOperation', ['configure']);
           return;
         }
@@ -1264,26 +1317,34 @@
    * Updates the list of available networks and their status, filtered by
    * network type.
    * @param {string} type The type of network.
-   * @param {Array} available The list of available networks and their status.
-   * @param {Array} remembered The list of remmebered networks.
+   * @param {Array<!chrome.networkingPrivate.NetworkStateProperties>} networks
+   *     The list of network objects.
+   * @return {number} The number of visible networks matching |type|.
    */
-  function loadData_(type, available, remembered) {
-    var data = {key: type};
+  function loadData_(type, networks) {
+    var res = 0;
     var availableNetworks = [];
-    for (var i = 0; i < available.length; i++) {
-      if (available[i].Type == type)
-        availableNetworks.push(available[i]);
-    }
-    data.networkList = availableNetworks;
-    if (remembered) {
-      var rememberedNetworks = [];
-      for (var i = 0; i < remembered.length; i++) {
-        if (remembered[i].Type == type)
-          rememberedNetworks.push(remembered[i]);
+    var rememberedNetworks = [];
+    for (var i = 0; i < networks.length; i++) {
+      var network = networks[i];
+      if (network.Type != type)
+        continue;
+      if (networkIsVisible(network)) {
+        availableNetworks.push(network);
+        ++res;
       }
-      data.rememberedNetworks = rememberedNetworks;
+      if ((type == 'WiFi' || type == 'VPN') && network.Source &&
+          network.Source != 'None') {
+        rememberedNetworks.push(network);
+      }
     }
+    var data = {
+      key: type,
+      networkList: availableNetworks,
+      rememberedNetworks: rememberedNetworks
+    };
     $('network-list').update(data);
+    return res;
   }
 
   /**
@@ -1301,24 +1362,6 @@
   }
 
   /**
-   * Fetches the active connection.
-   * @param {Array<Object>} networkList List of networks.
-   * @return {Object}
-   * @private
-   */
-  function getConnection_(networkList) {
-    if (!networkList)
-      return null;
-    for (var i = 0; i < networkList.length; i++) {
-      var entry = networkList[i];
-      if (entry.ConnectionState == 'Connected' ||
-          entry.ConnectionState == 'Connecting')
-        return entry;
-    }
-    return null;
-  }
-
-  /**
    * Creates a callback function that adds a new connection of the given type.
    * This method may be used for all network types except VPN.
    * @param {string} type An ONC network type
diff --git a/chrome/browser/resources/options/chromeos/preferred_networks.js b/chrome/browser/resources/options/chromeos/preferred_networks.js
index fb20b057..4f5a152b 100644
--- a/chrome/browser/resources/options/chromeos/preferred_networks.js
+++ b/chrome/browser/resources/options/chromeos/preferred_networks.js
@@ -5,7 +5,7 @@
 cr.exportPath('options');
 
 /**
- * @typedef {{Name: string, Type: string, GUID: string}}
+ * @typedef {{GUID: string, Name: string, Source: string, Type: string}}
  */
 options.PreferredNetwork;
 
@@ -83,8 +83,10 @@
       DeletableItem.prototype.decorate.call(this);
       var label = this.ownerDocument.createElement('div');
       label.textContent = this.data.Name;
-      if (this.data.policyManaged)
+      if (this.data.Source == 'DevicePolicy' ||
+          this.data.Source == 'UserPolicy') {
         this.deletable = false;
+      }
       this.contentElement.appendChild(label);
     }
   };
diff --git a/chrome/browser/resources/pdf/browser_api.js b/chrome/browser/resources/pdf/browser_api.js
new file mode 100644
index 0000000..52ce4c6
--- /dev/null
+++ b/chrome/browser/resources/pdf/browser_api.js
@@ -0,0 +1,159 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+let defaultZoomPromise = (function() {
+  if (!chrome.tabs)
+    return Promise.resolve(1);
+
+  return new Promise(function(resolve, reject) {
+    chrome.tabs.getZoomSettings(function(zoomSettings) {
+      resolve(zoomSettings.defaultZoomFactor);
+    }.bind(this));
+  }.bind(this));
+})();
+
+/**
+ * A class providing an interface to the browser.
+ */
+class BrowserApi {
+  /**
+   * @constructor
+   * @param {!Object} streamInfo The stream object which points to the data
+   *     contained in the PDF.
+   * @param {number} defaultZoom The default browser zoom.
+   * @param {boolean} manageZoom Whether to manage zoom.
+   */
+  constructor(streamInfo, defaultZoom, manageZoom) {
+    this.streamInfo_ = streamInfo;
+    this.defaultZoom_ = defaultZoom;
+    this.manageZoom_ = manageZoom;
+  }
+
+  /**
+   * Returns a promise to a BrowserApi.
+   * @param {!Promise.<Object>} streamInfoPromise A promise that will resolve
+   *     the stream object pointing to the data contained in the PDF.
+   * @param {boolean} manageZoom Whether to manage zoom.
+   */
+  static create(streamInfoPromise, manageZoom) {
+    return Promise.all([streamInfoPromise, defaultZoomPromise]).then(
+        function(results) {
+      return new BrowserApi(results[0], results[1], manageZoom);
+    });
+  }
+
+  /**
+   * Returns the stream info pointing to the data contained in the PDF.
+   * @return {Object} The stream info object.
+   */
+  getStreamInfo() {
+    return this.streamInfo_;
+  }
+
+  /**
+   * Aborts the stream.
+   */
+  abortStream() {
+    if (chrome.mimeHandlerPrivate)
+      chrome.mimeHandlerPrivate.abortStream();
+  }
+
+  /**
+   * Sets the browser zoom.
+   * @param {number} zoom The zoom factor to send to the browser.
+   * @return {Promise} A promise that will be resolved when the browser zoom
+   *     has been updated.
+   */
+  setZoom(zoom) {
+    if (!this.manageZoom_)
+      return Promise.resolve();
+    return new Promise(function(resolve, reject) {
+      chrome.tabs.setZoom(this.streamInfo_.tabId, zoom, resolve);
+    }.bind(this));
+  }
+
+  /**
+   * Returns the default browser zoom factor.
+   * @return {number} The default browser zoom factor.
+   */
+  getDefaultZoom() {
+    return this.defaultZoom_;
+  }
+
+  /**
+   * Adds an event listener to be notified when the browser zoom changes.
+   * @param {function} listener The listener to be called with the new zoom
+   *     factor.
+   */
+  addZoomEventListener(listener) {
+    if (!this.manageZoom_)
+      return;
+
+    chrome.tabs.onZoomChange.addListener(function(zoomChangeInfo) {
+      if (zoomChangeInfo.tabId != this.streamInfo_.tabId)
+        return;
+      listener(zoomChangeInfo.newZoomFactor);
+    }.bind(this));
+  }
+};
+
+/**
+ * Creates a BrowserApi for an extension running as a mime handler.
+ * @return {Promise.<BrowserApi>} A promise to a BrowserApi instance constructed
+ *     using the mimeHandlerPrivate API.
+ */
+function createBrowserApiForMimeHandlerView() {
+  return new Promise(function(resolve, reject) {
+    chrome.mimeHandlerPrivate.getStreamInfo(resolve);
+  }).then(function(streamInfo) {
+    if (streamInfo.embedded || streamInfo.tabId == -1)
+      return BrowserApi.create(streamInfo, false);
+
+    return BrowserApi.create(new Promise(function(resolve, reject) {
+      chrome.tabs.setZoomSettings(
+          streamInfo.tabId, {mode: 'manual', scope: 'per-tab'}, resolve);
+      }).then(function() {
+        return streamInfo;
+      }), true);
+  });
+}
+
+/**
+ * Creates a BrowserApi instance for an extension not running as a mime handler.
+ * @return {Promise.<BrowserApi>} A promise to a BrowserApi instance constructed
+ *     from the URL.
+ */
+function createBrowserApiForStandaloneExtension() {
+  let url = window.location.search.substring(1);
+  let streamInfo = {
+    streamUrl: url,
+    originalUrl: url,
+    responseHeaders: {},
+    embedded: window.parent != window,
+    tabId: -1,
+  };
+  if (!chrome.tabs)
+    return BrowserApi.create(streamInfo, false);
+
+  return BrowserApi.create(new Promise(function(resolve, reject) {
+    chrome.tabs.getCurrent(function(tab) {
+      streamInfo.tabId = tab.id;
+      resolve(streamInfo);
+    });
+  }), false);
+}
+
+/**
+ * Returns a promise that will resolve to a BrowserApi instance.
+ * @return {Promise.<BrowserApi>} A promise to a BrowserApi instance for the
+ *     current environment.
+ */
+function createBrowserApi() {
+  if (window.location.search)
+    return createBrowserApiForStandaloneExtension();
+
+  return createBrowserApiForMimeHandlerView();
+}
diff --git a/chrome/browser/resources/pdf/index-material.html b/chrome/browser/resources/pdf/index-material.html
index ec0e9d0..b71ef4c 100644
--- a/chrome/browser/resources/pdf/index-material.html
+++ b/chrome/browser/resources/pdf/index-material.html
@@ -38,6 +38,7 @@
 <script src="zoom_manager.js"></script>
 <script src="pdf_scripting_api.js"></script>
 <script src="chrome://resources/js/util.js"></script>
+<script src="browser_api.js"></script>
 <script src="pdf.js"></script>
 <script src="main.js"></script>
 </html>
diff --git a/chrome/browser/resources/pdf/index.html b/chrome/browser/resources/pdf/index.html
index 7062cec..2ecf2c8 100644
--- a/chrome/browser/resources/pdf/index.html
+++ b/chrome/browser/resources/pdf/index.html
@@ -55,6 +55,7 @@
 <script src="zoom_manager.js"></script>
 <script src="pdf_scripting_api.js"></script>
 <script src="chrome://resources/js/util.js"></script>
+<script src="browser_api.js"></script>
 <script src="pdf.js"></script>
 <script src="main.js"></script>
 </html>
diff --git a/chrome/browser/resources/pdf/main.js b/chrome/browser/resources/pdf/main.js
index 07fa2e0..e6938bc 100644
--- a/chrome/browser/resources/pdf/main.js
+++ b/chrome/browser/resources/pdf/main.js
@@ -29,56 +29,26 @@
 
   /**
    * Initialize the global PDFViewer and pass any outstanding messages to it.
-   * @param {Object} streamDetails The stream object which points to the data
-   *     contained in the PDF.
+   * @param {Object} browserApi An object providing an API to the browser.
    */
-  function initViewer(streamDetails) {
+  function initViewer(browserApi) {
     // PDFViewer will handle any messages after it is created.
     window.removeEventListener('message', handleScriptingMessage, false);
-    viewer = new PDFViewer(streamDetails);
+    viewer = new PDFViewer(browserApi);
     while (pendingMessages.length > 0)
       viewer.handleScriptingMessage(pendingMessages.shift());
   }
 
-  function generateStreamDetailsAndInitViewer() {
-    var url = window.location.search.substring(1);
-    var streamDetails = {
-      streamUrl: url,
-      originalUrl: url,
-      responseHeaders: '',
-      embedded: window.parent != window,
-      tabId: -1
-    };
-    if (!chrome.tabs) {
-      initViewer(streamDetails);
-      return;
-    }
-    chrome.tabs.getCurrent(function(tab) {
-      streamDetails.tabId = tab.id;
-      initViewer(streamDetails);
-    });
-  }
-
   /**
-   * Entrypoint for starting the PDF viewer. This function obtains the details
-   * of the PDF 'stream' (the data that points to the PDF) and constructs a
-   * PDFViewer object with it.
+   * Entrypoint for starting the PDF viewer. This function obtains the browser
+   * API for the PDF and constructs a PDFViewer object with it.
    */
   function main() {
     // Set up an event listener to catch scripting messages which are sent prior
     // to the PDFViewer being created.
     window.addEventListener('message', handleScriptingMessage, false);
 
-    if (window.location.search) {
-      generateStreamDetailsAndInitViewer();
-      return;
-    }
-
-    // If the viewer is started from the browser plugin, getStreamInfo will
-    // return the details of the stream.
-    chrome.mimeHandlerPrivate.getStreamInfo(function(streamDetails) {
-      initViewer(streamDetails);
-    });
+    createBrowserApi().then(initViewer);
   };
 
   main();
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js
index 47baecd..6e94d56 100644
--- a/chrome/browser/resources/pdf/pdf.js
+++ b/chrome/browser/resources/pdf/pdf.js
@@ -61,18 +61,17 @@
  * Creates a new PDFViewer. There should only be one of these objects per
  * document.
  * @constructor
- * @param {Object} streamDetails The stream object which points to the data
- *     contained in the PDF.
+ * @param {!BrowserApi} browserApi An object providing an API to the browser.
  */
-function PDFViewer(streamDetails) {
-  this.streamDetails_ = streamDetails;
+function PDFViewer(browserApi) {
+  this.browserApi_ = browserApi;
   this.loaded_ = false;
   this.parentWindow_ = null;
 
   this.delayedScriptingMessages_ = [];
 
-  this.isPrintPreview_ =
-      this.streamDetails_.originalUrl.indexOf('chrome://print') == 0;
+  this.isPrintPreview_ = this.browserApi_.getStreamInfo().originalUrl.indexOf(
+                             'chrome://print') == 0;
   this.isMaterial_ = location.pathname.substring(1) === 'index-material.html';
 
   // The sizer element is placed behind the plugin element to cause scrollbars
@@ -93,7 +92,8 @@
                                 this.viewportChanged_.bind(this),
                                 this.beforeZoom_.bind(this),
                                 this.afterZoom_.bind(this),
-                                getScrollbarWidth());
+                                getScrollbarWidth(),
+                                this.browserApi_.getDefaultZoom());
 
   // Create the plugin object dynamically so we can set its src. The plugin
   // element is sized to fill the entire window and is set to be fixed
@@ -113,20 +113,23 @@
   window.addEventListener('message', this.handleScriptingMessage.bind(this),
                           false);
 
-  document.title = getFilenameFromURL(this.streamDetails_.originalUrl);
-  this.plugin_.setAttribute('src', this.streamDetails_.originalUrl);
-  this.plugin_.setAttribute('stream-url', this.streamDetails_.streamUrl);
+  document.title =
+      getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl);
+  this.plugin_.setAttribute('src',
+                            this.browserApi_.getStreamInfo().originalUrl);
+  this.plugin_.setAttribute('stream-url',
+                            this.browserApi_.getStreamInfo().streamUrl);
   var headers = '';
-  for (var header in this.streamDetails_.responseHeaders) {
+  for (var header in this.browserApi_.getStreamInfo().responseHeaders) {
     headers += header + ': ' +
-        this.streamDetails_.responseHeaders[header] + '\n';
+        this.browserApi_.getStreamInfo().responseHeaders[header] + '\n';
   }
   this.plugin_.setAttribute('headers', headers);
 
   if (this.isMaterial_)
     this.plugin_.setAttribute('is-material', '');
 
-  if (!this.streamDetails_.embedded)
+  if (!this.browserApi_.getStreamInfo().embedded)
     this.plugin_.setAttribute('full-frame', '');
   document.body.appendChild(this.plugin_);
 
@@ -176,19 +179,12 @@
                                     [this.bookmarksPane_]);
   }
 
-  // Set up the zoom API.
-  if (this.shouldManageZoom_()) {
-    chrome.tabs.setZoomSettings(this.streamDetails_.tabId,
-                                {mode: 'manual', scope: 'per-tab'}, function() {
-      this.zoomManager_ =
-          new ZoomManager(this.viewport_, this.setZoom_.bind(this));
-      chrome.tabs.onZoomChange.addListener(function(zoomChangeInfo) {
-        if (zoomChangeInfo.tabId != this.streamDetails_.tabId)
-          return;
-        this.zoomManager_.onBrowserZoomChange(zoomChangeInfo.newZoomFactor);
-      }.bind(this));
-    }.bind(this));
-  }
+  // Set up the ZoomManager.
+  this.zoomManager_ = new ZoomManager(
+      this.viewport_, this.browserApi_.setZoom.bind(this.browserApi_),
+      this.browserApi_.getDefaultZoom());
+  this.browserApi_.addZoomEventListener(
+      this.zoomManager_.onBrowserZoomChange.bind(this.zoomManager_));
 
   // Setup the keyboard event listener.
   document.onkeydown = this.handleKeyEvent_.bind(this);
@@ -196,7 +192,7 @@
   // Parse open pdf parameters.
   this.paramsParser_ =
       new OpenPDFParamsParser(this.getNamedDestination_.bind(this));
-  this.navigator_ = new Navigator(this.streamDetails_.originalUrl,
+  this.navigator_ = new Navigator(this.browserApi_.getStreamInfo().originalUrl,
                                   this.viewport_, this.paramsParser_,
                                   onNavigateInCurrentTab, onNavigateInNewTab);
   this.viewportScroller_ =
@@ -425,7 +421,8 @@
       if (this.lastViewportPosition_)
         this.viewport_.position = this.lastViewportPosition_;
       this.paramsParser_.getViewportFromUrlParams(
-          this.streamDetails_.originalUrl, this.handleURLParams_.bind(this));
+          this.browserApi_.getStreamInfo().originalUrl,
+          this.handleURLParams_.bind(this));
       this.loaded_ = true;
       this.sendScriptingMessage_({
         type: 'documentLoaded'
@@ -571,14 +568,7 @@
       xOffset: position.x,
       yOffset: position.y
     });
-    if (this.zoomManager_)
-      this.zoomManager_.onPdfZoomChange();
-  },
-
-  setZoom_: function(zoom) {
-    return new Promise(function(resolve, reject) {
-      chrome.tabs.setZoom(this.streamDetails_.tabId, zoom, resolve);
-    }.bind(this));
+    this.zoomManager_.onPdfZoomChange();
   },
 
   /**
@@ -749,16 +739,6 @@
       this.parentWindow_.postMessage(message, '*');
   },
 
-  /**
-   * @private
-   * Return whether this PDFViewer should manage zoom for its containing page.
-   * @return {boolean} Whether this PDFViewer should manage zoom for its
-   *     containing page.
-   */
-  shouldManageZoom_: function() {
-    return !!(chrome.tabs && !this.streamDetails_.embedded &&
-              this.streamDetails_.tabId != -1);
-  },
 
   /**
    * @type {Viewport} the viewport of the PDF viewer.
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 20c8460..47c2507 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -24,13 +24,15 @@
  * @param {Function} beforeZoomCallback is run before a change in zoom
  * @param {Function} afterZoomCallback is run after a change in zoom
  * @param {number} scrollbarWidth the width of scrollbars on the page
+ * @param {number} defaultZoom The default zoom level.
  */
 function Viewport(window,
                   sizer,
                   viewportChangedCallback,
                   beforeZoomCallback,
                   afterZoomCallback,
-                  scrollbarWidth) {
+                  scrollbarWidth,
+                  defaultZoom) {
   this.window_ = window;
   this.sizer_ = sizer;
   this.viewportChangedCallback_ = viewportChangedCallback;
@@ -42,6 +44,7 @@
   this.pageDimensions_ = [];
   this.scrollbarWidth_ = scrollbarWidth;
   this.fittingType_ = Viewport.FittingType.NONE;
+  this.defaultZoom_ = defaultZoom;
 
   window.addEventListener('scroll', this.updateViewport_.bind(this));
   window.addEventListener('resize', this.resize_.bind(this));
@@ -498,10 +501,9 @@
       this.documentDimensions_ = documentDimensions;
       this.pageDimensions_ = this.documentDimensions_.pageDimensions;
       if (initialDimensions) {
-        this.setZoomInternal_(this.computeFittingZoom_(this.documentDimensions_,
-                                                       true));
-        if (this.zoom_ > 1)
-          this.setZoomInternal_(1);
+        this.setZoomInternal_(
+            Math.min(this.defaultZoom_,
+                     this.computeFittingZoom_(this.documentDimensions_, true)));
         this.window_.scrollTo(0, 0);
       }
       this.contentSizeChanged_();
diff --git a/chrome/browser/resources/pdf/zoom_manager.js b/chrome/browser/resources/pdf/zoom_manager.js
index 664c88f..14c57a06 100644
--- a/chrome/browser/resources/pdf/zoom_manager.js
+++ b/chrome/browser/resources/pdf/zoom_manager.js
@@ -13,13 +13,13 @@
    * @param {!Viewport} viewport A Viewport for which to manage zoom.
    * @param {Function} setBrowserZoomFunction A function that sets the browser
    *     zoom to the provided value.
+   * @param {number} defaultZoom The default browser zoom level.
    */
-  constructor(viewport, setBrowserZoomFunction) {
+  constructor(viewport, setBrowserZoomFunction, defaultZoom) {
     this.viewport_ = viewport;
     this.setBrowserZoomFunction_ = setBrowserZoomFunction;
-    this.browserZoom_ = 1;
+    this.browserZoom_ = defaultZoom;
     this.changingBrowserZoom_ = null;
-    this.onPdfZoomChange();
   }
 
   /**
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2.css b/chrome/browser/resources/security_warnings/interstitial_v2.css
index 81087bc..7987f80 100644
--- a/chrome/browser/resources/security_warnings/interstitial_v2.css
+++ b/chrome/browser/resources/security_warnings/interstitial_v2.css
@@ -338,10 +338,10 @@
        (min-height: 401px) and (orientation:portrait),
        (min-width: 421px) and (max-width: 736px) and (min-height: 240px) and
        (max-height: 420px) and (orientation:landscape) {
-
   body .nav-wrapper {
     background: #f7f7f7;
     bottom: 0;
+    box-shadow: 0 -22px 40px rgb(247, 247, 247);
     left: 0;
     margin: 0;
     max-width: 736px;
@@ -351,11 +351,17 @@
 
   body.safe-browsing .nav-wrapper {
     background: rgb(206, 52, 38);
+    box-shadow: 0 -22px 40px rgb(206, 52, 38);
   }
 
   .interstitial-wrapper {
     max-width: 736px;
   }
+
+  #details,
+  #main-content {
+    padding-bottom: 30px;
+  }
 }
 
 @media (max-width: 420px) and (orientation: portrait),
@@ -637,6 +643,7 @@
   .extended-reporting-has-checkbox #main-content {
     flex: 1 1 auto;
     order: 0;
+    padding-bottom: 0;
   }
 
   .extended-reporting-has-checkbox #extended-reporting-opt-in {
@@ -653,3 +660,10 @@
     width: 100%;
   }
 }
+
+@media (max-width: 239px) and (orientation: portrait) {
+  .nav-wrapper {
+    padding-left: 0;
+    padding-right: 0;
+  }
+}
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc
index 1293bd4..a616608 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc
@@ -17,4 +17,6 @@
 
 const char kTestExportName[] = "DummyExport";
 
+const char kTestDllMainExportName[] = "DllMain";
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.h b/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.h
index 262e015..d05183d 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.h
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.h
@@ -18,6 +18,9 @@
 // A function exported by the test dlls in |kTestDllNames|.
 extern const char kTestExportName[];
 
+// The DllMain function exported by the test dlls in |kTestDllNames|.
+extern const char kTestDllMainExportName[];
+
 }  // namespace safe_browsing
 
 #endif  // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_MODULE_INTEGRITY_UNITTEST_UTIL_WIN_H_
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc
index 377efbf..6ea499b2 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc
@@ -437,6 +437,10 @@
   if (!mem_peimage.VerifyMagic() || !state.disk_peimage.VerifyMagic())
     return result;
 
+  // Get the list of exports and sort them by address for efficient lookups.
+  mem_peimage.EnumExports(EnumExportsCallback, &state.exports);
+  std::sort(state.exports.begin(), state.exports.end());
+
   // Get the addresses of the code sections then calculate |code_section_delta|
   // and |image_base_delta|.
   if (!GetCodeAddrsAndSize(mem_peimage,
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
index f9c5369..5d3d84a 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
@@ -4,6 +4,11 @@
 
 #include "chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.h"
 
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <vector>
+
 #include "base/files/file_path.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/native_library.h"
@@ -15,8 +20,51 @@
 
 namespace safe_browsing {
 
+// A scoper that makes a modification at a given address when constructed, and
+// reverts it upon destruction.
+template <size_t ModificationLength>
+class ScopedModuleModifier {
+ public:
+  explicit ScopedModuleModifier(uint8_t* address) : address_(address) {
+    uint8_t modification[ModificationLength];
+    std::transform(address, address + ModificationLength, &modification[0],
+                   std::bind2nd(std::plus<uint8_t>(), 1U));
+    SIZE_T bytes_written = 0;
+    EXPECT_NE(0, WriteProcessMemory(GetCurrentProcess(),
+                                    address,
+                                    &modification[0],
+                                    ModificationLength,
+                                    &bytes_written));
+    EXPECT_EQ(ModificationLength, bytes_written);
+  }
+
+  ~ScopedModuleModifier() {
+    uint8_t modification[ModificationLength];
+    std::transform(address_, address_ + ModificationLength, &modification[0],
+                   std::bind2nd(std::minus<uint8_t>(), 1U));
+    SIZE_T bytes_written = 0;
+    EXPECT_NE(0, WriteProcessMemory(GetCurrentProcess(),
+                                    address_,
+                                    &modification[0],
+                                    ModificationLength,
+                                    &bytes_written));
+    EXPECT_EQ(ModificationLength, bytes_written);
+  }
+
+ private:
+  uint8_t* address_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedModuleModifier);
+};
+
 class SafeBrowsingModuleVerifierWinTest : public testing::Test {
  protected:
+  using ModuleState = ClientIncidentReport_EnvironmentData_Process_ModuleState;
+
+  // A mapping of an export name to the sequence of modifications for it.
+  using ExportNameToModifications =
+      std::map<std::string, std::vector<const ModuleState::Modification*>>;
+
   void SetUpTestDllAndPEImages() {
     LoadModule();
     HMODULE mem_handle;
@@ -62,23 +110,30 @@
         reinterpret_cast<HMODULE>(const_cast<uint8*>(disk_dll_handle_.data()));
   }
 
-  // Edits the first byte of the single function exported by the test dll.
-  void EditExport() {
+  // Returns the address of the named function exported by the test dll.
+  uint8_t* GetAddressOfExport(const char* export_name) {
     HMODULE mem_handle;
     GetMemModuleHandle(&mem_handle);
     uint8_t* export_addr =
-        reinterpret_cast<uint8_t*>(GetProcAddress(mem_handle, kTestExportName));
-    EXPECT_NE(reinterpret_cast<uint8_t*>(NULL), export_addr);
+        reinterpret_cast<uint8_t*>(GetProcAddress(mem_handle, export_name));
+    EXPECT_NE(nullptr, export_addr);
+    return export_addr;
+  }
 
-    // Edit the first byte of the function.
-    uint8_t new_val = (*export_addr) + 1;
-    SIZE_T bytes_written = 0;
-    WriteProcessMemory(GetCurrentProcess(),
-                       export_addr,
-                       reinterpret_cast<void*>(&new_val),
-                       1,
-                       &bytes_written);
-    EXPECT_EQ(1, bytes_written);
+  // Replaces the contents of |modification_map| with pointers to those in
+  // |state|. |state| must outlive |modification_map|.
+  static void BuildModificationMap(
+      const ModuleState& state,
+      ExportNameToModifications* modification_map) {
+    modification_map->clear();
+    std::string export_name;
+    for (auto& modification : state.modification()) {
+      if (!modification.has_export_name())
+        export_name.clear();
+      else
+        export_name = modification.export_name();
+      (*modification_map)[export_name].push_back(&modification);
+    }
   }
 
   base::ScopedNativeLibrary mem_dll_handle_;
@@ -125,14 +180,7 @@
 
   // Edit the first byte of the code section of the module (this may be before
   // the address of any export).
-  uint8_t new_val = (*mem_code_addr) + 1;
-  SIZE_T bytes_written = 0;
-  WriteProcessMemory(GetCurrentProcess(),
-                     mem_code_addr,
-                     reinterpret_cast<void*>(&new_val),
-                     1,
-                     &bytes_written);
-  EXPECT_EQ(1, bytes_written);
+  ScopedModuleModifier<1> mod(mem_code_addr);
 
   // VerifyModule should detect the change.
   EXPECT_EQ(MODULE_STATE_MODIFIED,
@@ -150,7 +198,7 @@
 
   // Edit the exported function, VerifyModule should now return the function
   // name in modified_exports.
-  EditExport();
+  ScopedModuleModifier<1> mod(GetAddressOfExport(kTestExportName));
   EXPECT_EQ(MODULE_STATE_MODIFIED,
             VerifyModule(kTestDllNames[0], &modified_exports, &num_bytes));
   ASSERT_EQ(1, modified_exports.size());
@@ -158,7 +206,7 @@
 }
 
 TEST_F(SafeBrowsingModuleVerifierWinTest, NewVerifyModuleUnmodified) {
-  ClientIncidentReport_EnvironmentData_Process_ModuleState state;
+  ModuleState state;
   // Call VerifyModule before the module has been loaded, should fail.
   VerificationResult result = NewVerifyModule(kTestDllNames[0], &state);
 
@@ -175,7 +223,7 @@
 }
 
 TEST_F(SafeBrowsingModuleVerifierWinTest, NewVerifyModuleModified) {
-  ClientIncidentReport_EnvironmentData_Process_ModuleState state;
+  ModuleState state;
 
   SetUpTestDllAndPEImages();
   VerificationResult result = NewVerifyModule(kTestDllNames[0], &state);
@@ -191,25 +239,11 @@
                                   &disk_code_addr,
                                   &code_size));
 
-  uint8_t new_first_byte = (*mem_code_addr) + 1;
-  SIZE_T bytes_written = 0;
-  WriteProcessMemory(GetCurrentProcess(),
-                     mem_code_addr,
-                     reinterpret_cast<void*>(&new_first_byte),
-                     1,
-                     &bytes_written);
-  EXPECT_EQ(1, bytes_written);
+  ScopedModuleModifier<1> mod(mem_code_addr);
 
   size_t modification_offset = code_size - 1;
-  uint8_t* last_byte_addr = mem_code_addr + modification_offset;
-  uint8_t new_last_byte = (*last_byte_addr) + 1;
-  bytes_written = 0;
-  WriteProcessMemory(GetCurrentProcess(),
-                     last_byte_addr,
-                     reinterpret_cast<void*>(&new_last_byte),
-                     1,
-                     &bytes_written);
-  EXPECT_EQ(1, bytes_written);
+  ScopedModuleModifier<1> mod2(mem_code_addr + modification_offset);
+
   result = NewVerifyModule(kTestDllNames[0], &state);
   EXPECT_EQ(MODULE_STATE_MODIFIED, result.state);
 
@@ -220,17 +254,19 @@
       disk_code_addr - reinterpret_cast<uint8_t*>(disk_peimage_ptr_->module());
   EXPECT_EQ(expected_file_offset, state.modification(0).file_offset());
   EXPECT_EQ(1, state.modification(0).byte_count());
-  EXPECT_EQ(new_first_byte, (uint8_t)state.modification(0).modified_bytes()[0]);
+  EXPECT_EQ(mem_code_addr[0],
+            (uint8_t)state.modification(0).modified_bytes()[0]);
 
   expected_file_offset = (disk_code_addr + modification_offset) -
       reinterpret_cast<uint8_t*>(disk_peimage_ptr_->module());
   EXPECT_EQ(expected_file_offset, state.modification(1).file_offset());
   EXPECT_EQ(1, state.modification(1).byte_count());
-  EXPECT_EQ(new_last_byte, (uint8_t)state.modification(1).modified_bytes()[0]);
+  EXPECT_EQ(mem_code_addr[modification_offset],
+            (uint8_t)state.modification(1).modified_bytes()[0]);
 }
 
 TEST_F(SafeBrowsingModuleVerifierWinTest, NewVerifyModuleLongModification) {
-  ClientIncidentReport_EnvironmentData_Process_ModuleState state;
+  ModuleState state;
 
   SetUpTestDllAndPEImages();
   VerificationResult result = NewVerifyModule(kTestDllNames[0], &state);
@@ -247,43 +283,32 @@
                                   &disk_code_addr,
                                   &code_size));
 
-  const size_t modification_size = 256;
+  const size_t kModificationSize = 256;
   // Write the modification at the end so it's not overlapping relocations
-  const size_t modification_offset = code_size - modification_size;
-  uint8_t modification[modification_size] { 0 };
-  for (size_t i = 0; i < modification_size; ++i) {
-    modification[i] = disk_code_addr[modification_offset + i] + 1;
-  }
-
-  SIZE_T bytes_written = 0;
-  uint8_t* write_addr = mem_code_addr + modification_offset;
-  WriteProcessMemory(GetCurrentProcess(),
-                     write_addr,
-                     reinterpret_cast<void*>(&modification),
-                     modification_size,
-                     &bytes_written);
-  EXPECT_EQ(modification_size, bytes_written);
+  const size_t modification_offset = code_size - kModificationSize;
+  ScopedModuleModifier<kModificationSize> mod(
+      mem_code_addr + modification_offset);
 
   result = NewVerifyModule(kTestDllNames[0], &state);
   EXPECT_EQ(MODULE_STATE_MODIFIED, result.state);
 
-  EXPECT_EQ(modification_size, result.num_bytes_different);
+  EXPECT_EQ(kModificationSize, result.num_bytes_different);
 
   EXPECT_EQ(1, state.modification_size());
-  EXPECT_EQ(modification_size, state.modification(0).byte_count());
+  EXPECT_EQ(kModificationSize, state.modification(0).byte_count());
 
   size_t expected_file_offset = disk_code_addr + modification_offset -
       reinterpret_cast<uint8_t*>(disk_peimage_ptr_->module());
   EXPECT_EQ(expected_file_offset, state.modification(0).file_offset());
 
-  for (size_t i = 0; i < modification_size; ++i) {
-    EXPECT_EQ((uint8_t)state.modification(0).modified_bytes()[i],
-              (uint8_t)(disk_code_addr[modification_offset + i] + 1));
-  }
+  EXPECT_EQ(
+      std::string(mem_code_addr + modification_offset,
+                  mem_code_addr + modification_offset + kModificationSize),
+      state.modification(0).modified_bytes());
 }
 
 TEST_F(SafeBrowsingModuleVerifierWinTest, NewVerifyModuleRelocOverlap) {
-  ClientIncidentReport_EnvironmentData_Process_ModuleState state;
+  ModuleState state;
 
   SetUpTestDllAndPEImages();
   VerificationResult result = NewVerifyModule(kTestDllNames[0], &state);
@@ -300,35 +325,85 @@
                                   &disk_code_addr,
                                   &code_size));
 
-  const size_t modification_size = 256;
-  // Write the modification at a point where there are relocations
-  const size_t modification_offset = 0xF50;
-  uint8_t modification[modification_size] { 0 };
-  for (size_t i = 0; i < modification_size; ++i) {
-    modification[i] = disk_code_addr[modification_offset + i] + 1;
-  }
-
-  SIZE_T bytes_written = 0;
-  uint8_t* write_addr = mem_code_addr + modification_offset;
-  WriteProcessMemory(GetCurrentProcess(),
-                     write_addr,
-                     reinterpret_cast<void*>(&modification),
-                     modification_size,
-                     &bytes_written);
-  EXPECT_EQ(modification_size, bytes_written);
+  // Modify the first hunk of the code, which contains many relocs.
+  const size_t kModificationSize = 256;
+  ScopedModuleModifier<kModificationSize> mod(mem_code_addr);
 
   result = NewVerifyModule(kTestDllNames[0], &state);
   EXPECT_EQ(MODULE_STATE_MODIFIED, result.state);
 
-  EXPECT_EQ(modification_size, result.num_bytes_different);
+  EXPECT_EQ(kModificationSize, result.num_bytes_different);
 
-  // There should be more than one modification because there were relocations
-  // in the modified range.
-  EXPECT_EQ((size_t)1, state.modification_size());
-
-  EXPECT_EQ(modification_size, state.modification(0).byte_count());
+  // Modifications across the relocs should have been coalesced into one.
+  ASSERT_EQ(1U, state.modification_size());
+  ASSERT_EQ(kModificationSize, state.modification(0).byte_count());
+  ASSERT_EQ(kModificationSize, state.modification(0).modified_bytes().size());
+  EXPECT_EQ(std::string(mem_code_addr, mem_code_addr + kModificationSize),
+            state.modification(0).modified_bytes());
 }
 
+TEST_F(SafeBrowsingModuleVerifierWinTest, NewVerifyModuleExportModified) {
+  ModuleState state;
+
+  // Confirm the module is identical in memory as on disk before we begin.
+  SetUpTestDllAndPEImages();
+  VerificationResult result = NewVerifyModule(kTestDllNames[0], &state);
+  ASSERT_EQ(MODULE_STATE_UNMODIFIED, result.state);
+  state.Clear();
+
+  // Edit one exported function. VerifyModule should now return the function
+  // name in the modification.
+  ScopedModuleModifier<1> mod(GetAddressOfExport(kTestExportName));
+  result = NewVerifyModule(kTestDllNames[0], &state);
+  EXPECT_EQ(MODULE_STATE_MODIFIED, result.state);
+  ASSERT_EQ(1, state.modification_size());
+
+  // Extract the offset of this modification.
+  ExportNameToModifications modification_map;
+  BuildModificationMap(state, &modification_map);
+  ASSERT_EQ(1U, modification_map[kTestExportName].size());
+  uint32_t export_offset = modification_map[kTestExportName][0]->file_offset();
+
+  // Edit another exported function. VerifyModule should now report both.
+  state.Clear();
+  ScopedModuleModifier<1> mod2(GetAddressOfExport(kTestDllMainExportName));
+  result = NewVerifyModule(kTestDllNames[0], &state);
+  EXPECT_EQ(MODULE_STATE_MODIFIED, result.state);
+  ASSERT_EQ(2, state.modification_size());
+
+  // The first modification should be present and unmodified.
+  BuildModificationMap(state, &modification_map);
+  ASSERT_EQ(1U, modification_map[kTestExportName].size());
+  ASSERT_EQ(export_offset, modification_map[kTestExportName][0]->file_offset());
+
+  // The second modification should be present and different than the first.
+  ASSERT_EQ(1U, modification_map[kTestDllMainExportName].size());
+  ASSERT_NE(export_offset,
+            modification_map[kTestDllMainExportName][0]->file_offset());
+
+  // Now make another edit at the very end of the code section. This should be
+  // attributed to the last export.
+  uint8_t* mem_code_addr = nullptr;
+  uint8_t* disk_code_addr = nullptr;
+  uint32_t code_size = 0;
+  ASSERT_TRUE(GetCodeAddrsAndSize(*mem_peimage_ptr_,
+                                  *disk_peimage_ptr_,
+                                  &mem_code_addr,
+                                  &disk_code_addr,
+                                  &code_size));
+  ScopedModuleModifier<1> mod3(mem_code_addr + code_size - 1);
+
+  state.Clear();
+  result = NewVerifyModule(kTestDllNames[0], &state);
+  EXPECT_EQ(MODULE_STATE_MODIFIED, result.state);
+  ASSERT_EQ(3, state.modification_size());
+
+  // One of the two exports now has two modifications.
+  BuildModificationMap(state, &modification_map);
+  ASSERT_EQ(2U, modification_map.size());
+  ASSERT_EQ(3U, (modification_map.begin()->second.size() +
+                 (++modification_map.begin())->second.size()));
+}
 #endif  // ADDRESS_SANITIZER
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll.cc b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll.cc
index d8bdc53a..b1c0ae5 100644
--- a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll.cc
@@ -2,14 +2,28 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Some pointless code that will become a DLL with some exports and relocs.
+
 #include <windows.h>
 
-extern "C" {
-// Have a dummy export so that the module gets an export table entry.
-void DummyExport() {
-}
+namespace {
+
+void* g_somestate = nullptr;
+int g_somevalue = 0;
+
+}  // namespace
+
+extern "C"
+void DummyExport(int foo) {
+  g_somevalue = foo;
 }
 
+extern "C"
 BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
-  return true;
+  if (reason == DLL_PROCESS_ATTACH)
+    g_somestate = &DummyExport;
+  else if (reason == DLL_PROCESS_DETACH)
+    g_somestate = nullptr;
+
+  return TRUE;
 }
diff --git a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_1.def b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_1.def
index 105afdd..78a4a167 100644
--- a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_1.def
+++ b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_1.def
@@ -5,4 +5,5 @@
 LIBRARY "verifier_test_dll_1.dll"
 
 EXPORTS
+  DllMain
   DummyExport
diff --git a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_2.def b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_2.def
index c4208f7..b06372d5 100644
--- a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_2.def
+++ b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_test_dll_2.def
@@ -5,4 +5,5 @@
 LIBRARY "verifier_test_dll_2.dll"
 
 EXPORTS
+  DllMain
   DummyExport
diff --git a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_unittest.gyp b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_unittest.gyp
index 55ae891..bf93f8e 100644
--- a/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_unittest.gyp
+++ b/chrome/browser/safe_browsing/incident_reporting/verifier_test/verifier_unittest.gyp
@@ -1,4 +1,10 @@
 {
+  'variables': {
+    # Unconditionally disable incremental linking for these modules so that
+    # their exports do not go through an ILT jmp stub.
+    'incremental_chrome_dll': '0',  # 0 means no
+    'msvs_debug_link_incremental': '1',  # 1 means /INCREMENTAL:NO
+  },
   'targets': [
     {
       'target_name': 'verifier_test_dll_1',
diff --git a/chrome/browser/search/hotword_service.cc b/chrome/browser/search/hotword_service.cc
index db9d85f..9455991 100644
--- a/chrome/browser/search/hotword_service.cc
+++ b/chrome/browser/search/hotword_service.cc
@@ -271,6 +271,13 @@
       l10n_util::NormalizeLocale(GetCurrentLocale(profile));
   base::StringToLowerASCII(&normalized_locale);
 
+  // For M43, we are limiting always-on to en_us only.
+  // TODO(kcarattini): Remove this once
+  // https://code.google.com/p/chrome-os-partner/issues/detail?id=39227
+  // is fixed.
+  if (HotwordServiceFactory::IsAlwaysOnAvailable())
+    return normalized_locale == "en_us";
+
   for (size_t i = 0; i < arraysize(kSupportedLocales); i++) {
     if (normalized_locale == kSupportedLocales[i])
       return true;
diff --git a/chrome/browser/search/hotword_service_unittest.cc b/chrome/browser/search/hotword_service_unittest.cc
index 7244abf..a3aef47 100644
--- a/chrome/browser/search/hotword_service_unittest.cc
+++ b/chrome/browser/search/hotword_service_unittest.cc
@@ -399,8 +399,8 @@
   hotword_service->SetExtensionService(service());
   hotword_service->SetExtensionId(extension_id_);
 
-  // Initialize the locale to "en".
-  SetApplicationLocale(profile(), "en");
+  // Initialize the locale to "en_us".
+  SetApplicationLocale(profile(), "en_us");
 
   // The previous locale should not be set. No reason to uninstall.
   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
@@ -415,13 +415,15 @@
   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
   EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
 
-  // Switch the locale to a valid but different one.
-  SetApplicationLocale(profile(), "fr_fr");
-  EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
+  // TODO(kcarattini): Uncomment this sectione once we launch always-on
+  // in more languages.
+  // // Switch the locale to a valid but different one.
+  // SetApplicationLocale(profile(), "fr_fr");
+  // EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
 
-  // Different but valid locale so expect uninstall.
-  EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
-  EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
+  // // Different but valid locale so expect uninstall.
+  // EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
+  // EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
 
   // Re-enable always-on.
   profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
@@ -432,12 +434,14 @@
   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
   EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
 
-  // If the locale is set back to the last valid one, then an uninstall-install
-  // shouldn't be needed.
-  SetApplicationLocale(profile(), "fr_fr");
-  EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
-  EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
-  EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
+  // TODO(kcarattini): Uncomment this sectione once we launch always-on
+  // in more languages.
+  // // If the locale is set back to the last valid one, then an
+  // // uninstall-install shouldn't be needed.
+  // SetApplicationLocale(profile(), "fr_fr");
+  // EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
+  // EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
+  // EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
 }
 
 TEST_P(HotwordServiceTest, IsAlwaysOnEnabled) {
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc
index bf75e9a..573c415 100644
--- a/chrome/browser/search/instant_service.cc
+++ b/chrome/browser/search/instant_service.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/fallback_icon_service_factory.h"
-#include "chrome/browser/favicon/favicon_service_factory.h"
+#include "chrome/browser/favicon/large_icon_service_factory.h"
 #include "chrome/browser/history/top_sites_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/instant_io_context.h"
@@ -25,7 +25,7 @@
 #include "chrome/browser/ui/webui/theme_source.h"
 #include "chrome/common/render_messages.h"
 #include "components/favicon/core/fallback_icon_service.h"
-#include "components/favicon/core/favicon_service.h"
+#include "components/favicon/core/large_icon_service.h"
 #include "components/history/core/browser/top_sites.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/search_engines/template_url_service.h"
@@ -118,18 +118,16 @@
   content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_));
 #endif  // !defined(OS_ANDROID)
 
-  favicon::FaviconService* favicon_service =
-      FaviconServiceFactory::GetForProfile(profile_,
-                                           ServiceAccessType::EXPLICIT_ACCESS);
   favicon::FallbackIconService* fallback_icon_service =
       FallbackIconServiceFactory::GetForBrowserContext(profile_);
-
-  content::URLDataSource::Add(profile_,
-      new LargeIconSource(favicon_service, fallback_icon_service));
+  favicon::LargeIconService* large_icon_service =
+      LargeIconServiceFactory::GetForBrowserContext(profile_);
   content::URLDataSource::Add(
       profile_, new FallbackIconSource(fallback_icon_service));
   content::URLDataSource::Add(
       profile_, new FaviconSource(profile_, FaviconSource::FAVICON));
+  content::URLDataSource::Add(
+      profile_, new LargeIconSource(fallback_icon_service, large_icon_service));
   content::URLDataSource::Add(profile_, new MostVisitedIframeSource());
   content::URLDataSource::Add(
       profile_, new suggestions::SuggestionsSource(profile_));
diff --git a/chrome/browser/services/gcm/instance_id/instance_id_profile_service.cc b/chrome/browser/services/gcm/instance_id/instance_id_profile_service.cc
new file mode 100644
index 0000000..e91922a
--- /dev/null
+++ b/chrome/browser/services/gcm/instance_id/instance_id_profile_service.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/services/gcm/instance_id/instance_id_profile_service.h"
+
+namespace instance_id {
+
+InstanceIDProfileService::InstanceIDProfileService(Profile* profile) {
+}
+
+InstanceIDProfileService::~InstanceIDProfileService() {
+}
+
+}  // namespace instance_id
diff --git a/chrome/browser/services/gcm/instance_id/instance_id_profile_service.h b/chrome/browser/services/gcm/instance_id/instance_id_profile_service.h
new file mode 100644
index 0000000..7930d11
--- /dev/null
+++ b/chrome/browser/services/gcm/instance_id/instance_id_profile_service.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SERVICES_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_H_
+#define CHROME_BROWSER_SERVICES_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_H_
+
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class Profile;
+
+namespace instance_id {
+
+// Providing Instance ID support, via InstanceIDDriver, to a profile.
+class InstanceIDProfileService : public KeyedService {
+ public:
+  explicit InstanceIDProfileService(Profile* profile);
+  ~InstanceIDProfileService() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(InstanceIDProfileService);
+};
+
+}  // namespace instance_id
+
+#endif  // CHROME_BROWSER_SERVICES_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_H_
diff --git a/chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.cc b/chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.cc
new file mode 100644
index 0000000..6fd67fd
--- /dev/null
+++ b/chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
+#include "chrome/browser/services/gcm/instance_id/instance_id_profile_service.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace instance_id {
+
+// static
+InstanceIDProfileService* InstanceIDProfileServiceFactory::GetForProfile(
+    content::BrowserContext* profile) {
+  // Instance ID is not supported in incognito mode.
+  if (profile->IsOffTheRecord())
+    return NULL;
+
+  return static_cast<InstanceIDProfileService*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+InstanceIDProfileServiceFactory*
+InstanceIDProfileServiceFactory::GetInstance() {
+  return Singleton<InstanceIDProfileServiceFactory>::get();
+}
+
+InstanceIDProfileServiceFactory::InstanceIDProfileServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+        "InstanceIDProfileService",
+        BrowserContextDependencyManager::GetInstance()) {
+  // GCM is needed for device ID.
+  DependsOn(gcm::GCMProfileServiceFactory::GetInstance());
+}
+
+InstanceIDProfileServiceFactory::~InstanceIDProfileServiceFactory() {
+}
+
+KeyedService* InstanceIDProfileServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new InstanceIDProfileService(Profile::FromBrowserContext(context));
+}
+
+content::BrowserContext*
+InstanceIDProfileServiceFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+}
+
+}  // namespace instance_id
diff --git a/chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.h b/chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.h
new file mode 100644
index 0000000..688aea7
--- /dev/null
+++ b/chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SERVICES_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_SERVICES_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace instance_id {
+
+class InstanceIDProfileService;
+
+// Singleton that owns all InstanceIDProfileService and associates them with
+// profiles.
+class InstanceIDProfileServiceFactory :
+    public BrowserContextKeyedServiceFactory {
+ public:
+  static InstanceIDProfileService* GetForProfile(
+      content::BrowserContext* profile);
+  static InstanceIDProfileServiceFactory* GetInstance();
+
+ private:
+  friend struct DefaultSingletonTraits<InstanceIDProfileServiceFactory>;
+
+  InstanceIDProfileServiceFactory();
+  ~InstanceIDProfileServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* profile) const override;
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(InstanceIDProfileServiceFactory);
+};
+
+}  // namespace instance_id
+
+#endif  // CHROME_BROWSER_SERVICES_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_FACTORY_H_
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index f261a35..9af5d0c 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -27,6 +27,7 @@
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
+#include "components/proximity_auth/ble/proximity_auth_ble_system.h"
 #include "components/proximity_auth/switches.h"
 #include "components/user_manager/user.h"
 #include "device/bluetooth/bluetooth_adapter.h"
@@ -646,6 +647,13 @@
     app_manager_->LoadApp();
     NotifyUserUpdated();
 
+    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+            proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery) &&
+        !proximity_auth_ble_system_) {
+      proximity_auth_ble_system_.reset(
+          new proximity_auth::ProximityAuthBleSystem());
+    }
+
 #if defined(OS_CHROMEOS)
     if (!power_monitor_)
       power_monitor_.reset(new PowerMonitor(this));
@@ -664,6 +672,7 @@
     if (!bluetooth_waking_up) {
       app_manager_->DisableAppIfLoaded();
       ResetScreenlockState();
+      proximity_auth_ble_system_.reset();
 #if defined(OS_CHROMEOS)
       power_monitor_.reset();
 #endif
@@ -844,8 +853,10 @@
 }
 
 void EasyUnlockService::EnsureTpmKeyPresentIfNeeded() {
-  if (tpm_key_checked_ || GetType() != TYPE_REGULAR || GetUserEmail().empty())
+  if (tpm_key_checked_ || GetType() != TYPE_REGULAR || GetUserEmail().empty() ||
+      GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) {
     return;
+  }
 
 #if defined(OS_CHROMEOS)
   // If this is called before the session is started, the chances are Chrome
diff --git a/chrome/browser/signin/easy_unlock_service.h b/chrome/browser/signin/easy_unlock_service.h
index 4824a95..969297e 100644
--- a/chrome/browser/signin/easy_unlock_service.h
+++ b/chrome/browser/signin/easy_unlock_service.h
@@ -35,6 +35,10 @@
 class PrefRegistrySyncable;
 }
 
+namespace proximity_auth {
+class ProximityAuthBleSystem;
+}
+
 class EasyUnlockAppManager;
 class EasyUnlockServiceObserver;
 class Profile;
@@ -329,6 +333,11 @@
 
   scoped_ptr<BluetoothDetector> bluetooth_detector_;
 
+  // The proximity auth over Bluetooth Low Energy system. This is main entry
+  // point to bootstap Smart Lock to discover phones over Bluetooth Low
+  // Energy.
+  scoped_ptr<proximity_auth::ProximityAuthBleSystem> proximity_auth_ble_system_;
+
 #if defined(OS_CHROMEOS)
   // Monitors suspend and wake state of ChromeOS.
   class PowerMonitor;
diff --git a/chrome/browser/signin/fake_profile_oauth2_token_service.cc b/chrome/browser/signin/fake_profile_oauth2_token_service.cc
index 89ba6ea..6901cdf4 100644
--- a/chrome/browser/signin/fake_profile_oauth2_token_service.cc
+++ b/chrome/browser/signin/fake_profile_oauth2_token_service.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
 
+#include "base/bind.h"
 #include "base/message_loop/message_loop.h"
-#include "components/signin/core/browser/signin_account_id_helper.h"
 
 FakeProfileOAuth2TokenService::PendingRequest::PendingRequest() {
 }
@@ -16,11 +16,9 @@
 FakeProfileOAuth2TokenService::FakeProfileOAuth2TokenService()
     : auto_post_fetch_response_on_message_loop_(false),
       weak_ptr_factory_(this) {
-  SigninAccountIdHelper::SetDisableForTest(true);
 }
 
 FakeProfileOAuth2TokenService::~FakeProfileOAuth2TokenService() {
-  SigninAccountIdHelper::SetDisableForTest(false);
 }
 
 bool FakeProfileOAuth2TokenService::RefreshTokenIsAvailable(
diff --git a/chrome/browser/speech/tts_android.cc b/chrome/browser/speech/tts_android.cc
index a9e7ee8..be3592cc 100644
--- a/chrome/browser/speech/tts_android.cc
+++ b/chrome/browser/speech/tts_android.cc
@@ -30,8 +30,7 @@
 
 TtsPlatformImplAndroid::~TtsPlatformImplAndroid() {
   JNIEnv* env = AttachCurrentThread();
-  if (java_ref_.obj())
-    Java_TtsPlatformImpl_destroy(env, java_ref_.obj());
+  Java_TtsPlatformImpl_destroy(env, java_ref_.obj());
 }
 
 bool TtsPlatformImplAndroid::PlatformImplAvailable() {
@@ -44,9 +43,6 @@
     const std::string& lang,
     const VoiceData& voice,
     const UtteranceContinuousParameters& params) {
-  if (!java_ref_.obj())
-    return false;
-
   JNIEnv* env = AttachCurrentThread();
   jboolean success = Java_TtsPlatformImpl_speak(
       env, java_ref_.obj(),
@@ -63,9 +59,6 @@
 }
 
 bool TtsPlatformImplAndroid::StopSpeaking() {
-  if (!java_ref_.obj())
-    return false;
-
   JNIEnv* env = AttachCurrentThread();
   Java_TtsPlatformImpl_stop(env, java_ref_.obj());
   utterance_id_ = 0;
@@ -86,9 +79,6 @@
 
 void TtsPlatformImplAndroid::GetVoices(
     std::vector<VoiceData>* out_voices) {
-  if (!java_ref_.obj())
-    return;
-
   JNIEnv* env = AttachCurrentThread();
   if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_.obj()))
     return;
diff --git a/chrome/browser/spellchecker/spellcheck_platform_mac.mm b/chrome/browser/spellchecker/spellcheck_platform_mac.mm
index 434c66fd..805f7ec06 100644
--- a/chrome/browser/spellchecker/spellcheck_platform_mac.mm
+++ b/chrome/browser/spellchecker/spellcheck_platform_mac.mm
@@ -195,14 +195,19 @@
 
 void FillSuggestionList(const base::string16& wrong_word,
                         std::vector<base::string16>* optional_suggestions) {
-  NSString* NS_wrong_word = base::SysUTF16ToNSString(wrong_word);
+  NSString* ns_wrong_word = base::SysUTF16ToNSString(wrong_word);
   // The suggested words for |wrong_word|.
-  NSArray* guesses = [SharedSpellChecker() guessesForWord:NS_wrong_word];
-  for (int i = 0; i < static_cast<int>([guesses count]); ++i) {
-    if (i < chrome::spellcheck_common::kMaxSuggestions) {
-      optional_suggestions->push_back(base::SysNSStringToUTF16(
-                                      [guesses objectAtIndex:i]));
-    }
+  // TODO(groby): guessesForWord: has been deprecated since OSX 10.6.
+  // http://www.crbug.com/479014.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+  NSArray* guesses = [SharedSpellChecker() guessesForWord:ns_wrong_word];
+#pragma clang diagnostic pop
+  int i = 0;
+  for (NSString* guess in guesses) {
+    optional_suggestions->push_back(base::SysNSStringToUTF16(guess));
+    if (++i >= chrome::spellcheck_common::kMaxSuggestions)
+      break;
   }
 }
 
diff --git a/chrome/browser/ssl/chrome_ssl_host_state_delegate.h b/chrome/browser/ssl/chrome_ssl_host_state_delegate.h
index e4e6480d..b680740 100644
--- a/chrome/browser/ssl/chrome_ssl_host_state_delegate.h
+++ b/chrome/browser/ssl/chrome_ssl_host_state_delegate.h
@@ -41,7 +41,7 @@
 
   // Revokes all SSL certificate error allow exceptions made by the user for
   // |host| in the given Profile.
-  virtual void RevokeUserAllowExceptions(const std::string& host);
+  void RevokeUserAllowExceptions(const std::string& host) override;
 
   // RevokeUserAllowExceptionsHard is the same as RevokeUserAllowExceptions but
   // additionally may close idle connections in the process. This should be used
@@ -53,7 +53,7 @@
   // |host|. This does not mean that *all* certificate errors are allowed, just
   // that there exists an exception. To see if a particular certificate and
   // error combination exception is allowed, use QueryPolicy().
-  virtual bool HasAllowException(const std::string& host) const;
+  bool HasAllowException(const std::string& host) const override;
 
  protected:
   // SetClock takes ownership of the passed in clock.
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index e7ded660..59da844 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/safe_browsing/ping_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
+#include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
 #include "chrome/browser/ssl/ssl_blocking_page.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -41,6 +42,7 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
@@ -50,13 +52,19 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/download_test_observer.h"
 #include "content/public/test/test_renderer_host.h"
+#include "net/base/host_port_pair.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_data_directory.h"
 #include "net/cert/cert_status_flags.h"
+#include "net/cert/test_root_certs.h"
 #include "net/cert/x509_certificate.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/http/http_transaction_factory.h"
 #include "net/ssl/ssl_info.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
 
 #if defined(USE_NSS_CERTS)
 #include "chrome/browser/net/nss_context.h"
@@ -265,6 +273,33 @@
 
 }  // namespace CertificateReporting
 
+void RootCertsChangedOnIOThread(
+    const scoped_refptr<net::URLRequestContextGetter> context_getter) {
+  net::CertDatabase::GetInstance()->NotifyObserversOfCACertChanged(NULL);
+  context_getter->GetURLRequestContext()
+      ->http_transaction_factory()
+      ->GetSession()
+      ->CloseAllConnections();
+}
+
+// Alerts the URLRequestContext for the given WebContents that a root
+// certificate has changed state or been removed. This, in turn, clears any
+// cached certificate validation in the cert verifier. This will also close all
+// connections in the socket pool of |contents|, so calls to this should be made
+// with care.
+void RootCertsChanged(WebContents* contents) {
+  scoped_refptr<net::URLRequestContextGetter> url_request_context =
+      contents->GetBrowserContext()->GetRequestContextForRenderProcess(
+          contents->GetRenderProcessHost()->GetID());
+  base::RunLoop run_loop;
+  content::BrowserThread::PostTaskAndReply(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&RootCertsChangedOnIOThread, url_request_context),
+      run_loop.QuitClosure());
+  run_loop.Run();
+  base::RunLoop().RunUntilIdle();
+}
+
 }  // namespace
 
 class SSLUITest : public InProcessBrowserTest {
@@ -438,11 +473,11 @@
   }
 
   static bool GetPageWithUnsafeWorkerPath(
-      const net::SpawnedTestServer& expired_https_server,
+      const net::SpawnedTestServer& https_server,
       std::string* page_with_unsafe_worker_path) {
     // Get the "imported.js" URL from the expired https server and
     // substitute it into the unsafe_worker.js file.
-    GURL imported_js_url = expired_https_server.GetURL("files/ssl/imported.js");
+    GURL imported_js_url = https_server.GetURL("files/ssl/imported.js");
     std::vector<net::SpawnedTestServer::StringPair>
         replacement_text_for_unsafe_worker;
     replacement_text_for_unsafe_worker.push_back(
@@ -2032,32 +2067,93 @@
   CheckAuthenticatedState(tab, AuthState::NONE);
 }
 
-IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorker) {
+// This test, and the related test TestUnsafeContentsWithUserException, verify
+// that if unsafe content is loaded but the host of that unsafe content has a
+// user exception, the content runs and the security style remains
+// authenticated. This is not necessarily the behavior that should exist, but it
+// is verification that it does behave that way. See https://crbug.com/477868
+// for more inforamtion on this.
+IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) {
   ASSERT_TRUE(https_server_.Start());
-  ASSERT_TRUE(https_server_expired_.Start());
+  // Note that it is necessary to user https_server_mismatched_ here over the
+  // other invalid cert servers. This is because the test relies on the two
+  // servers having different hosts since SSL exceptions are per-host, not per
+  // origin, and https_server_mismatched_ uses 'localhost' rather than
+  // '127.0.0.1'.
+  ASSERT_TRUE(https_server_mismatched_.Start());
 
   // Navigate to an unsafe site. Proceed with interstitial page to indicate
   // the user approves the bad certificate.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/blank_page.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  CheckAuthenticationBrokenState(
-      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
+  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+                                 AuthState::SHOWING_INTERSTITIAL);
   ProceedThroughInterstitial(tab);
-  CheckAuthenticationBrokenState(
-      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
+  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+                                 AuthState::NONE);
 
   // Navigate to safe page that has Worker loading unsafe content.
   // Expect content to load but be marked as auth broken due to running insecure
   // content.
   std::string page_with_unsafe_worker_path;
-  ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_,
+  ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_mismatched_,
                                           &page_with_unsafe_worker_path));
-  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
-      page_with_unsafe_worker_path));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_.GetURL(page_with_unsafe_worker_path));
   CheckWorkerLoadResult(tab, true);  // Worker loads insecure content
-  CheckAuthenticationBrokenState(
-      tab, CertError::NONE, AuthState::RAN_INSECURE_CONTENT);
+  CheckAuthenticatedState(tab, CertError::NONE);
+}
+
+// Visits a page with unsafe content and makes sure that if a user exception to
+// the certificate error is present, the image is loaded and script executes.
+//
+// See the comment above SSLUITest.TestUnsafeContentsInWorkerWithUserException
+// for a discussion about the desired behavior.
+IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) {
+  ASSERT_TRUE(https_server_.Start());
+  // Note that it is necessary to user https_server_mismatched_ here over the
+  // other invalid cert servers. This is because the test relies on the two
+  // servers having different hosts since SSL exceptions are per-host, not per
+  // origin, and https_server_mismatched_ uses 'localhost' rather than
+  // '127.0.0.1'.
+  ASSERT_TRUE(https_server_mismatched_.Start());
+
+  // Navigate to an unsafe site. Proceed with interstitial page to indicate
+  // the user approves the bad certificate.
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
+  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+                                 AuthState::SHOWING_INTERSTITIAL);
+  ProceedThroughInterstitial(tab);
+  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+                                 AuthState::NONE);
+
+  std::string replacement_path;
+  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
+      "files/ssl/page_with_unsafe_contents.html",
+      https_server_mismatched_.host_port_pair(), &replacement_path));
+  ui_test_utils::NavigateToURL(browser(),
+                               https_server_.GetURL(replacement_path));
+
+  // When the bad content is filtered, the state is expected to be
+  // authenticated.
+  CheckAuthenticatedState(tab, AuthState::NONE);
+
+  int img_width;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
+      tab, "window.domAutomationController.send(ImageWidth());", &img_width));
+  // In order to check that the image was loaded, we check its width.
+  // The actual image (Google logo) is 114 pixels wide, so we assume a good
+  // image is greater than 100.
+  EXPECT_GT(img_width, 100);
+
+  bool js_result = false;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      tab, "window.domAutomationController.send(IsFooSet());", &js_result));
+  EXPECT_TRUE(js_result);
+  CheckAuthenticatedState(tab, CertError::NONE);
 }
 
 // Test that when the browser blocks displaying insecure content (images), the
@@ -2248,6 +2344,40 @@
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
 }
 
+// Verifies that if a bad certificate is seen for a host and the user proceeds
+// through the interstitial, the decision to proceed is initially remembered.
+// However, if this is followed by another visit, and a good certificate
+// is seen for the same host, the original exception is forgotten.
+IN_PROC_BROWSER_TEST_F(SSLUITest, BadCertFollowedByGoodCert) {
+  ASSERT_TRUE(https_server_.Start());
+  std::string https_server_host =
+      https_server_.GetURL("files/ssl/google.html").host();
+
+  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+  net::TestRootCerts* root_certs = net::TestRootCerts::GetInstance();
+
+  ASSERT_TRUE(root_certs);
+  root_certs->Clear();
+
+  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
+  ChromeSSLHostStateDelegate* state =
+      reinterpret_cast<ChromeSSLHostStateDelegate*>(
+          profile->GetSSLHostStateDelegate());
+
+  ui_test_utils::NavigateToURL(browser(),
+                               https_server_.GetURL("files/ssl/google.html"));
+
+  ProceedThroughInterstitial(tab);
+  EXPECT_TRUE(state->HasAllowException(https_server_host));
+
+  ASSERT_TRUE(https_server_.LoadTestRootCert());
+  RootCertsChanged(tab);
+  ui_test_utils::NavigateToURL(browser(),
+                               https_server_.GetURL("files/ssl/google.html"));
+  ASSERT_FALSE(tab->GetInterstitialPage());
+  EXPECT_FALSE(state->HasAllowException(https_server_host));
+}
+
 class SSLBlockingPageIDNTest : public SecurityInterstitialIDNTest {
  protected:
   // SecurityInterstitialIDNTest implementation
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
index cbc080f..ab5868f 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -103,15 +103,19 @@
 
 void ChildAccountService::SetIsChildAccount(bool is_child_account) {
   PropagateChildStatusToUser(is_child_account);
-  if (profile_->IsChild() == is_child_account)
-    return;
-
-  if (is_child_account) {
-    profile_->GetPrefs()->SetString(prefs::kSupervisedUserId,
-                                    supervised_users::kChildAccountSUID);
-  } else {
-    profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserId);
+  if (profile_->IsChild() != is_child_account) {
+    if (is_child_account) {
+      profile_->GetPrefs()->SetString(prefs::kSupervisedUserId,
+                                      supervised_users::kChildAccountSUID);
+    } else {
+      profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserId);
+    }
   }
+  profile_->GetPrefs()->SetBoolean(prefs::kChildAccountStatusKnown, true);
+
+  for (const auto& callback : status_received_callback_list_)
+    callback.Run();
+  status_received_callback_list_.clear();
 }
 
 void ChildAccountService::Init() {
@@ -321,16 +325,6 @@
       std::find(flags.begin(), flags.end(),
                 kIsChildAccountServiceFlagName) != flags.end();
 
-  bool status_was_known = profile_->GetPrefs()->GetBoolean(
-      prefs::kChildAccountStatusKnown);
-  profile_->GetPrefs()->SetBoolean(prefs::kChildAccountStatusKnown, true);
-
-  if (!status_was_known) {
-    for (auto& callback : status_received_callback_list_)
-      callback.Run();
-    status_received_callback_list_.clear();
-  }
-
   SetIsChildAccount(is_child_account);
 
   ScheduleNextStatusFlagUpdate(
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.cc b/chrome/browser/sync/glue/autofill_data_type_controller.cc
index 87d7132..83729c58 100644
--- a/chrome/browser/sync/glue/autofill_data_type_controller.cc
+++ b/chrome/browser/sync/glue/autofill_data_type_controller.cc
@@ -40,25 +40,25 @@
 }
 
 void AutofillDataTypeController::WebDatabaseLoaded() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(MODEL_STARTING, state());
 
   OnModelLoaded();
 }
 
 AutofillDataTypeController::~AutofillDataTypeController() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 bool AutofillDataTypeController::PostTaskOnBackendThread(
     const tracked_objects::Location& from_here,
     const base::Closure& task) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return BrowserThread::PostTask(BrowserThread::DB, from_here, task);
 }
 
 bool AutofillDataTypeController::StartModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(MODEL_STARTING, state());
 
   autofill::AutofillWebDataService* web_data_service =
@@ -79,7 +79,7 @@
 
 void AutofillDataTypeController::StartAssociating(
     const StartCallback& start_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state(), MODEL_LOADED);
   ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile(
       profile_);
diff --git a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc
index ad0ec69..c1dc733b 100644
--- a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc
+++ b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc
@@ -43,12 +43,12 @@
 }
 
 void AutofillProfileDataTypeController::WebDatabaseLoaded() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   OnModelLoaded();
 }
 
 void AutofillProfileDataTypeController::OnPersonalDataChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state(), MODEL_STARTING);
 
   personal_data_->RemoveObserver(this);
@@ -73,12 +73,12 @@
 bool AutofillProfileDataTypeController::PostTaskOnBackendThread(
     const tracked_objects::Location& from_here,
     const base::Closure& task) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return BrowserThread::PostTask(BrowserThread::DB, from_here, task);
 }
 
 bool AutofillProfileDataTypeController::StartModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state(), MODEL_STARTING);
   // Waiting for the personal data is subtle:  we do this as the PDM resets
   // its cache of unique IDs once it gets loaded. If we were to proceed with
@@ -110,7 +110,7 @@
 }
 
 void AutofillProfileDataTypeController::StopModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   personal_data_->RemoveObserver(this);
 }
 
diff --git a/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc b/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc
index 2f644ba..7975b26 100644
--- a/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc
+++ b/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc
@@ -34,7 +34,7 @@
       profile_(profile),
       callback_registered_(false),
       currently_enabled_(IsEnabled()) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   pref_registrar_.Init(profile->GetPrefs());
   pref_registrar_.Add(
       autofill::prefs::kAutofillWalletSyncExperimentEnabled,
@@ -61,12 +61,12 @@
 bool AutofillWalletDataTypeController::PostTaskOnBackendThread(
     const tracked_objects::Location& from_here,
     const base::Closure& task) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return BrowserThread::PostTask(BrowserThread::DB, from_here, task);
 }
 
 bool AutofillWalletDataTypeController::StartModels() {
-  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state(), MODEL_STARTING);
 
   autofill::AutofillWebDataService* web_data_service =
@@ -89,7 +89,7 @@
 }
 
 void AutofillWalletDataTypeController::StopModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // This function is called when shutting down (nothing is changing), when
   // sync is disabled completely, or when wallet sync is disabled. In the
@@ -115,7 +115,7 @@
 }
 
 bool AutofillWalletDataTypeController::ReadyForStart() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return currently_enabled_;
 }
 
@@ -124,7 +124,7 @@
 }
 
 void AutofillWalletDataTypeController::OnSyncPrefChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   bool new_enabled = IsEnabled();
   if (currently_enabled_ == new_enabled)
@@ -154,7 +154,7 @@
 }
 
 bool AutofillWalletDataTypeController::IsEnabled() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Require both the sync experiment and the user-visible pref to be
   // enabled to sync Wallet data.
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.cc b/chrome/browser/sync/glue/bookmark_change_processor.cc
index ad7ab852..0336a78b 100644
--- a/chrome/browser/sync/glue/bookmark_change_processor.cc
+++ b/chrome/browser/sync/glue/bookmark_change_processor.cc
@@ -54,7 +54,7 @@
       bookmark_model_(NULL),
       profile_(profile),
       model_associator_(model_associator) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(model_associator);
   DCHECK(profile);
   DCHECK(error_handler);
@@ -66,7 +66,7 @@
 }
 
 void BookmarkChangeProcessor::StartImpl() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!bookmark_model_);
   bookmark_model_ = BookmarkModelFactory::GetForProfile(profile_);
   DCHECK(bookmark_model_->loaded());
@@ -524,7 +524,7 @@
     const syncer::BaseTransaction* trans,
     int64 model_version,
     const syncer::ImmutableChangeRecordList& changes) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // A note about ordering.  Sync backend is responsible for ordering the change
   // records in the following order:
   //
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller.cc b/chrome/browser/sync/glue/bookmark_data_type_controller.cc
index abed22c..45007a4 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller.cc
@@ -107,7 +107,7 @@
 
 void BookmarkDataTypeController::OnHistoryServiceLoaded(
     history::HistoryService* service) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state_, MODEL_STARTING);
   history_service_observer_.RemoveAll();
 
diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc
index 08008ba..d24a7e7 100644
--- a/chrome/browser/sync/glue/bookmark_model_associator.cc
+++ b/chrome/browser/sync/glue/bookmark_model_associator.cc
@@ -260,18 +260,18 @@
       unrecoverable_error_handler_(unrecoverable_error_handler),
       expect_mobile_bookmarks_folder_(expect_mobile_bookmarks_folder),
       weak_factory_(this) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(bookmark_model_);
   DCHECK(user_share_);
   DCHECK(unrecoverable_error_handler_);
 }
 
 BookmarkModelAssociator::~BookmarkModelAssociator() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 void BookmarkModelAssociator::UpdatePermanentNodeVisibility() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(bookmark_model_->loaded());
 
   BookmarkNode::Type bookmark_node_types[] = {
@@ -323,7 +323,7 @@
 
 void BookmarkModelAssociator::Associate(const BookmarkNode* node,
                                         int64 sync_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   int64 node_id = node->id();
   DCHECK_NE(sync_id, syncer::kInvalidId);
   DCHECK(id_map_.find(node_id) == id_map_.end());
@@ -336,7 +336,7 @@
 }
 
 void BookmarkModelAssociator::Disassociate(int64 sync_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   SyncIdToBookmarkNodeMap::iterator iter = id_map_inverse_.find(sync_id);
   if (iter == id_map_inverse_.end())
     return;
@@ -582,7 +582,10 @@
             &sync_child_node, parent_node, bookmark_model_, profile_, index);
         if (!child_node) {
           return unrecoverable_error_handler_->CreateAndUploadError(
-              FROM_HERE, "Failed to create bookmark node.", model_type());
+              FROM_HERE, "Failed to create bookmark node with title " +
+                             sync_child_node.GetTitle() + " and url " +
+                             sync_child_node.GetBookmarkSpecifics().url(),
+              model_type());
         }
         Associate(child_node, sync_child_id);
         local_merge_result->set_num_items_added(
diff --git a/chrome/browser/sync/glue/extension_setting_data_type_controller.cc b/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
index 9e015d9..8d269e5 100644
--- a/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
+++ b/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
@@ -29,7 +29,7 @@
           profile_sync_factory),
       type_(type),
       profile_(profile) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
 }
 
@@ -47,12 +47,12 @@
 bool ExtensionSettingDataTypeController::PostTaskOnBackendThread(
     const tracked_objects::Location& from_here,
     const base::Closure& task) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return BrowserThread::PostTask(BrowserThread::FILE, from_here, task);
 }
 
 bool ExtensionSettingDataTypeController::StartModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   extensions::ExtensionSystem::Get(profile_)->InitForRegularProfile(true);
   return true;
 }
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.cc b/chrome/browser/sync/glue/frontend_data_type_controller.cc
index aee9f84..d987f742 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.cc
@@ -35,7 +35,7 @@
       profile_(profile),
       sync_service_(sync_service),
       state_(NOT_RUNNING) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(profile_sync_factory);
   DCHECK(profile);
   DCHECK(sync_service);
@@ -43,7 +43,7 @@
 
 void FrontendDataTypeController::LoadModels(
     const ModelLoadCallback& model_load_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   model_load_callback_ = model_load_callback;
 
   if (state_ != NOT_RUNNING) {
@@ -68,7 +68,7 @@
 }
 
 void FrontendDataTypeController::OnModelLoaded() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state_, MODEL_STARTING);
 
   state_ = MODEL_LOADED;
@@ -77,7 +77,7 @@
 
 void FrontendDataTypeController::StartAssociating(
     const StartCallback& start_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!start_callback.is_null());
   DCHECK_EQ(state_, MODEL_LOADED);
 
@@ -89,7 +89,7 @@
 }
 
 void FrontendDataTypeController::Stop() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (state_ == NOT_RUNNING)
     return;
@@ -158,7 +158,7 @@
 }
 
 FrontendDataTypeController::~FrontendDataTypeController() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 bool FrontendDataTypeController::StartModels() {
@@ -243,7 +243,7 @@
 }
 
 void FrontendDataTypeController::AbortModelLoad() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   CleanUp();
   state_ = NOT_RUNNING;
 }
@@ -252,7 +252,7 @@
     ConfigureResult start_result,
     const syncer::SyncMergeResult& local_merge_result,
     const syncer::SyncMergeResult& syncer_merge_result) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!IsSuccessfulResult(start_result)) {
     if (IsUnrecoverableResult(start_result))
       RecordUnrecoverableError(FROM_HERE, "StartFailed");
@@ -270,7 +270,7 @@
 }
 
 void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 #define PER_DATA_TYPE_MACRO(type_str) \
     UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time);
   SYNC_DATA_TYPE_HISTOGRAM(type());
@@ -278,7 +278,7 @@
 }
 
 void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures",
                             ModelTypeToHistogramInt(type()),
                             syncer::MODEL_TYPE_COUNT);
diff --git a/chrome/browser/sync/glue/history_model_worker.cc b/chrome/browser/sync/glue/history_model_worker.cc
index 6cda56c7..33a7334f 100644
--- a/chrome/browser/sync/glue/history_model_worker.cc
+++ b/chrome/browser/sync/glue/history_model_worker.cc
@@ -70,7 +70,7 @@
     base::CancelableTaskTracker* cancelable_tracker,
     WaitableEvent* done,
     syncer::SyncerError* error) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (history_service.get()) {
     scoped_ptr<history::HistoryDBTask> task(new WorkerTask(work, done, error));
     history_service->ScheduleDBTask(task.Pass(), cancelable_tracker);
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
index b37e96a..cab1037a 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
@@ -53,7 +53,7 @@
     NonFrontendDataTypeController* controller)
     : controller_(controller),
       type_(controller->type()) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   controller_handle_ =
       syncer::MakeWeakHandle(controller_->weak_ptr_factory_.GetWeakPtr());
 }
@@ -173,7 +173,7 @@
       model_associator_(NULL),
       change_processor_(NULL),
       weak_ptr_factory_(this) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(profile_sync_factory_);
   DCHECK(profile_);
   DCHECK(profile_sync_service_);
@@ -181,7 +181,7 @@
 
 void NonFrontendDataTypeController::LoadModels(
     const ModelLoadCallback& model_load_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   model_load_callback_ = model_load_callback;
   if (state_ != NOT_RUNNING) {
     model_load_callback.Run(type(),
@@ -218,7 +218,7 @@
 
 void NonFrontendDataTypeController::StartAssociating(
     const StartCallback& start_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!start_callback.is_null());
   DCHECK(!components_container_);
   DCHECK_EQ(state_, MODEL_LOADED);
@@ -251,7 +251,7 @@
 }
 
 void NonFrontendDataTypeController::Stop() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (state_ == NOT_RUNNING)
     return;
@@ -313,13 +313,13 @@
 }
 
 NonFrontendDataTypeController::~NonFrontendDataTypeController() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!change_processor_);
   DCHECK(!model_associator_);
 }
 
 bool NonFrontendDataTypeController::StartModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state_, MODEL_STARTING);
   // By default, no additional services need to be started before we can proceed
   // with model association, so do nothing.
@@ -334,7 +334,7 @@
     DataTypeController::ConfigureResult start_result,
     const syncer::SyncMergeResult& local_merge_result,
     const syncer::SyncMergeResult& syncer_merge_result) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DataTypeController::State new_state;
 
   if (IsSuccessfulResult(start_result)) {
@@ -354,7 +354,7 @@
     DataTypeController::State new_state,
     const syncer::SyncMergeResult& local_merge_result,
     const syncer::SyncMergeResult& syncer_merge_result) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   state_ = new_state;
   if (state_ != RUNNING) {
@@ -367,7 +367,7 @@
 
 void NonFrontendDataTypeController::DisableImpl(
     const syncer::SyncError& error) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!model_load_callback_.is_null()) {
     model_load_callback_.Run(type(), error);
   }
@@ -375,7 +375,7 @@
 
 void NonFrontendDataTypeController::RecordAssociationTime(
     base::TimeDelta time) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 #define PER_DATA_TYPE_MACRO(type_str) \
     UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time);
   SYNC_DATA_TYPE_HISTOGRAM(type());
@@ -383,7 +383,7 @@
 }
 
 void NonFrontendDataTypeController::RecordStartFailure(ConfigureResult result) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures",
                             ModelTypeToHistogramInt(type()),
                             syncer::MODEL_TYPE_COUNT);
@@ -445,7 +445,7 @@
 
 void NonFrontendDataTypeController::AssociationCallback(
     AssociationResult result) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (result.needs_crypto) {
     StartDone(NEEDS_CRYPTO,
diff --git a/chrome/browser/sync/glue/password_data_type_controller.cc b/chrome/browser/sync/glue/password_data_type_controller.cc
index 71b589a..44464f0 100644
--- a/chrome/browser/sync/glue/password_data_type_controller.cc
+++ b/chrome/browser/sync/glue/password_data_type_controller.cc
@@ -43,14 +43,14 @@
 bool PasswordDataTypeController::PostTaskOnBackendThread(
       const tracked_objects::Location& from_here,
       const base::Closure& task) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!password_store_.get())
     return false;
   return password_store_->ScheduleTask(task);
 }
 
 bool PasswordDataTypeController::StartModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(MODEL_STARTING, state());
 
   ProfileSyncService* profile_sync_service =
@@ -66,7 +66,7 @@
 }
 
 void PasswordDataTypeController::StopModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ProfileSyncService* profile_sync_service =
       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
   DCHECK(profile_sync_service);
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller.cc b/chrome/browser/sync/glue/search_engine_data_type_controller.cc
index 5ac663a..161909d 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller.cc
@@ -60,7 +60,7 @@
 }
 
 void SearchEngineDataTypeController::OnTemplateURLServiceLoaded() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(state_, MODEL_STARTING);
   template_url_subscription_.reset();
   OnModelLoaded();
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.cc b/chrome/browser/sync/glue/sync_backend_host_impl.cc
index 26538eb1..fa0ba02 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_impl.cc
@@ -642,7 +642,7 @@
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK_EQ(type, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL);
 
   content::Details<const syncer::ModelTypeSet> state_details(details);
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
index 00216ff..bbc5a4d 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
@@ -260,7 +260,7 @@
   }
 
   void IssueRefreshRequest(syncer::ModelTypeSet types) {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
     content::NotificationService::current()->Notify(
         chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
diff --git a/chrome/browser/sync/glue/sync_backend_registrar.cc b/chrome/browser/sync/glue/sync_backend_registrar.cc
index bcddbb2..d7b22c7c 100644
--- a/chrome/browser/sync/glue/sync_backend_registrar.cc
+++ b/chrome/browser/sync/glue/sync_backend_registrar.cc
@@ -61,7 +61,7 @@
     scoped_ptr<base::Thread> sync_thread) :
     name_(name),
     profile_(profile) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   CHECK(profile_);
 
   // TODO(pavely): Remove ScopedTracker below once crbug.com/426272 is fixed.
@@ -148,7 +148,7 @@
 }
 
 bool SyncBackendRegistrar::IsNigoriEnabled() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::AutoLock lock(lock_);
   return routing_info_.find(syncer::NIGORI) != routing_info_.end();
 }
@@ -203,7 +203,7 @@
 }
 
 void SyncBackendRegistrar::RequestWorkerStopOnUIThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::AutoLock lock(lock_);
   for (WorkerMap::const_iterator it = workers_.begin();
        it != workers_.end(); ++it) {
diff --git a/chrome/browser/sync/glue/typed_url_change_processor.cc b/chrome/browser/sync/glue/typed_url_change_processor.cc
index f573315..49f07fe 100644
--- a/chrome/browser/sync/glue/typed_url_change_processor.cc
+++ b/chrome/browser/sync/glue/typed_url_change_processor.cc
@@ -323,7 +323,7 @@
 }
 
 void TypedUrlChangeProcessor::StartImpl() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(history_backend_);
   DCHECK(backend_loop_);
   backend_loop_->PostTask(FROM_HERE,
diff --git a/chrome/browser/sync/glue/typed_url_data_type_controller.cc b/chrome/browser/sync/glue/typed_url_data_type_controller.cc
index ab2b1a5..cef7363d 100644
--- a/chrome/browser/sync/glue/typed_url_data_type_controller.cc
+++ b/chrome/browser/sync/glue/typed_url_data_type_controller.cc
@@ -93,7 +93,7 @@
 }
 
 bool TypedUrlDataTypeController::ReadyForStart() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return !profile()->GetPrefs()->GetBoolean(
       prefs::kSavingBrowserHistoryDisabled);
 }
@@ -104,7 +104,7 @@
 }
 
 void TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (profile()->GetPrefs()->GetBoolean(
           prefs::kSavingBrowserHistoryDisabled)) {
     // We've turned off history persistence, so if we are running,
@@ -124,7 +124,7 @@
 bool TypedUrlDataTypeController::PostTaskOnBackendThread(
     const tracked_objects::Location& from_here,
     const base::Closure& task) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   history::HistoryService* history = HistoryServiceFactory::GetForProfile(
       profile(), ServiceAccessType::IMPLICIT_ACCESS);
   if (history) {
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index c7350a8c..2ea5d3e 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -114,7 +114,7 @@
 }
 
 void ProfileSyncServiceAndroid::EnableSync(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Don't need to do anything if we're already enabled.
   if (sync_prefs_->IsStartSuppressed())
     sync_service_->UnsuppressAndStart();
@@ -123,7 +123,7 @@
 }
 
 void ProfileSyncServiceAndroid::DisableSync(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Don't need to do anything if we're already disabled.
   if (!sync_prefs_->IsStartSuppressed()) {
     sync_service_->StopAndSuppress();
@@ -134,7 +134,7 @@
 }
 
 void ProfileSyncServiceAndroid::SignInSync(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Just return if sync already has everything it needs to start up (sync
   // should start up automatically as long as it has credentials). This can
   // happen normally if (for example) the user closes and reopens the sync
@@ -151,7 +151,7 @@
 }
 
 void ProfileSyncServiceAndroid::SignOutSync(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(profile_);
   sync_service_->DisableForUser();
 
@@ -160,13 +160,13 @@
 }
 
 void ProfileSyncServiceAndroid::FlushDirectory(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   sync_service_->FlushDirectory();
 }
 
 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(profile_);
   std::string status(sync_service_->QuerySyncStatusSummaryString());
   return ConvertUTF8ToJavaString(env, status);
@@ -174,7 +174,7 @@
 
 jboolean ProfileSyncServiceAndroid::SetSyncSessionsId(
     JNIEnv* env, jobject obj, jstring tag) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(profile_);
   std::string machine_tag = ConvertJavaStringToUTF8(env, tag);
   sync_prefs_->SetSyncSessionsGUID(machine_tag);
@@ -182,41 +182,41 @@
 }
 
 jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->GetAuthError().state();
 }
 
 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->EncryptEverythingEnabled();
 }
 
 jboolean ProfileSyncServiceAndroid::IsSyncInitialized(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->backend_initialized();
 }
 
 jboolean ProfileSyncServiceAndroid::IsFirstSetupInProgress(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->FirstSetupInProgress();
 }
 
 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingAllowed(
     JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->EncryptEverythingAllowed();
 }
 
 jboolean ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->IsPassphraseRequired();
 }
 
 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
     JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // In case of CUSTOM_PASSPHRASE we always sync passwords. Prompt the user for
   // a passphrase if cryptographer has any pending keys.
   if (sync_service_->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE) {
@@ -237,27 +237,27 @@
 
 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return
       sync_service_->passphrase_required_reason() == syncer::REASON_DECRYPTION;
 }
 
 jboolean ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->IsUsingSecondaryPassphrase();
 }
 
 jboolean ProfileSyncServiceAndroid::SetDecryptionPassphrase(
     JNIEnv* env, jobject obj, jstring passphrase) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::string key = ConvertJavaStringToUTF8(env, passphrase);
   return sync_service_->SetDecryptionPassphrase(key);
 }
 
 void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
     JNIEnv* env, jobject obj, jstring passphrase, jboolean is_gaia) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::string key = ConvertJavaStringToUTF8(env, passphrase);
   sync_service_->SetEncryptionPassphrase(
       key,
@@ -270,20 +270,20 @@
 }
 
 jint ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->GetPassphraseType();
 }
 
 jboolean ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
   return !passphrase_time.is_null();
 }
 
 jlong ProfileSyncServiceAndroid::GetExplicitPassphraseTime(
         JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
   return passphrase_time.ToJavaTime();
 }
@@ -291,7 +291,7 @@
 ScopedJavaLocalRef<jstring>
     ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
         JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
   base::string16 passphrase_time_str =
       base::TimeFormatShortDate(passphrase_time);
@@ -304,7 +304,7 @@
 ScopedJavaLocalRef<jstring>
     ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
         JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
   base::string16 passphrase_time_str =
       base::TimeFormatShortDate(passphrase_time);
@@ -316,7 +316,7 @@
 ScopedJavaLocalRef<jstring>
     ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
         JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const std::string& sync_username =
       SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
   return base::android::ConvertUTF16ToJavaString(env,
@@ -328,14 +328,14 @@
 ScopedJavaLocalRef<jstring>
     ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
         JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return ConvertUTF8ToJavaString(
       env, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY));
 }
 
 jboolean ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
       JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   syncer::SyncStatus status;
   bool is_status_valid = sync_service_->QueryDetailedSyncStatus(&status);
   return is_status_valid && !status.keystore_migration_time.is_null();
@@ -359,7 +359,7 @@
     JNIEnv* env, jobject obj,
     jboolean sync_everything,
     jlong model_type_selection) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   syncer::ModelTypeSet types;
   // Note: only user selectable types should be included here.
   if (model_type_selection & AUTOFILL)
@@ -378,49 +378,49 @@
 
 void ProfileSyncServiceAndroid::SetSetupInProgress(
     JNIEnv* env, jobject obj, jboolean in_progress) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   sync_service_->SetSetupInProgress(in_progress);
 }
 
 void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
     JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   sync_service_->SetSyncSetupCompleted();
 }
 
 jboolean ProfileSyncServiceAndroid::HasSyncSetupCompleted(
     JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->HasSyncSetupCompleted();
 }
 
 jboolean ProfileSyncServiceAndroid::IsStartSuppressed(
     JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_prefs_->IsStartSuppressed();
 }
 
 void ProfileSyncServiceAndroid::EnableEncryptEverything(
     JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   sync_service_->EnableEncryptEverything();
 }
 
 jboolean ProfileSyncServiceAndroid::HasKeepEverythingSynced(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_prefs_->HasKeepEverythingSynced();
 }
 
 jboolean ProfileSyncServiceAndroid::HasUnrecoverableError(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return sync_service_->HasUnrecoverableError();
 }
 
 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::GetAboutInfoForTest(
     JNIEnv* env, jobject) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   scoped_ptr<base::DictionaryValue> about_info =
       sync_ui_util::ConstructAboutInformation(sync_service_);
diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
index 25082eb..e011045 100644
--- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
@@ -173,7 +173,7 @@
       autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
   void RemoveExpiredFormElements() override {}
   void NotifyOfMultipleAutofillChanges() override {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+    DCHECK_CURRENTLY_ON(BrowserThread::DB);
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_changed_);
   }
 
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc
index 565c5ad8..087a4d2 100644
--- a/chrome/browser/sync/profile_sync_test_util.cc
+++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -27,7 +27,7 @@
 void ThreadNotifier::Notify(int type,
                             const content::NotificationSource& source,
                             const content::NotificationDetails& details) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   notify_thread_->message_loop()->PostTask(
       FROM_HERE,
       base::Bind(&ThreadNotifier::NotifyTask, this, type, source, details));
diff --git a/chrome/browser/sync/profile_sync_test_util.h b/chrome/browser/sync/profile_sync_test_util.h
index b2692df..2fb427476 100644
--- a/chrome/browser/sync/profile_sync_test_util.h
+++ b/chrome/browser/sync/profile_sync_test_util.h
@@ -29,7 +29,7 @@
 }
 
 ACTION(QuitUIMessageLoop) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   base::MessageLoop::current()->Quit();
 }
 
diff --git a/chrome/browser/sync/sessions/session_data_type_controller.cc b/chrome/browser/sync/sessions/session_data_type_controller.cc
index f3d43ba..9eb90ae4 100644
--- a/chrome/browser/sync/sessions/session_data_type_controller.cc
+++ b/chrome/browser/sync/sessions/session_data_type_controller.cc
@@ -46,7 +46,7 @@
 SessionDataTypeController::~SessionDataTypeController() {}
 
 bool SessionDataTypeController::StartModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::set<const browser_sync::SyncedWindowDelegate*> window =
       synced_window_getter_->GetSyncedWindowDelegates();
   for (std::set<const browser_sync::SyncedWindowDelegate*>::const_iterator i =
@@ -77,7 +77,7 @@
 }
 
 bool SessionDataTypeController::ReadyForStart() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return !profile_->GetPrefs()->GetBoolean(
       prefs::kSavingBrowserHistoryDisabled);
 }
@@ -96,7 +96,7 @@
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_EQ(chrome::NOTIFICATION_SESSION_RESTORE_COMPLETE, type);
   DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
   notification_registrar_.RemoveAll();
@@ -106,7 +106,7 @@
 }
 
 void SessionDataTypeController::OnLocalDeviceInfoInitialized() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   subscription_.reset();
 
   waiting_on_local_device_info_ = false;
@@ -114,7 +114,7 @@
 }
 
 void SessionDataTypeController::OnSavingBrowserHistoryPrefChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (profile_->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled)) {
     // If history and tabs persistence is turned off then generate an
     // unrecoverable error. SESSIONS won't be a registered type on the next
diff --git a/chrome/browser/sync/test/integration/autofill_helper.cc b/chrome/browser/sync/test/integration/autofill_helper.cc
index b5877fc5..957de84 100644
--- a/chrome/browser/sync/test/integration/autofill_helper.cc
+++ b/chrome/browser/sync/test/integration/autofill_helper.cc
@@ -101,14 +101,14 @@
 
 void GetAllAutofillEntriesOnDBThread(AutofillWebDataService* wds,
                                      std::vector<AutofillEntry>* entries) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+  DCHECK_CURRENTLY_ON(BrowserThread::DB);
   AutofillTable::FromWebDatabase(
       wds->GetDatabase())->GetAllAutofillEntries(entries);
 }
 
 std::vector<AutofillEntry> GetAllAutofillEntries(AutofillWebDataService* wds) {
   std::vector<AutofillEntry> entries;
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   RunOnDBThreadAndBlock(Bind(&GetAllAutofillEntriesOnDBThread,
                              Unretained(wds),
                              &entries));
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_service.cc b/chrome/browser/sync_file_system/local/local_file_sync_service.cc
index 51ab55a..b9c76f74 100644
--- a/chrome/browser/sync_file_system/local/local_file_sync_service.cc
+++ b/chrome/browser/sync_file_system/local/local_file_sync_service.cc
@@ -120,7 +120,7 @@
 }
 
 LocalFileSyncService::~LocalFileSyncService() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 void LocalFileSyncService::Shutdown() {
@@ -350,7 +350,7 @@
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)
               .get())),
       local_change_processor_(nullptr) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   sync_context_->AddOriginChangeObserver(this);
 }
 
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.cc b/chrome/browser/sync_file_system/sync_file_system_service.cc
index 777c8c5..804eccf 100644
--- a/chrome/browser/sync_file_system/sync_file_system_service.cc
+++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -158,7 +158,7 @@
 
   // LocalFileSyncService::Observer overrides.
   void OnLocalChangeAvailable(int64 pending_changes) override {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
     OnChangesUpdated(pending_changes);
 
@@ -208,7 +208,7 @@
 
   // RemoteFileSyncService::Observer overrides.
   void OnRemoteChangeQueueUpdated(int64 pending_changes) override {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
     OnChangesUpdated(pending_changes);
 
@@ -251,7 +251,7 @@
 // SyncFileSystemService
 
 void SyncFileSystemService::Shutdown() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   local_sync_runners_.clear();
   remote_sync_runners_.clear();
@@ -272,7 +272,7 @@
 }
 
 SyncFileSystemService::~SyncFileSystemService() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!profile_);
 }
 
@@ -446,7 +446,7 @@
 void SyncFileSystemService::Initialize(
     scoped_ptr<LocalFileSyncService> local_service,
     scoped_ptr<RemoteFileSyncService> remote_service) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(local_service);
   DCHECK(remote_service);
   DCHECK(profile_);
@@ -635,7 +635,7 @@
 void SyncFileSystemService::OnRemoteServiceStateUpdated(
     RemoteServiceState state,
     const std::string& description) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   util::Log(logging::LOG_VERBOSE, FROM_HERE,
             "OnRemoteServiceStateChanged: %d %s", state, description.c_str());
 
diff --git a/chrome/browser/task_management/providers/child_process_task_provider.cc b/chrome/browser/task_management/providers/child_process_task_provider.cc
index 59db47f34..a6f2073a 100644
--- a/chrome/browser/task_management/providers/child_process_task_provider.cc
+++ b/chrome/browser/task_management/providers/child_process_task_provider.cc
@@ -24,7 +24,7 @@
 // |BrowserChildProcessObserver|.
 scoped_ptr<std::vector<ChildProcessData>> CollectChildProcessData() {
   // The |BrowserChildProcessHostIterator| must only be used on the IO thread.
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   scoped_ptr<std::vector<ChildProcessData>> child_processes(
       new std::vector<ChildProcessData>());
@@ -55,7 +55,7 @@
 Task* ChildProcessTaskProvider::GetTaskOfUrlRequest(int origin_pid,
                                                     int child_id,
                                                     int route_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   auto itr = tasks_by_pid_.find(static_cast<base::ProcessId>(origin_pid));
   if (itr == tasks_by_pid_.end())
     return nullptr;
@@ -65,7 +65,7 @@
 
 void ChildProcessTaskProvider::BrowserChildProcessHostConnected(
     const content::ChildProcessData& data) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (data.handle == base::kNullProcessHandle)
     return;
 
@@ -74,12 +74,12 @@
 
 void ChildProcessTaskProvider::BrowserChildProcessHostDisconnected(
     const content::ChildProcessData& data) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DeleteTask(data.handle);
 }
 
 void ChildProcessTaskProvider::StartUpdating() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(tasks_by_handle_.empty());
   DCHECK(tasks_by_pid_.empty());
 
@@ -93,7 +93,7 @@
 }
 
 void ChildProcessTaskProvider::StopUpdating() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // ChildProcessDataCollected() should never be called after this, and hence
   // we must invalidate the weak pointers.
@@ -112,7 +112,7 @@
 
 void ChildProcessTaskProvider::ChildProcessDataCollected(
     scoped_ptr<const std::vector<content::ChildProcessData>> child_processes) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   for (auto& process_data : *child_processes)
     CreateTask(process_data);
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 8175584..53f5de7 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -651,7 +651,7 @@
 // static
 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension(
     const Extension* extension) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(extension);
   DCHECK(extension->is_theme());
 
@@ -712,7 +712,7 @@
 // static
 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack(
     const base::FilePath& path, const std::string& expected_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Allow IO on UI thread due to deep-seated theme design issues.
   // (see http://crbug.com/80206)
   base::ThreadRestrictions::ScopedAllowIO allow_io;
diff --git a/chrome/browser/thumbnails/content_based_thumbnailing_algorithm.cc b/chrome/browser/thumbnails/content_based_thumbnailing_algorithm.cc
index 9d6222f..6278009 100644
--- a/chrome/browser/thumbnails/content_based_thumbnailing_algorithm.cc
+++ b/chrome/browser/thumbnails/content_based_thumbnailing_algorithm.cc
@@ -60,7 +60,7 @@
     scoped_refptr<ThumbnailingContext> context,
     const ConsumerCallback& callback,
     const SkBitmap& bitmap) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(context.get());
   if (bitmap.isNull() || bitmap.empty())
     return;
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop.cc b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
index 67774d55..102fd61 100644
--- a/chrome/browser/thumbnails/simple_thumbnail_crop.cc
+++ b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
@@ -41,7 +41,7 @@
     scoped_refptr<ThumbnailingContext> context,
     const ConsumerCallback& callback,
     const SkBitmap& bitmap) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (bitmap.isNull() || bitmap.empty())
     return;
 
diff --git a/chrome/browser/thumbnails/thumbnail_service_impl.cc b/chrome/browser/thumbnails/thumbnail_service_impl.cc
index 29ff5ec..ee6cf7e 100644
--- a/chrome/browser/thumbnails/thumbnail_service_impl.cc
+++ b/chrome/browser/thumbnails/thumbnail_service_impl.cc
@@ -36,7 +36,7 @@
 
 void AddForcedURLOnUIThread(scoped_refptr<history::TopSites> top_sites,
                             const GURL& url) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (top_sites)
     top_sites->AddForcedURL(url, base::Time::Now());
diff --git a/chrome/browser/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
index 0db6199..f8322e7 100644
--- a/chrome/browser/thumbnails/thumbnail_tab_helper.cc
+++ b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
@@ -71,7 +71,7 @@
 
   // On success, we must be on the UI thread (on failure because of shutdown we
   // are not on the UI thread).
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   algorithm->ProcessBitmap(context, base::Bind(&UpdateThumbnail), bitmap);
 }
@@ -79,7 +79,7 @@
 void AsyncProcessThumbnail(content::WebContents* web_contents,
                            scoped_refptr<ThumbnailingContext> context,
                            scoped_refptr<ThumbnailingAlgorithm> algorithm) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   RenderWidgetHost* render_widget_host = web_contents->GetRenderViewHost();
   content::RenderWidgetHostView* view = render_widget_host->GetView();
   if (!view)
diff --git a/chrome/browser/ui/app_list/search/common/url_icon_source.cc b/chrome/browser/ui/app_list/search/common/url_icon_source.cc
index 3dccf53..daa4046 100644
--- a/chrome/browser/ui/app_list/search/common/url_icon_source.cc
+++ b/chrome/browser/ui/app_list/search/common/url_icon_source.cc
@@ -22,9 +22,7 @@
                              const GURL& icon_url,
                              int icon_size,
                              int default_icon_resource_id)
-    : ImageRequest(
-          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
-      icon_loaded_callback_(icon_loaded_callback),
+    : icon_loaded_callback_(icon_loaded_callback),
       context_getter_(context_getter),
       icon_url_(icon_url),
       icon_size_(icon_size),
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index f3ef877..c70275f 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -58,6 +58,8 @@
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
 #include "chrome/browser/chromeos/options/network_config_view.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/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
@@ -1018,8 +1020,17 @@
   GetSystemTrayNotifier()->NotifyDateFormatChanged();
   // This also works for enterprise-managed devices because they never have
   // local owner.
-  if (user_manager::UserManager::Get()->IsCurrentUserOwner())
-    CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock);
+  if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
+    user_manager::User* const user =
+        user_manager::UserManager::Get()->GetActiveUser();
+    CHECK(user);
+    Profile* const profile = ProfileHelper::Get()->GetProfileByUser(user);
+    CHECK(profile);
+    OwnerSettingsServiceChromeOS* const service =
+        OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile);
+    CHECK(service);
+    service->SetBoolean(kSystemUse24HourClock, use_24_hour_clock);
+  }
 }
 
 void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() {
@@ -1120,8 +1131,15 @@
   // user's profile has actually been loaded (http://crbug.com/317745). The
   // system tray's time format is updated at login via SetProfile().
   if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
-    CrosSettings::Get()->SetBoolean(kSystemUse24HourClock,
-                                    ShouldUse24HourClock());
+    user_manager::User* const user =
+        user_manager::UserManager::Get()->GetActiveUser();
+    CHECK(user);
+    Profile* const profile = ProfileHelper::Get()->GetProfileByUser(user);
+    CHECK(profile);
+    OwnerSettingsServiceChromeOS* const service =
+        OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile);
+    CHECK(service);
+    service->SetBoolean(kSystemUse24HourClock, ShouldUse24HourClock());
   }
 }
 
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 56ccdce..ac03700f 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -2074,9 +2074,6 @@
 }
 #endif
 
-// TODO(schenney) Disable on Mac to enable a Blink roll.
-// Re-enable and fix after Blink rolls.
-#if !defined(OS_MACOSX)
 IN_PROC_BROWSER_TEST_F(BrowserTest, WindowOpenClose) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kDisablePopupBlocking);
@@ -2089,7 +2086,6 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 2);
   EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
 }
-#endif
 
 // TODO(linux_aura) http://crbug.com/163931
 // Mac disabled: http://crbug.com/169820
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc
index 8a43633..feb5af2 100644
--- a/chrome/browser/ui/browser_command_controller_browsertest.cc
+++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -75,15 +75,9 @@
 
 // Note that a Browser's destructor, when the browser's profile is guest, will
 // create and execute a BrowsingDataRemover.
-// Flakes on Linux: http://crbug.com/471953
-#if defined(OS_LINUX)
-#define MAYBE_NewAvatarMenuEnabledInGuestMode \
-    DISABLED_NewAvatarMenuEnabledInGuestMode
-#else
-#define MAYBE_NewAvatarMenuEnabledInGuestMode NewAvatarMenuEnabledInGuestMode
-#endif
+// Flakes http://crbug.com/471953
 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
-                       MAYBE_NewAvatarMenuEnabledInGuestMode) {
+                       DISABLED_NewAvatarMenuEnabledInGuestMode) {
   switches::EnableNewAvatarMenuForTesting(
       base::CommandLine::ForCurrentProcess());
 
diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
index 6744a8c..84e1618 100644
--- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
@@ -855,8 +855,10 @@
 }
 
 void NativeAppWindowCocoa::WindowDidEnterFullscreen() {
-  is_fullscreen_ = true;
-  app_window_->OSFullscreen();
+  if (!is_fullscreen_) {
+    is_fullscreen_ = true;
+    app_window_->OSFullscreen();
+  }
   app_window_->OnNativeWindowChanged();
 }
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h
index 25479f9..483270e 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h
@@ -20,13 +20,24 @@
  @private
   const bookmarks::BookmarkNode* bookmarkNode_;  // weak
   NSMatrix* matrix_;  // weak
+
+  // NSCell does not implement the |target| or |action| properties. Subclasses
+  // that need this functionality are expected to implement this functionality.
   id target_;  // weak
   SEL action_;
 }
 
 @property(nonatomic, assign) NSMatrix* matrix;
+
+#if !defined(MAC_OS_X_VERSION_10_10) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
+// In OSX SDK <= 10.9, there are setters and getters for target and action in
+// NSCell, but no properties. In the OSX 10.10 SDK, the properties are defined
+// as atomic. There is no point in redeclaring the properties if they already
+// exist.
 @property(nonatomic, assign) id target;
 @property(nonatomic, assign) SEL action;
+#endif  // MAC_OS_X_VERSION_10_10
 
 - (const bookmarks::BookmarkNode*)bookmarkNode;
 - (void)setBookmarkNode:(const bookmarks::BookmarkNode*)bookmarkNode;
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
index af71cd3..073e7dd 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
@@ -16,6 +16,7 @@
 @class BrowserActionsContainerView;
 @class MenuButton;
 class ToolbarActionsBar;
+@class ToolbarActionsBarBubbleMac;
 class ToolbarActionsBarDelegate;
 
 namespace content {
@@ -60,11 +61,15 @@
 
   // The Browser Actions overflow menu.
   base::scoped_nsobject<NSMenu> overflowMenu_;
+
+  // The bubble that is actively showing, if any.
+  ToolbarActionsBarBubbleMac* activeBubble_;
 }
 
 @property(readonly, nonatomic) BrowserActionsContainerView* containerView;
 @property(readonly, nonatomic) Browser* browser;
 @property(readonly, nonatomic) BOOL isOverflow;
+@property(readonly, nonatomic) ToolbarActionsBarBubbleMac* activeBubble;
 
 // Initializes the controller given the current browser and container view that
 // will hold the browser action buttons. If |mainController| is nil, the created
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index ff5a3b2..10ae632 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -111,6 +111,10 @@
 // Returns the frame that the button with the given |index| should have.
 - (NSRect)frameForIndex:(NSUInteger)index;
 
+// Returns the popup point for the given |view| with |bounds|.
+- (NSPoint)popupPointForView:(NSView*)view
+                  withBounds:(NSRect)bounds;
+
 // Moves the given button both visually and within the toolbar model to the
 // specified index.
 - (void)moveButton:(BrowserActionButton*)button
@@ -149,6 +153,10 @@
 - (ToolbarActionsBarBubbleMac*)createMessageBubble:
     (scoped_ptr<ToolbarActionsBarBubbleDelegate>)delegate;
 
+// Called when the window for the active bubble is closing, and sets the active
+// bubble to nil.
+- (void)bubbleWindowClosing:(NSNotification*)notification;
+
 @end
 
 namespace {
@@ -281,6 +289,7 @@
 @synthesize containerView = containerView_;
 @synthesize browser = browser_;
 @synthesize isOverflow = isOverflow_;
+@synthesize activeBubble = activeBubble_;
 
 #pragma mark -
 #pragma mark Public Methods
@@ -403,17 +412,7 @@
                         fromView:[button superview]];
   }
 
-  // Anchor point just above the center of the bottom.
-  DCHECK([referenceButton isFlipped]);
-  NSPoint anchor = NSMakePoint(NSMidX(bounds),
-                               NSMaxY(bounds) - kBrowserActionBubbleYOffset);
-  // Convert the point to the container view's frame, and adjust for animation.
-  NSPoint anchorInContainer =
-      [containerView_ convertPoint:anchor fromView:referenceButton];
-  anchorInContainer.x -= NSMinX([containerView_ frame]) -
-      NSMinX([containerView_ animationEndFrame]);
-
-  return [containerView_ convertPoint:anchorInContainer toView:nil];
+  return [self popupPointForView:referenceButton withBounds:bounds];
 }
 
 - (BOOL)chevronIsHidden {
@@ -512,11 +511,18 @@
   std::vector<ToolbarActionViewController*> toolbar_actions =
       toolbarActionsBar_->toolbar_actions();
   for (NSUInteger i = 0; i < [buttons_ count]; ++i) {
-    if ([[buttons_ objectAtIndex:i] viewController] != toolbar_actions[i]) {
+    auto controller = static_cast<ToolbarActionViewController*>(
+        [[buttons_ objectAtIndex:i] viewController]);
+    if (controller != toolbar_actions[i]) {
       size_t j = i + 1;
-      while (toolbar_actions[i] != [[buttons_ objectAtIndex:j] viewController])
+      while (true) {
+        auto other_controller = static_cast<ToolbarActionViewController*>(
+            [[buttons_ objectAtIndex:j] viewController]);
+        if (other_controller == toolbar_actions[i])
+          break;
         ++j;
-      [buttons_ exchangeObjectAtIndex:i withObjectAtIndex: j];
+      }
+      [buttons_ exchangeObjectAtIndex:i withObjectAtIndex:j];
     }
   }
 
@@ -691,7 +697,8 @@
 }
 
 - (void)containerMouseEntered:(NSNotification*)notification {
-  if (ExtensionToolbarIconSurfacingBubbleDelegate::ShouldShowForProfile(
+  if (!activeBubble_ &&  // only show one bubble at a time
+      ExtensionToolbarIconSurfacingBubbleDelegate::ShouldShowForProfile(
           browser_->profile())) {
     ToolbarActionsBarBubbleMac* bubble =
         [self createMessageBubble:scoped_ptr<ToolbarActionsBarBubbleDelegate>(
@@ -766,6 +773,21 @@
                     ToolbarActionsBar::IconHeight());
 }
 
+- (NSPoint)popupPointForView:(NSView*)view
+                  withBounds:(NSRect)bounds {
+  // Anchor point just above the center of the bottom.
+  DCHECK([view isFlipped]);
+  NSPoint anchor = NSMakePoint(NSMidX(bounds),
+                               NSMaxY(bounds) - kBrowserActionBubbleYOffset);
+  // Convert the point to the container view's frame, and adjust for animation.
+  NSPoint anchorInContainer =
+      [containerView_ convertPoint:anchor fromView:view];
+  anchorInContainer.x -= NSMinX([containerView_ frame]) -
+      NSMinX([containerView_ animationEndFrame]);
+
+  return [containerView_ convertPoint:anchorInContainer toView:nil];
+}
+
 - (void)moveButton:(BrowserActionButton*)button
            toIndex:(NSUInteger)index {
   NSRect buttonFrame = [self frameForIndex:index];
@@ -889,15 +911,33 @@
 - (ToolbarActionsBarBubbleMac*)createMessageBubble:
     (scoped_ptr<ToolbarActionsBarBubbleDelegate>)delegate {
   DCHECK_GE([buttons_ count], 0u);
-  NSPoint anchor = [self popupPointForId:[[buttons_ objectAtIndex:0]
-                                             viewController]->GetId()];
+  NSPoint anchor;
+  if ([buttons_ count] > 0) {
+    auto controller = static_cast<ToolbarActionViewController*>(
+        [[buttons_ objectAtIndex:0] viewController]);
+    anchor = [self popupPointForId:controller->GetId()];
+  } else {
+    NSView* wrenchButton = [[self toolbarController] wrenchButton];
+    anchor = [self popupPointForView:wrenchButton
+                          withBounds:[wrenchButton bounds]];
+  }
+
   anchor = [[containerView_ window] convertBaseToScreen:anchor];
-  return [[ToolbarActionsBarBubbleMac alloc]
+  activeBubble_ = [[ToolbarActionsBarBubbleMac alloc]
       initWithParentWindow:[containerView_ window]
                anchorPoint:anchor
                   delegate:delegate.Pass()];
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(bubbleWindowClosing:)
+             name:NSWindowWillCloseNotification
+           object:[activeBubble_ window]];
+  return activeBubble_;
 }
 
+- (void)bubbleWindowClosing:(NSNotification*)notification {
+  activeBubble_ = nil;
+}
 
 #pragma mark -
 #pragma mark Testing Methods
diff --git a/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm b/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm
new file mode 100644
index 0000000..2579ed5
--- /dev/null
+++ b/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm
@@ -0,0 +1,131 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/browser_window.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/extensions/browser_action_button.h"
+#import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
+#import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
+#include "chrome/browser/ui/extensions/extension_message_bubble_browsertest.h"
+
+namespace {
+
+// Returns the ToolbarController for the given browser.
+ToolbarController* ToolbarControllerForBrowser(Browser* browser) {
+  return [[BrowserWindowController browserWindowControllerForWindow:
+             browser->window()->GetNativeWindow()] toolbarController];
+}
+
+// Checks that the |bubble| is using the |expectedReferenceView|, and is in
+// approximately the correct position.
+void CheckBubbleAndReferenceView(ToolbarActionsBarBubbleMac* bubble,
+                                 NSView* expectedReferenceView) {
+  ASSERT_TRUE(bubble);
+  ASSERT_TRUE(expectedReferenceView);
+
+  // Do a rough check that the bubble is in the right place.
+  // A window's frame (like the bubble's) is already in screen coordinates.
+  NSRect bubbleFrame = [[bubble window] frame];
+
+  // Unfortunately, it's more tedious to get the reference view's screen
+  // coordinates (since -[NSWindow convertRectToScreen is in OSX 10.7).
+  NSRect referenceFrame = [expectedReferenceView bounds];
+  referenceFrame =
+      [expectedReferenceView convertRect:referenceFrame toView:nil];
+  NSWindow* window = [expectedReferenceView window];
+  CGFloat refLowY = [expectedReferenceView isFlipped] ?
+      NSMaxY(referenceFrame) : NSMinY(referenceFrame);
+  NSPoint refLowerLeft = NSMakePoint(NSMinX(referenceFrame), refLowY);
+  NSPoint refLowerLeftInScreen = [window convertBaseToScreen:refLowerLeft];
+  NSPoint refLowerRight = NSMakePoint(NSMaxX(referenceFrame), refLowY);
+  NSPoint refLowerRightInScreen = [window convertBaseToScreen:refLowerRight];
+
+  // The bubble should be below the reference view, but not too far below.
+  EXPECT_LE(NSMaxY(bubbleFrame), refLowerLeftInScreen.y);
+  // "Too far below" is kind of ambiguous. The exact logic of where a bubble
+  // is positioned with respect to its anchor view should be tested as part of
+  // the bubble logic, but we still want to make sure we didn't accidentally
+  // place it somewhere crazy (which can happen if we draw it, and then
+  // animate or reposition the reference view).
+  const int kFudgeFactor = 50;
+  EXPECT_LE(NSMaxY(bubbleFrame), refLowerLeftInScreen.y + kFudgeFactor);
+
+  // The bubble should intersect the reference view somewhere along the x-axis.
+  EXPECT_LE(refLowerLeftInScreen.x, NSMaxX(bubbleFrame));
+  EXPECT_LE(NSMinX(bubbleFrame), refLowerRightInScreen.x);
+
+  // And, of course, the bubble should be visible.
+  EXPECT_TRUE([[bubble window] isVisible]);
+}
+
+}  // namespace
+
+class ExtensionMessageBubbleBrowserTestMac
+    : public ExtensionMessageBubbleBrowserTest {
+ public:
+  ExtensionMessageBubbleBrowserTestMac() {}
+  ~ExtensionMessageBubbleBrowserTestMac() override {}
+
+ private:
+  void SetUpCommandLine(base::CommandLine* command_line) override;
+  void CheckBubble(Browser* browser, AnchorPosition anchor) override;
+  void CloseBubble(Browser* browser) override;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleBrowserTestMac);
+};
+
+void ExtensionMessageBubbleBrowserTestMac::SetUpCommandLine(
+    base::CommandLine* command_line) {
+  ExtensionMessageBubbleBrowserTest::SetUpCommandLine(command_line);
+  [ToolbarActionsBarBubbleMac setAnimationEnabledForTesting:NO];
+}
+
+void ExtensionMessageBubbleBrowserTestMac::CheckBubble(
+    Browser* browser,
+    AnchorPosition anchor) {
+  ToolbarController* toolbarController = ToolbarControllerForBrowser(browser);
+  BrowserActionsController* actionsController =
+      [toolbarController browserActionsController];
+  NSView* anchorView = nil;
+  ToolbarActionsBarBubbleMac* bubble = [actionsController activeBubble];
+  switch (anchor) {
+    case ANCHOR_BROWSER_ACTION:
+      anchorView = [actionsController buttonWithIndex:0];
+      break;
+    case ANCHOR_WRENCH_MENU:
+      anchorView = [toolbarController wrenchButton];
+      break;
+  }
+  CheckBubbleAndReferenceView(bubble, anchorView);
+}
+
+void ExtensionMessageBubbleBrowserTestMac::CloseBubble(Browser* browser) {
+  BrowserActionsController* controller =
+      [ToolbarControllerForBrowser(browser) browserActionsController];
+  ToolbarActionsBarBubbleMac* bubble = [controller activeBubble];
+  ASSERT_TRUE(bubble);
+  [bubble close];
+  EXPECT_EQ(nil, [controller activeBubble]);
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleBrowserTestMac,
+                       ExtensionBubbleAnchoredToExtensionAction) {
+  TestBubbleAnchoredToExtensionAction();
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleBrowserTestMac,
+                       ExtensionBubbleAnchoredToWrenchMenu) {
+  TestBubbleAnchoredToWrenchMenu();
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleBrowserTestMac,
+                       PRE_ExtensionBubbleShowsOnStartup) {
+  PreBubbleShowsOnStartup();
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleBrowserTestMac,
+                       ExtensionBubbleShowsOnStartup) {
+  TestBubbleShowsOnStartup();
+}
diff --git a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h
index eef920d..81808e9 100644
--- a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h
+++ b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h
@@ -39,6 +39,9 @@
                   delegate:(scoped_ptr<ToolbarActionsBarBubbleDelegate>)
                                delegate;
 
+// Toggles animation for testing purposes.
++ (void)setAnimationEnabledForTesting:(BOOL)enabled;
+
 @property(readonly, nonatomic) NSButton* actionButton;
 @property(readonly, nonatomic) NSButton* dismissButton;
 @property(readonly, nonatomic) NSButton* learnMoreButton;
diff --git a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm
index e131d23..940d26b 100644
--- a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm
+++ b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm
@@ -17,6 +17,10 @@
 #import "ui/base/cocoa/window_size_constants.h"
 #include "ui/native_theme/native_theme.h"
 
+namespace {
+BOOL g_animations_enabled = false;
+}
+
 @class ExtensionMessageBubbleButton;
 
 @interface ToolbarActionsBarBubbleMac ()
@@ -91,11 +95,18 @@
         gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor(
             ui::NativeTheme::kColorId_DialogBackground))];
 
+    if (!g_animations_enabled)
+      [window setAllowedAnimations:info_bubble::kAnimateNone];
+
     [self layout];
   }
   return self;
 }
 
++ (void)setAnimationEnabledForTesting:(BOOL)enabled {
+  g_animations_enabled = enabled;
+}
+
 - (IBAction)showWindow:(id)sender {
   delegate_->OnBubbleShown();
   [super showWindow:sender];
diff --git a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac_unittest.mm b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac_unittest.mm
index 2fcd80d..bca8680 100644
--- a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac_unittest.mm
+++ b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac_unittest.mm
@@ -8,7 +8,6 @@
 #include "base/strings/utf_string_conversions.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
 #import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h"
-#import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/run_loop_testing.h"
 #include "chrome/browser/ui/toolbar/test_toolbar_actions_bar_bubble_delegate.h"
 #import "ui/events/test/cocoa_test_event_utils.h"
@@ -59,6 +58,8 @@
   ToolbarActionsBarBubbleMacTest() {}
   ~ToolbarActionsBarBubbleMacTest() override {}
 
+  void SetUp() override;
+
   // Create and display a new bubble with the given |delegate|.
   ToolbarActionsBarBubbleMac* CreateAndShowBubble(
       TestToolbarActionsBarBubbleDelegate* delegate);
@@ -78,6 +79,11 @@
   DISALLOW_COPY_AND_ASSIGN(ToolbarActionsBarBubbleMacTest);
 };
 
+void ToolbarActionsBarBubbleMacTest::SetUp() {
+  CocoaTest::SetUp();
+  [ToolbarActionsBarBubbleMac setAnimationEnabledForTesting:NO];
+}
+
 ToolbarActionsBarBubbleMac* ToolbarActionsBarBubbleMacTest::CreateAndShowBubble(
     TestToolbarActionsBarBubbleDelegate* delegate) {
   ToolbarActionsBarBubbleMac* bubble =
@@ -87,8 +93,6 @@
                       delegate:delegate->GetDelegate()];
   EXPECT_FALSE(delegate->shown());
   [bubble showWindow:nil];
-  [base::mac::ObjCCastStrict<InfoBubbleWindow>([bubble window])
-      setAllowedAnimations:info_bubble::kAnimateNone];
   chrome::testing::NSRunLoopRunAllPending();
   EXPECT_FALSE(delegate->close_action());
   EXPECT_TRUE(delegate->shown());
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
index 7d633768..66a1bc2 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -392,7 +392,7 @@
   }
 
   model()->StartAutocomplete([editor selectedRange].length != 0,
-                            prevent_inline_autocomplete);
+                            prevent_inline_autocomplete, false);
 }
 
 void OmniboxViewMac::CloseOmniboxPopup() {
@@ -736,7 +736,7 @@
     if (cmd == @selector(insertBacktab:)) {
       if (model()->popup_model()->selected_line_state() ==
             OmniboxPopupModel::KEYWORD) {
-        model()->ClearKeyword(GetText());
+        model()->ClearKeyword();
         return true;
       } else {
         model()->OnUpOrDownKeyPressed(-1);
@@ -987,7 +987,7 @@
 
   // We're showing a keyword and the user pressed backspace at the
   // beginning of the text.  Delete the selected keyword.
-  model()->ClearKeyword(GetText());
+  model()->ClearKeyword();
   return true;
 }
 
diff --git a/chrome/browser/ui/cocoa/simple_message_box_mac.mm b/chrome/browser/ui/cocoa/simple_message_box_mac.mm
index 767c963..732569fc 100644
--- a/chrome/browser/ui/cocoa/simple_message_box_mac.mm
+++ b/chrome/browser/ui/cocoa/simple_message_box_mac.mm
@@ -25,7 +25,7 @@
   // Ignore the title; it's the window title on other platforms and ignorable.
   NSAlert* alert = [[[NSAlert alloc] init] autorelease];
   [alert setMessageText:base::SysUTF16ToNSString(message)];
-  NSUInteger style = (type == MESSAGE_BOX_TYPE_INFORMATION) ?
+  NSAlertStyle style = (type == MESSAGE_BOX_TYPE_INFORMATION) ?
       NSInformationalAlertStyle : NSWarningAlertStyle;
   [alert setAlertStyle:style];
   if (type == MESSAGE_BOX_TYPE_QUESTION) {
diff --git a/chrome/browser/ui/cocoa/web_dialog_window_controller.mm b/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
index b66c86c..87f40074 100644
--- a/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
+++ b/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
@@ -199,8 +199,7 @@
 
 void WebDialogWindowDelegateBridge::OnCloseContents(WebContents* source,
                                                     bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 void WebDialogWindowDelegateBridge::CloseContents(WebContents* source) {
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc
new file mode 100644
index 0000000..9bea9c6d
--- /dev/null
+++ b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc
@@ -0,0 +1,71 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/extensions/extension_message_bubble_browsertest.h"
+
+#include "base/run_loop.h"
+#include "chrome/browser/extensions/extension_action_test_util.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/ui/extensions/extension_message_bubble_factory.h"
+#include "extensions/common/feature_switch.h"
+
+ExtensionMessageBubbleBrowserTest::ExtensionMessageBubbleBrowserTest() {
+}
+
+ExtensionMessageBubbleBrowserTest::~ExtensionMessageBubbleBrowserTest() {
+}
+
+void ExtensionMessageBubbleBrowserTest::SetUpCommandLine(
+    base::CommandLine* command_line) {
+  BrowserActionsBarBrowserTest::SetUpCommandLine(command_line);
+  // The dev mode warning bubble is an easy one to trigger, so we use that for
+  // our testing purposes.
+  dev_mode_bubble_override_.reset(
+      new extensions::FeatureSwitch::ScopedOverride(
+          extensions::FeatureSwitch::force_dev_mode_highlighting(),
+          true));
+  ExtensionMessageBubbleFactory::set_enabled_for_tests(true);
+}
+
+void ExtensionMessageBubbleBrowserTest::TestBubbleAnchoredToExtensionAction() {
+  scoped_refptr<const extensions::Extension> action_extension =
+      extensions::extension_action_test_util::CreateActionExtension(
+          "action_extension",
+          extensions::extension_action_test_util::BROWSER_ACTION,
+          extensions::Manifest::UNPACKED);
+  extension_service()->AddExtension(action_extension.get());
+
+  Browser* second_browser = new Browser(
+      Browser::CreateParams(profile(), browser()->host_desktop_type()));
+  base::RunLoop().RunUntilIdle();
+
+  CheckBubble(second_browser, ANCHOR_BROWSER_ACTION);
+  CloseBubble(second_browser);
+}
+
+void ExtensionMessageBubbleBrowserTest::TestBubbleAnchoredToWrenchMenu() {
+  scoped_refptr<const extensions::Extension> no_action_extension =
+      extensions::extension_action_test_util::CreateActionExtension(
+          "action_extension",
+          extensions::extension_action_test_util::NO_ACTION,
+          extensions::Manifest::UNPACKED);
+  extension_service()->AddExtension(no_action_extension.get());
+
+  Browser* second_browser = new Browser(
+      Browser::CreateParams(profile(), browser()->host_desktop_type()));
+  base::RunLoop().RunUntilIdle();
+
+  CheckBubble(second_browser, ANCHOR_WRENCH_MENU);
+  CloseBubble(second_browser);
+}
+
+void ExtensionMessageBubbleBrowserTest::PreBubbleShowsOnStartup() {
+  LoadExtension(test_data_dir_.AppendASCII("good_unpacked"));
+}
+
+void ExtensionMessageBubbleBrowserTest::TestBubbleShowsOnStartup() {
+  base::RunLoop().RunUntilIdle();
+  CheckBubble(browser(), ANCHOR_BROWSER_ACTION);
+  CloseBubble(browser());
+}
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h
new file mode 100644
index 0000000..1552130f
--- /dev/null
+++ b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_MESSAGE_BUBBLE_BROWSERTEST_H_
+#define CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_MESSAGE_BUBBLE_BROWSERTEST_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h"
+
+class ExtensionMessageBubbleBrowserTest
+    : public BrowserActionsBarBrowserTest {
+ protected:
+  enum AnchorPosition {
+    ANCHOR_BROWSER_ACTION,
+    ANCHOR_WRENCH_MENU,
+  };
+
+  ExtensionMessageBubbleBrowserTest();
+  ~ExtensionMessageBubbleBrowserTest() override;
+
+  // BrowserActionsBarBrowserTest:
+  void SetUpCommandLine(base::CommandLine* command_line) override;
+
+  // Checks the position of the bubble present in the given |browser|, when the
+  // bubble should be anchored at the given |anchor|.
+  virtual void CheckBubble(Browser* browser, AnchorPosition anchor) = 0;
+
+  // Closes the bubble present in the given |browser|.
+  virtual void CloseBubble(Browser* browser) = 0;
+
+  // The following are essentially the different tests, but we can't define the
+  // tests in this file, since it relies on platform-specific implementation
+  // (the above virtual methods).
+
+  // Tests that an extension bubble will be anchored to an extension action when
+  // there are extensions with actions.
+  void TestBubbleAnchoredToExtensionAction();
+
+  // Tests that an extension bubble will be anchored to the wrench menu when
+  // there aren't any extensions with actions.
+  // This also tests that the crashes in crbug.com/476426 are fixed.
+  void TestBubbleAnchoredToWrenchMenu();
+
+  // Tests that the extension bubble will show on startup.
+  void PreBubbleShowsOnStartup();
+  void TestBubbleShowsOnStartup();
+
+ private:
+  scoped_ptr<extensions::FeatureSwitch::ScopedOverride>
+      dev_mode_bubble_override_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleBrowserTest);
+};
+
+#endif  // CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_MESSAGE_BUBBLE_BROWSERTEST_H_
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
index dcbdd8a..6bc5f55 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
@@ -560,7 +560,8 @@
 
 void OmniboxEditModel::StartAutocomplete(
     bool has_selected_text,
-    bool prevent_inline_autocomplete) {
+    bool prevent_inline_autocomplete,
+    bool entering_keyword_mode) {
   // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
   tracked_objects::ScopedTracker tracking_profile(
       FROM_HERE_WITH_EXPLICIT_FUNCTION(
@@ -570,12 +571,17 @@
     // Cursor position is equivalent to the current selection's end.
     size_t start;
     view_->GetSelectionBounds(&start, &cursor_position);
-    // Adjust cursor position taking into account possible keyword in the user
-    // text.  We rely on DisplayTextFromUserText() method which is consistent
-    // with keyword extraction done in KeywordProvider/SearchProvider.
-    const size_t cursor_offset =
-        user_text_.length() - DisplayTextFromUserText(user_text_).length();
-    cursor_position += cursor_offset;
+    // If we're in keyword mode, we're not displaying the full |user_text_|, so
+    // the cursor position we got from the view has to be adjusted later by the
+    // length of the undisplayed text.  If we're just entering keyword mode,
+    // though, we have to avoid making this adjustment, because we haven't
+    // actually hidden any text yet, but the caller has already cleared
+    // |is_keyword_hint_|, so DisplayTextFromUserText() will believe we are
+    // already in keyword mode, and will thus mis-adjust the cursor position.
+    if (!entering_keyword_mode) {
+      cursor_position +=
+          user_text_.length() - DisplayTextFromUserText(user_text_).length();
+    }
   } else {
     // There are some cases where StartAutocomplete() may be called
     // with non-empty |inline_autocomplete_text_|.  In such cases, we cannot
@@ -894,16 +900,40 @@
   if (popup_model() && popup_model()->IsOpen())
     popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD);
   else
-    StartAutocomplete(false, true);
+    StartAutocomplete(false, true, true);
 
-  // Ensure the current selection is saved before showing keyword mode
-  // so that moving to another line and then reverting the text will restore
-  // the current state properly.
-  bool save_original_selection = !has_temporary_text_;
-  has_temporary_text_ = true;
-  view_->OnTemporaryTextMaybeChanged(
-      DisplayTextFromUserText(CurrentMatch(NULL).fill_into_edit),
-      save_original_selection, true);
+  // When entering keyword mode via tab, the new text to show is whatever the
+  // newly-selected match in the dropdown is.  When entering via space, however,
+  // we should make sure to use the actual |user_text_| as the basis for the new
+  // text.  This ensures that if the user types "<keyword><space>" and the
+  // default match would have inline autocompleted a further string (e.g.
+  // because there's a past multi-word search beginning with this keyword), the
+  // inline autocompletion doesn't get filled in as the keyword search query
+  // text.
+  //
+  // We also treat tabbing into keyword mode like tabbing through the popup in
+  // that we set |has_temporary_text_|, whereas pressing space is treated like
+  // a new keystroke that changes the current match instead of overlaying it
+  // with a temporary one.  This is important because rerunning autocomplete
+  // after the user pressed space, which will have happened just before reaching
+  // here, may have generated a new match, which the user won't actually see and
+  // which we don't want to switch back to when existing keyword mode; see
+  // comments in ClearKeyword().
+  if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) {
+    // Ensure the current selection is saved before showing keyword mode
+    // so that moving to another line and then reverting the text will restore
+    // the current state properly.
+    bool save_original_selection = !has_temporary_text_;
+    has_temporary_text_ = true;
+    const AutocompleteMatch& match = CurrentMatch(NULL);
+    original_url_ = match.destination_url;
+    view_->OnTemporaryTextMaybeChanged(
+        DisplayTextFromUserText(match.fill_into_edit),
+        save_original_selection, true);
+  } else {
+    view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(user_text_),
+                                       false, true);
+  }
 
   view_->UpdatePlaceholderText();
 
@@ -922,29 +952,41 @@
     delegate_->OnInputStateChanged();
 }
 
-void OmniboxEditModel::ClearKeyword(const base::string16& visible_text) {
+void OmniboxEditModel::ClearKeyword() {
   autocomplete_controller()->Stop(false);
   omnibox_controller_->ClearPopupKeywordMode();
 
-  const base::string16 window_text(keyword_ + visible_text);
+  const base::string16 window_text(keyword_ + view_->GetText());
 
-  // Only reset the result if the edit text has changed since the
-  // keyword was accepted, or if the popup is closed.
-  if (just_deleted_text_ || !visible_text.empty() ||
-      !(popup_model() && popup_model()->IsOpen())) {
+  // If we've tabbed into keyword mode and haven't done anything else,
+  // |has_temporary_text_| will be true, and we should just revert into keyword
+  // hint mode; otherwise we do a more complete state update/revert via
+  // OnBefore/AfterPossibleChange().
+  //
+  // If we were to do the "complete state revert" all the time, then in cases
+  // where our associated keyword match is in the middle of the popup instead of
+  // on the first line, tabbing into it and then hitting shift-tab would reset
+  // the entire popup contents, and we'd wind up with the first line selected.
+  //
+  // If we were instead to "just switch back to keyword hint mode" all the time,
+  // we could wind up with strange state in some cases.  For example, if a user
+  // has a keyword named "x", an inline-autocompletable history site "xyz.com",
+  // and a lower-ranked inline-autocompletable search "x y", then typing "x"
+  // will inline autocomplete to "xyz.com", hitting space will toggle into
+  // keyword mode, but then hitting backspace might wind up with the default
+  // match as the "x y" search, due to the particulars of how we re-run
+  // autocomplete for "x " before toggling into keyword mode to begin with.
+  if (has_temporary_text_) {
+    is_keyword_hint_ = true;
+    view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(),
+        false, true);
+  } else {
     view_->OnBeforePossibleChange();
     view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(),
         false, false);
     keyword_.clear();
     is_keyword_hint_ = false;
     view_->OnAfterPossibleChange();
-    just_deleted_text_ = true;  // OnAfterPossibleChange() fails to clear this
-                                // since the edit contents have actually grown
-                                // longer.
-  } else {
-    is_keyword_hint_ = true;
-    view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(),
-        false, true);
   }
 
   view_->UpdatePlaceholderText();
@@ -1375,7 +1417,11 @@
       // have gotten here.
       CHECK(!result().empty());
       CHECK(popup_model()->selected_line() < result().size());
-      *match = result().match_at(popup_model()->selected_line());
+      const AutocompleteMatch& selected_match =
+          result().match_at(popup_model()->selected_line());
+      *match =
+          (popup_model()->selected_line_state() == OmniboxPopupModel::KEYWORD) ?
+              *selected_match.associated_keyword : selected_match;
     }
     if (alternate_nav_url &&
         (!popup_model() || popup_model()->manually_selected_match().empty()))
@@ -1402,8 +1448,7 @@
 bool OmniboxEditModel::MaybeAcceptKeywordBySpace(
     const base::string16& new_text) {
   size_t keyword_length = new_text.length() - 1;
-  return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() &&
-      inline_autocomplete_text_.empty() &&
+  return (paste_state_ == NONE) && is_keyword_hint_ &&
       (keyword_.length() == keyword_length) &&
       IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) &&
       !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) &&
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.h b/chrome/browser/ui/omnibox/omnibox_edit_model.h
index 274fca10..7260790 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.h
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.h
@@ -174,7 +174,8 @@
 
   // Directs the popup to start autocomplete.
   void StartAutocomplete(bool has_selected_text,
-                         bool prevent_inline_autocomplete);
+                         bool prevent_inline_autocomplete,
+                         bool entering_keyword_mode);
 
   // Closes the popup and cancels any pending asynchronous queries.
   void StopAutocomplete();
@@ -242,9 +243,8 @@
   // Accepts the current temporary text as the user text.
   void AcceptTemporaryTextAsUserText();
 
-  // Clears the current keyword.  |visible_text| is the (non-keyword) text
-  // currently visible in the edit.
-  void ClearKeyword(const base::string16& visible_text);
+  // Clears the current keyword.
+  void ClearKeyword();
 
   // Returns the current autocomplete result.  This logic should in the future
   // live in AutocompleteController but resides here for now.  This method is
diff --git a/chrome/browser/ui/omnibox/omnibox_popup_model.cc b/chrome/browser/ui/omnibox/omnibox_popup_model.cc
index c43b961..d20ee265 100644
--- a/chrome/browser/ui/omnibox/omnibox_popup_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_popup_model.cc
@@ -64,6 +64,8 @@
   if (!description_width)
     return;
 
+  // If we want to display the description, we need to reserve enough space for
+  // the separator.
   available_width -= separator_width;
 
   if (contents_width + description_width > available_width) {
diff --git a/chrome/browser/ui/omnibox/omnibox_popup_model.h b/chrome/browser/ui/omnibox/omnibox_popup_model.h
index dc5f7344..c87302b 100644
--- a/chrome/browser/ui/omnibox/omnibox_popup_model.h
+++ b/chrome/browser/ui/omnibox/omnibox_popup_model.h
@@ -87,8 +87,14 @@
   void Move(int count);
 
   // If the selected line has both a normal match and a keyword match, this can
-  // be used to choose which to select. It is an error to call this when the
-  // selected line does not have both matches (or there is no selection).
+  // be used to choose which to select.  This allows the user to toggle between
+  // normal and keyword mode with tab/shift-tab without rerunning autocomplete
+  // or disturbing other popup state, which in turn is an important part of
+  // supporting the use of tab to do both tab-to-search and
+  // tab-to-traverse-dropdown.
+  //
+  // It is an error to call this when the selected line does not have both
+  // matches (or there is no selection).
   void SetSelectedLineState(LineState state);
 
   // Called when the user hits shift-delete.  This should determine if the item
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 11f8029..8c02bb4 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -883,7 +883,7 @@
   ASSERT_TRUE(omnibox_view->GetText().empty());
 
   // Revert to keyword hint mode.
-  omnibox_view->model()->ClearKeyword(base::string16());
+  omnibox_view->model()->ClearKeyword();
   ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
   ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
   ASSERT_EQ(search_keyword, omnibox_view->GetText());
@@ -898,7 +898,7 @@
   ASSERT_TRUE(omnibox_view->GetText().empty());
 
   // Revert to keyword hint mode.
-  omnibox_view->model()->ClearKeyword(base::string16());
+  omnibox_view->model()->ClearKeyword();
   ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
   ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
   ASSERT_EQ(search_keyword, omnibox_view->GetText());
diff --git a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
index 9987f46..a347a39 100644
--- a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
+++ b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
@@ -83,8 +83,7 @@
       Profile* profile,
       const GURL& url,
       const Referrer& referrer,
-      Origin origin,
-      uint8 experiment_id) override;
+      Origin origin) override;
 
  private:
   bool call_did_finish_load_;
@@ -99,8 +98,7 @@
     const Referrer& referrer,
     Origin origin,
     bool call_did_finish_load)
-    : PrerenderContents(prerender_manager, profile, url, referrer, origin,
-                        PrerenderManager::kNoExperiment),
+    : PrerenderContents(prerender_manager, profile, url, referrer, origin),
       profile_(profile),
       url_(url),
       call_did_finish_load_(call_did_finish_load) {
@@ -143,8 +141,7 @@
     Profile* profile,
     const GURL& url,
     const Referrer& referrer,
-    Origin origin,
-    uint8 experiment_id) {
+    Origin origin) {
   return new DummyPrerenderContents(prerender_manager, profile, url, referrer,
                                     origin, call_did_finish_load_);
 }
diff --git a/chrome/browser/ui/sync/inline_login_dialog.cc b/chrome/browser/ui/sync/inline_login_dialog.cc
index 555cdbb..dfd056d 100644
--- a/chrome/browser/ui/sync/inline_login_dialog.cc
+++ b/chrome/browser/ui/sync/inline_login_dialog.cc
@@ -48,8 +48,7 @@
 
 void InlineLoginDialog::OnCloseContents(
     content::WebContents* source, bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool InlineLoginDialog::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index df974a92d..fb3a6ce 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -8,6 +8,8 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/chrome_content_settings_client.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
+#include "chrome/browser/engagement/site_engagement_helper.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
 #include "chrome/browser/favicon/favicon_helper.h"
 #include "chrome/browser/history/history_tab_helper.h"
 #include "chrome/browser/infobars/infobar_service.h"
@@ -152,6 +154,8 @@
   PrefsTabHelper::CreateForWebContents(web_contents);
   prerender::PrerenderTabHelper::CreateForWebContents(web_contents);
   SearchTabHelper::CreateForWebContents(web_contents);
+  if (SiteEngagementService::IsEnabled())
+    SiteEngagementHelper::CreateForWebContents(web_contents);
   // TODO(vabr): Remove TabSpecificContentSettings from here once their function
   // is taken over by ChromeContentSettingsClient. http://crbug.com/387075
   TabSpecificContentSettings::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
index 04de2ffd..1308607 100644
--- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
+++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -172,10 +172,8 @@
   EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
   EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(0));
   // Force hide one of the extensions' browser action.
-  extensions::ExtensionActionAPI::SetBrowserActionVisibility(
-      extensions::ExtensionPrefs::Get(browser()->profile()),
-      extension_a()->id(),
-      false);
+  extensions::ExtensionActionAPI::Get(browser()->profile())->
+      SetBrowserActionVisibility(extension_a()->id(), false);
   // The browser action for Extension A should be removed.
   EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
   EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(0));
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc
index 72e570e..a8cf716 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/ui/extensions/extension_action_view_controller.h"
 #include "chrome/browser/ui/extensions/extension_message_bubble_factory.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/tabs/tab_strip_model_observer.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/toolbar/toolbar_actions_bar_delegate.h"
@@ -101,305 +100,8 @@
 bool ToolbarActionsBar::disable_animations_for_testing_ = false;
 
 // static
-bool ToolbarActionsBar::pop_out_actions_to_run_ = false;
-
-// static
 bool ToolbarActionsBar::send_overflowed_action_changes_ = true;
 
-// A class to implement an optional tab ordering that "pops out" actions that
-// want to run on a particular page, as part of our experimentation with how to
-// best signal that actions like extension page actions want to run.
-// TODO(devlin): Once we finally settle on the right behavior, determine if
-// we need this.
-class ToolbarActionsBar::TabOrderHelper
-    : public TabStripModelObserver {
- public:
-  TabOrderHelper(ToolbarActionsBar* toolbar,
-                 Browser* browser,
-                 extensions::ExtensionToolbarModel* model);
-  ~TabOrderHelper() override;
-
-  // Returns the number of extra icons that should appear on the given |tab_id|
-  // because of actions that are going to pop out.
-  size_t GetExtraIconCount(int tab_id);
-
-  // Returns the item order of actions for the tab with the given
-  // |web_contents|.
-  WeakToolbarActions GetActionOrder(content::WebContents* web_contents);
-
-  // Notifies the TabOrderHelper that a given |action| does/doesn't want to run
-  // on the tab indicated by |tab_id|.
-  void SetActionWantsToRun(ToolbarActionViewController* action,
-                           int tab_id,
-                           bool wants_to_run);
-
-  // Notifies the TabOrderHelper that a given |action| has been removed.
-  void ActionRemoved(ToolbarActionViewController* action);
-
-  // Handles a resize, including updating any actions that want to act and
-  // updating the model.
-  void HandleResize(size_t resized_count, int tab_id);
-
-  // Handles a drag and drop, including updating any actions that want to act
-  // and updating the model.
-  void HandleDragDrop(int dragged,
-                      int dropped,
-                      ToolbarActionsBar::DragType drag_type,
-                      int tab_id);
-
-  void notify_overflow_bar(ToolbarActionsBar* overflow_bar,
-                           bool should_notify) {
-    // There's a possibility that a new overflow bar can be constructed before
-    // the first is fully destroyed. Only un-register the |overflow_bar_| if
-    // it's the one making the request.
-    if (should_notify)
-      overflow_bar_ = overflow_bar;
-    else if (overflow_bar_ == overflow_bar)
-      overflow_bar_ = nullptr;
-  }
-
- private:
-  // TabStripModelObserver:
-  void TabInsertedAt(content::WebContents* web_contents,
-                     int index,
-                     bool foreground) override;
-  void TabDetachedAt(content::WebContents* web_contents, int index) override;
-  void ActiveTabChanged(content::WebContents* old_contents,
-                        content::WebContents* new_contents,
-                        int index,
-                        int reason) override;
-  void TabStripModelDeleted() override;
-
-  // Notifies the main |toolbar_| and, if present, the |overflow_bar_| that
-  // actions need to be reordered.
-  void NotifyReorderActions();
-
-  // The set of tabs for the given action (the key) is currently "popped out".
-  // "Popped out" actions are those that were in the overflow menu normally, but
-  // want to run and are moved to the main bar so the user can see them.
-  std::map<ToolbarActionViewController*, std::set<int>> popped_out_in_tabs_;
-
-  // The set of tab ids that have been checked for whether actions need to be
-  // popped out or not.
-  std::set<int> tabs_checked_for_pop_out_;
-
-  // The owning ToolbarActionsBar.
-  ToolbarActionsBar* toolbar_;
-
-  // The overflow bar, if one is present.
-  ToolbarActionsBar* overflow_bar_;
-
-  // The associated toolbar model.
-  extensions::ExtensionToolbarModel* model_;
-
-  // A scoped tab strip observer so we can clean up |tabs_checked_for_popout_|.
-  ScopedObserver<TabStripModel, TabStripModelObserver> tab_strip_observer_;
-
-  DISALLOW_COPY_AND_ASSIGN(TabOrderHelper);
-};
-
-ToolbarActionsBar::TabOrderHelper::TabOrderHelper(
-    ToolbarActionsBar* toolbar,
-    Browser* browser,
-    extensions::ExtensionToolbarModel* model)
-    : toolbar_(toolbar),
-      overflow_bar_(nullptr),
-      model_(model),
-      tab_strip_observer_(this) {
-  tab_strip_observer_.Add(browser->tab_strip_model());
-}
-
-ToolbarActionsBar::TabOrderHelper::~TabOrderHelper() {
-}
-
-size_t ToolbarActionsBar::TabOrderHelper::GetExtraIconCount(int tab_id) {
-  size_t extra_icons = 0;
-  const WeakToolbarActions& toolbar_actions = toolbar_->toolbar_actions();
-  for (ToolbarActionViewController* action : toolbar_actions) {
-    auto actions_tabs = popped_out_in_tabs_.find(action);
-    if (actions_tabs != popped_out_in_tabs_.end() &&
-        actions_tabs->second.count(tab_id))
-      ++extra_icons;
-  }
-  return extra_icons;
-}
-
-void ToolbarActionsBar::TabOrderHelper::HandleResize(size_t resized_count,
-                                                     int tab_id) {
-  int extra = GetExtraIconCount(tab_id);
-  size_t tab_icon_count = model_->visible_icon_count() + extra;
-  bool reorder_necessary = false;
-  const WeakToolbarActions& toolbar_actions = toolbar_->toolbar_actions();
-  if (resized_count < tab_icon_count) {
-    for (int i = resized_count; i < extra; ++i) {
-      // If an extension that was popped out to act is overflowed, then it
-      // should no longer be popped out, and it also doesn't count for adjusting
-      // the visible count (since it wasn't really out to begin with).
-      if (popped_out_in_tabs_[toolbar_actions[i]].count(tab_id)) {
-        reorder_necessary = true;
-        popped_out_in_tabs_[toolbar_actions[i]].erase(tab_id);
-        ++(resized_count);
-      }
-    }
-  } else {
-    // If the user increases the toolbar size while actions that popped out are
-    // visible, we need to re-arrange the icons in other windows to be
-    // consistent with what the user sees.
-    // That is, if the normal order is A, B, [C, D] (with C and D hidden), C
-    // pops out to act, and then the user increases the size of the toolbar,
-    // the user sees uncovering D (since C is already out). This is what should
-    // happen in all windows.
-    for (size_t i = tab_icon_count; i < resized_count; ++i) {
-      if (toolbar_actions[i]->GetId() !=
-              model_->toolbar_items()[i - extra]->id())
-        model_->MoveExtensionIcon(toolbar_actions[i]->GetId(), i - extra);
-    }
-  }
-
-  resized_count -= extra;
-  model_->SetVisibleIconCount(resized_count);
-  if (reorder_necessary)
-    NotifyReorderActions();
-}
-
-void ToolbarActionsBar::TabOrderHelper::HandleDragDrop(
-    int dragged_index,
-    int dropped_index,
-    ToolbarActionsBar::DragType drag_type,
-    int tab_id) {
-  const WeakToolbarActions& toolbar_actions = toolbar_->toolbar_actions();
-  ToolbarActionViewController* action = toolbar_actions[dragged_index];
-  int delta = 0;
-  switch (drag_type) {
-    case ToolbarActionsBar::DRAG_TO_OVERFLOW:
-      // If the user moves an action back into overflow, then we don't adjust
-      // the base visible count, but do stop popping that action out.
-      if (popped_out_in_tabs_[action].count(tab_id))
-        popped_out_in_tabs_[action].erase(tab_id);
-      else
-        delta = -1;
-      break;
-    case ToolbarActionsBar::DRAG_TO_MAIN:
-      delta = 1;
-      break;
-    case ToolbarActionsBar::DRAG_TO_SAME:
-      // If the user moves an action that had popped out to be on the toolbar,
-      // then we treat it as "pinning" the action, and adjust the base visible
-      // count to accommodate.
-      if (popped_out_in_tabs_[action].count(tab_id)) {
-        delta = 1;
-        popped_out_in_tabs_[action].erase(tab_id);
-      }
-      break;
-  }
-
-  // If there are any actions that are in front of the dropped index only
-  // because they were popped out, decrement the dropped index.
-  for (int i = 0; i < dropped_index; ++i) {
-    if (i != dragged_index &&
-        model_->GetIndexForId(toolbar_actions[i]->GetId()) >= dropped_index)
-      --dropped_index;
-  }
-
-  model_->MoveExtensionIcon(action->GetId(), dropped_index);
-
-  if (delta)
-    model_->SetVisibleIconCount(model_->visible_icon_count() + delta);
-}
-
-void ToolbarActionsBar::TabOrderHelper::SetActionWantsToRun(
-    ToolbarActionViewController* action,
-    int tab_id,
-    bool wants_to_run) {
-  bool is_overflowed = model_->GetIndexForId(action->GetId()) >=
-      static_cast<int>(model_->visible_icon_count());
-  bool reorder_necessary = false;
-  if (wants_to_run && is_overflowed) {
-    popped_out_in_tabs_[action].insert(tab_id);
-    reorder_necessary = true;
-  } else if (!wants_to_run && popped_out_in_tabs_[action].count(tab_id)) {
-    popped_out_in_tabs_[action].erase(tab_id);
-    reorder_necessary = true;
-  }
-  if (reorder_necessary)
-    NotifyReorderActions();
-}
-
-void ToolbarActionsBar::TabOrderHelper::ActionRemoved(
-    ToolbarActionViewController* action) {
-  popped_out_in_tabs_.erase(action);
-}
-
-WeakToolbarActions ToolbarActionsBar::TabOrderHelper::GetActionOrder(
-    content::WebContents* web_contents) {
-  WeakToolbarActions toolbar_actions = toolbar_->toolbar_actions();
-  // First, make sure that we've checked any actions that want to run.
-  int tab_id = SessionTabHelper::IdForTab(web_contents);
-  if (!tabs_checked_for_pop_out_.count(tab_id)) {
-    tabs_checked_for_pop_out_.insert(tab_id);
-    for (ToolbarActionViewController* toolbar_action : toolbar_actions) {
-      if (toolbar_action->WantsToRun(web_contents))
-        popped_out_in_tabs_[toolbar_action].insert(tab_id);
-    }
-  }
-
-  // Then, shift any actions that want to run to the front.
-  size_t insert_at = 0;
-  // Rotate any actions that want to run to the boundary between visible and
-  // overflowed actions.
-  for (WeakToolbarActions::iterator iter =
-           toolbar_actions.begin() + model_->visible_icon_count();
-       iter != toolbar_actions.end(); ++iter) {
-    if (popped_out_in_tabs_[(*iter)].count(tab_id)) {
-      std::rotate(toolbar_actions.begin() + insert_at, iter, iter + 1);
-      ++insert_at;
-    }
-  }
-
-  return toolbar_actions;
-}
-
-void ToolbarActionsBar::TabOrderHelper::TabInsertedAt(
-    content::WebContents* web_contents,
-    int index,
-    bool foreground) {
-  if (foreground)
-    NotifyReorderActions();
-}
-
-void ToolbarActionsBar::TabOrderHelper::TabDetachedAt(
-    content::WebContents* web_contents,
-    int index) {
-  int tab_id = SessionTabHelper::IdForTab(web_contents);
-  for (auto& tabs : popped_out_in_tabs_)
-    tabs.second.erase(tab_id);
-  tabs_checked_for_pop_out_.erase(tab_id);
-}
-
-void ToolbarActionsBar::TabOrderHelper::ActiveTabChanged(
-    content::WebContents* old_contents,
-    content::WebContents* new_contents,
-    int index,
-    int reason) {
-  // When we do a bulk-refresh by switching tabs, we don't animate the
-  // difference. We only animate when it's a change driven by the action or the
-  // user.
-  base::AutoReset<bool> animation_reset(&toolbar_->suppress_animation_, true);
-  NotifyReorderActions();
-}
-
-void ToolbarActionsBar::TabOrderHelper::TabStripModelDeleted() {
-  tab_strip_observer_.RemoveAll();
-}
-
-void ToolbarActionsBar::TabOrderHelper::NotifyReorderActions() {
-  // Reorder the reference toolbar first (since we use its actions in
-  // GetActionOrder()).
-  toolbar_->ReorderActions();
-  if (overflow_bar_)
-    overflow_bar_->ReorderActions();
-}
-
 ToolbarActionsBar::PlatformSettings::PlatformSettings(bool in_overflow_mode)
     : left_padding(in_overflow_mode ? kOverflowLeftPadding : kLeftPadding),
       right_padding(in_overflow_mode ? kOverflowRightPadding : kRightPadding),
@@ -425,13 +127,6 @@
       weak_ptr_factory_(this) {
   if (model_)  // |model_| can be null in unittests.
     model_observer_.Add(model_);
-
-  if (pop_out_actions_to_run_) {
-    if (in_overflow_mode())
-      main_bar_->tab_order_helper_->notify_overflow_bar(this, true);
-    else
-      tab_order_helper_.reset(new TabOrderHelper(this, browser_, model_));
-  }
 }
 
 ToolbarActionsBar::~ToolbarActionsBar() {
@@ -439,8 +134,6 @@
   // the order of deletion between the views and the ToolbarActionsBar.
   DCHECK(toolbar_actions_.empty()) <<
       "Must call DeleteActions() before destruction.";
-  if (in_overflow_mode() && pop_out_actions_to_run_)
-    main_bar_->tab_order_helper_->notify_overflow_bar(this, false);
 }
 
 // static
@@ -536,16 +229,9 @@
   if (!model_)
     return 0u;
 
-  size_t extra_icons = 0;
-  if (tab_order_helper_) {
-    extra_icons = tab_order_helper_->GetExtraIconCount(
-        SessionTabHelper::IdForTab(
-            browser_->tab_strip_model()->GetActiveWebContents()));
-  }
-
   size_t visible_icons = in_overflow_mode() ?
       toolbar_actions_.size() - main_bar_->GetIconCount() :
-      model_->visible_icon_count() + extra_icons;
+      model_->visible_icon_count();
 
 #if DCHECK_IS_ON()
   // Good time for some sanity checks: We should never try to display more
@@ -684,13 +370,7 @@
   // Save off the desired number of visible icons. We do this now instead of
   // at the end of the animation so that even if the browser is shut down
   // while animating, the right value will be restored on next run.
-  if (tab_order_helper_) {
-    tab_order_helper_->HandleResize(
-        resized_count,
-        SessionTabHelper::IdForTab(GetCurrentWebContents()));
-  } else {
-    model_->SetVisibleIconCount(resized_count);
-  }
+  model_->SetVisibleIconCount(resized_count);
 }
 
 void ToolbarActionsBar::OnDragDrop(int dragged_index,
@@ -702,23 +382,15 @@
     return;
   }
 
-  if (tab_order_helper_) {
-    tab_order_helper_->HandleDragDrop(
-        dragged_index,
-        dropped_index,
-        drag_type,
-        SessionTabHelper::IdForTab(GetCurrentWebContents()));
-  } else {
-    int delta = 0;
-    if (drag_type == DRAG_TO_OVERFLOW)
-      delta = -1;
-    else if (drag_type == DRAG_TO_MAIN)
-      delta = 1;
-    model_->MoveExtensionIcon(toolbar_actions_[dragged_index]->GetId(),
-                              dropped_index);
-    if (delta)
-      model_->SetVisibleIconCount(model_->visible_icon_count() + delta);
-  }
+  int delta = 0;
+  if (drag_type == DRAG_TO_OVERFLOW)
+    delta = -1;
+  else if (drag_type == DRAG_TO_MAIN)
+    delta = 1;
+  model_->MoveExtensionIcon(toolbar_actions_[dragged_index]->GetId(),
+                            dropped_index);
+  if (delta)
+    model_->SetVisibleIconCount(model_->visible_icon_count() + delta);
 }
 
 void ToolbarActionsBar::MaybeShowExtensionBubble() {
@@ -776,8 +448,6 @@
   scoped_ptr<ToolbarActionViewController> removed_action(*iter);
   toolbar_actions_.weak_erase(iter);
   delegate_->RemoveViewForAction(removed_action.get());
-  if (tab_order_helper_)
-    tab_order_helper_->ActionRemoved(removed_action.get());
   removed_action.reset();
 
   // If the extension is being upgraded we don't want the bar to shrink
@@ -820,18 +490,9 @@
   // There might not be a view in cases where we are highlighting or if we
   // haven't fully initialized the actions.
   if (action) {
-    content::WebContents* web_contents = GetCurrentWebContents();
     action->UpdateState();
-
-    if (tab_order_helper_) {
-      tab_order_helper_->SetActionWantsToRun(
-          action,
-          SessionTabHelper::IdForTab(web_contents),
-          action->WantsToRun(web_contents));
-    }
+    SetOverflowedActionWantsToRun();
   }
-
-  SetOverflowedActionWantsToRun();
 }
 
 bool ToolbarActionsBar::ShowExtensionActionPopup(
@@ -910,21 +571,6 @@
   };
   SortContainer(&toolbar_actions_.get(), model_->toolbar_items(), compare);
 
-  // Only adjust the order if the model isn't highlighting a particular
-  // subset (and the specialized tab order is enabled).
-  TabOrderHelper* tab_order_helper = in_overflow_mode() ?
-      main_bar_->tab_order_helper_.get() : tab_order_helper_.get();
-  if (!model_->is_highlighting() && tab_order_helper) {
-    WeakToolbarActions new_order =
-        tab_order_helper->GetActionOrder(GetCurrentWebContents());
-    auto compare = [](ToolbarActionViewController* const& first,
-                      ToolbarActionViewController* const& second) {
-      return first->GetId() == second->GetId();
-    };
-    SortContainer(
-        &toolbar_actions_.get(), new_order, compare);
-  }
-
   // Our visible browser actions may have changed - re-Layout() and check the
   // size (if we aren't suppressing the layout).
   if (!suppress_layout_) {
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar.h b/chrome/browser/ui/toolbar/toolbar_actions_bar.h
index e5d974b..6cdba0d 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_bar.h
+++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.h
@@ -137,11 +137,6 @@
 
   ToolbarActionsBarDelegate* delegate_for_test() { return delegate_; }
 
-  static void set_pop_out_actions_to_run_for_testing(
-      bool pop_out_actions_to_run) {
-    pop_out_actions_to_run_ = pop_out_actions_to_run;
-  }
-
   static void set_send_overflowed_action_changes_for_testing(
       bool send_overflowed_action_changes) {
     send_overflowed_action_changes_ = send_overflowed_action_changes;
@@ -153,8 +148,6 @@
   static bool disable_animations_for_testing_;
 
  private:
-  class TabOrderHelper;
-
   using ToolbarActions = ScopedVector<ToolbarActionViewController>;
 
   // ExtensionToolbarModel::Observer:
@@ -215,10 +208,6 @@
   // The toolbar actions.
   ToolbarActions toolbar_actions_;
 
-  // The TabOrderHelper that manages popping out actions that want to act.
-  // This is only non-null if |pop_out_actions_to_run| is true.
-  scoped_ptr<TabOrderHelper> tab_order_helper_;
-
   ScopedObserver<extensions::ExtensionToolbarModel,
                  extensions::ExtensionToolbarModel::Observer> model_observer_;
 
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
index 2d21db0..e583536 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
@@ -480,303 +480,3 @@
   EXPECT_TRUE(
       prefs->GetBoolean(prefs::kToolbarIconSurfacingBubbleAcknowledged));
 }
-
-class ToolbarActionsBarPopOutUnitTest
-    : public ToolbarActionsBarRedesignUnitTest {
- public:
-  ToolbarActionsBarPopOutUnitTest() {}
-
- protected:
-  void SetUp() override {
-    ToolbarActionsBar::set_pop_out_actions_to_run_for_testing(true);
-    ToolbarActionsBarUnitTest::SetUp();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ToolbarActionsBarPopOutUnitTest);
-};
-
-// Test that toolbar actions can pop themselves out of overflow if they want to
-// act on a given tab.
-TEST_F(ToolbarActionsBarPopOutUnitTest, ActionsPopOutToAct) {
-  // Add three extensions to the profile; this is the easiest way to have
-  // toolbar actions.
-  const char kBrowserAction[] = "browser action";
-  const char kPageAction[] = "page action";
-  const char kSynthetic[] = "synthetic";  // This has a generated action icon.
-
-  CreateAndAddExtension(kBrowserAction,
-                        extensions::extension_action_test_util::BROWSER_ACTION);
-  scoped_refptr<const extensions::Extension> page_action =
-      CreateAndAddExtension(
-          kPageAction, extensions::extension_action_test_util::PAGE_ACTION);
-  CreateAndAddExtension(kSynthetic,
-                        extensions::extension_action_test_util::NO_ACTION);
-
-  {
-    // We should start in the order of "browser action", "page action",
-    // "synthetic" and have all actions visible.
-    const char* expected_names[] = { kBrowserAction, kPageAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 3u));
-  }
-
-  // Shrink the bar to only show one action, and move the page action to the
-  // end.
-  toolbar_model()->SetVisibleIconCount(1);
-  toolbar_model()->MoveExtensionIcon(page_action->id(), 2u);
-
-  {
-    // Quickly verify that the move/visible count worked.
-    const char* expected_names[] = { kBrowserAction, kSynthetic, kPageAction };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-  }
-
-  // Create two tabs.
-  AddTab(browser(), GURL("http://www.google.com/"));
-  AddTab(browser(), GURL("http://www.youtube.com/"));
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetWebContentsAt(0);
-
-  {
-    // First, check the order for the first tab. Since we haven't changed
-    // anything (i.e., no extensions want to act), this should be the same as we
-    // left it: "browser action", "synthetic", "page action", with only one
-    // visible.
-    ActivateTab(0);
-    const char* expected_names[] = { kBrowserAction, kSynthetic, kPageAction };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-  }
-
-  extensions::ExtensionActionManager* action_manager =
-      extensions::ExtensionActionManager::Get(profile());
-  ExtensionAction* action = action_manager->GetExtensionAction(*page_action);
-  ASSERT_TRUE(action);
-
-  {
-    // Make "page action" want to act.
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    // This should result in "page action" being popped out of the overflow
-    // menu.
-    // This has two visible effects:
-    // - page action should moved to the zero-index (left-most side of the bar).
-    // - The visible count should increase by one (so page action is visible).
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 2u));
-  }
-
-  {
-    // This should not have any effect on the second tab, which should still
-    // have the original order and visible count.
-    ActivateTab(1);
-    const char* expected_names[] = { kBrowserAction, kSynthetic, kPageAction };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-  }
-
- {
-    // Switching back to the first tab should mean that actions that want to run
-    // are re-popped out.
-    ActivateTab(0);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 2u));
-  }
-
-  {
-    // Now, set the action to be hidden again, and notify of the change.
-    SetActionWantsToRunOnTab(action, web_contents, false);
-    // The order and visible count should return to normal (the page action
-    // should move back to its original index in overflow).
-    const char* expected_names[] = { kBrowserAction, kSynthetic, kPageAction };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-  }
-
-  {
-    // Move page action to the second index and increase visible size to 2 (so
-    // it's naturally visible).
-    toolbar_model()->MoveExtensionIcon(page_action->id(), 1u);
-    toolbar_model()->SetVisibleIconCount(2u);
-    const char* expected_names[] = { kBrowserAction, kPageAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 2u));
-    // Make the now-visible page action want to act.
-    // Since the action is already visible, this should have no effect - the
-    // order and visible count should remain unchanged.
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 2u));
-  }
-
-  {
-    // We should still be able to increase the size of the model, and to move
-    // the page action.
-    toolbar_model()->SetVisibleIconCount(3);
-    toolbar_model()->MoveExtensionIcon(page_action->id(), 0u);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 3u));
-    // If we moved the page action, the move should remain in effect even after
-    // the action no longer wants to act.
-    SetActionWantsToRunOnTab(action, web_contents, false);
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 3u));
-  }
-
-  {
-    // Test the edge case of having no icons visible.
-    toolbar_model()->SetVisibleIconCount(0);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 0u));
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-  }
-
-  // Reset the action, and create another page action extension.
-  SetActionWantsToRunOnTab(action, web_contents, false);
-  const char kPageAction2[] = "page action2";
-  scoped_refptr<const extensions::Extension> page_action2 =
-      CreateAndAddExtension(
-          kPageAction2, extensions::extension_action_test_util::PAGE_ACTION);
-  // The new extension was installed visible. Move it to the last index, and
-  // adjust the visible count.
-  toolbar_model()->MoveExtensionIcon(page_action2->id(), 3u);
-  toolbar_model()->SetVisibleIconCount(0);
-
-  {
-    // The second page action should be added to the end, and no icons should
-    // be visible.
-    const char* expected_names[] =
-        { kPageAction, kBrowserAction, kSynthetic, kPageAction2 };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 4u, 0u));
-  }
-
-  {
-    // Make both page actions want to run, with the second triggering first.
-    SetActionWantsToRunOnTab(
-        action_manager->GetExtensionAction(*page_action2), web_contents, true);
-    SetActionWantsToRunOnTab(action, web_contents, true);
-
-    // Even though the second page action triggered first, the order of actions
-    // wanting to run should respect the normal order of actions.
-    const char* expected_names[] =
-        { kPageAction, kPageAction2, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 4u, 2u));
-  }
-}
-
-TEST_F(ToolbarActionsBarPopOutUnitTest, AdjustingActionsThatWantToAct) {
-  // Add three extensions to the profile; this is the easiest way to have
-  // toolbar actions.
-  const char kBrowserAction[] = "browser action";
-  const char kPageAction[] = "page action";
-  const char kSynthetic[] = "synthetic";  // This has a generated action icon.
-
-  CreateAndAddExtension(kBrowserAction,
-                        extensions::extension_action_test_util::BROWSER_ACTION);
-  scoped_refptr<const extensions::Extension> page_action =
-      CreateAndAddExtension(
-          kPageAction, extensions::extension_action_test_util::PAGE_ACTION);
-  CreateAndAddExtension(kSynthetic,
-                        extensions::extension_action_test_util::NO_ACTION);
-
-  // Move the page action to the second index and reduce the visible count to 1
-  // so that the page action is hidden (and can pop out when it needs to act).
-  toolbar_model()->SetVisibleIconCount(1);
-  toolbar_model()->MoveExtensionIcon(page_action->id(), 1u);
-
-  // Create a tab.
-  AddTab(browser(), GURL("http://www.google.com/"));
-  AddTab(browser(), GURL("http://www.youtube.com/"));
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetWebContentsAt(0);
-
-  extensions::ExtensionActionManager* action_manager =
-      extensions::ExtensionActionManager::Get(profile());
-  ExtensionAction* action = action_manager->GetExtensionAction(*page_action);
-  ASSERT_TRUE(action);
-
-  {
-    // Make the page action pop out, which causes the visible count for tab to
-    // become 2, with the page action at the front.
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 2u));
-  }
-
-  {
-    // Shrink the toolbar count. To the user, this is hiding "browser action",
-    // so that's the effect it should have (browser action should be hidden from
-    // all windows).
-    toolbar_actions_bar()->OnResizeComplete(
-        toolbar_actions_bar()->IconCountToWidth(1u));
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-    // Once the action no longer wants to run, "page action" should go back to
-    // its normal spot, and visible count goes to zero.
-    SetActionWantsToRunOnTab(action, web_contents, false);
-    const char* expected_names2[] = { kBrowserAction, kPageAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names2, 3u, 0u));
-  }
-
-  {
-    // Make the action want to run again - it should pop out, and be the only
-    // action visible on the tab.
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 1u));
-    // Set the visible icon count for that tab to 2. This uncovers one action,
-    // so the base visible count should be 1, and the order should still be
-    // "page action", "browser action", "synthetic".
-    toolbar_actions_bar()->OnResizeComplete(
-        toolbar_actions_bar()->IconCountToWidth(2u));
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 2u));
-    // Next, grow the item order to 3 for the tab. This uncovers the "synthetic"
-    // extension. This is interesting, because for the same action to be
-    // uncovered on other tabs, the underlying order (which was previously
-    // "browser action", "page action", "synthetic") has to chage (to be
-    // "browser action", "synthetic", "page action"). If we don't make this
-    // change, we uncover "synthetic" here, but in other windows, "page action"
-    // is uncovered (which is weird). Ensure that the change that was visible
-    // to the user (uncovering "synthetic") is the one that happens to the
-    // underlying model.
-    toolbar_actions_bar()->OnResizeComplete(
-        toolbar_actions_bar()->IconCountToWidth(3u));
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 3u));
-    // So when "page action" finishes, it should go back to overflow, leaving
-    // the other two visible.
-    SetActionWantsToRunOnTab(action, web_contents, false);
-    const char* expected_names2[] = { kBrowserAction, kSynthetic, kPageAction };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names2, 3u, 2u));
-  }
-
-  {
-    // Next, test that moving an action that was popped out for overflow pins
-    // the action to the new spot. Since the action originated in overflow, this
-    // also causes the base visible count to increase.
-    // Set the action to be visible.
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 3u));
-    // Move the popped out "page action" extension to the first index.
-    toolbar_actions_bar()->OnDragDrop(0, 1, ToolbarActionsBar::DRAG_TO_SAME);
-    const char* expected_names2[] = { kBrowserAction, kPageAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names2, 3u, 3u));
-    // Since this pinned "page action", the order stays the same after the run.
-    SetActionWantsToRunOnTab(action, web_contents, false);
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names2, 3u, 3u));
-  }
-
-  {
-    // Move "page action" back to overflow.
-    toolbar_actions_bar()->OnDragDrop(1, 2, ToolbarActionsBar::DRAG_TO_SAME);
-    toolbar_actions_bar()->OnResizeComplete(
-        toolbar_actions_bar()->IconCountToWidth(2u));
-
-    // Test moving a popped out extension to the overflow menu; this should have
-    // no effect on the base visible count.
-    SetActionWantsToRunOnTab(action, web_contents, true);
-    const char* expected_names[] = { kPageAction, kBrowserAction, kSynthetic };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names, 3u, 3u));
-    // Move "page action" to the overflow menu.
-    toolbar_actions_bar()->OnDragDrop(
-        0, 2, ToolbarActionsBar::DRAG_TO_OVERFLOW);
-    const char* expected_names2[] = { kBrowserAction, kSynthetic, kPageAction };
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names2, 3u, 2u));
-    SetActionWantsToRunOnTab(action, web_contents, false);
-    EXPECT_TRUE(VerifyToolbarOrder(expected_names2, 3u, 2u));
-  }
-}
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model.cc b/chrome/browser/ui/toolbar/wrench_menu_model.cc
index e6a923d..9f27c2e4 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model.cc
+++ b/chrome/browser/ui/toolbar/wrench_menu_model.cc
@@ -96,6 +96,42 @@
   }
 }
 
+#if defined(OS_WIN)
+bool GetRestartMenuItemIfRequired(const chrome::HostDesktopType& desktop_type,
+                                  int* command_id,
+                                  int* string_id) {
+  if (base::win::GetVersion() == base::win::VERSION_WIN8 ||
+      base::win::GetVersion() == base::win::VERSION_WIN8_1) {
+    if (desktop_type != chrome::HOST_DESKTOP_TYPE_ASH) {
+      *command_id = IDC_WIN8_METRO_RESTART;
+      *string_id = IDS_WIN8_METRO_RESTART;
+    } else {
+      *command_id = IDC_WIN_DESKTOP_RESTART;
+      *string_id = IDS_WIN_DESKTOP_RESTART;
+    }
+    return true;
+  }
+
+  // Windows 7 ASH mode is only supported in DEBUG for now.
+#if !defined(NDEBUG)
+  // Windows 8 can support ASH mode using WARP, but Windows 7 requires a working
+  // GPU compositor.
+  if (base::win::GetVersion() == base::win::VERSION_WIN7 &&
+      content::GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) {
+    if (desktop_type != chrome::HOST_DESKTOP_TYPE_ASH) {
+      *command_id = IDC_WIN_CHROMEOS_RESTART;
+      *string_id = IDS_WIN_CHROMEOS_RESTART;
+    } else {
+      *command_id = IDC_WIN_DESKTOP_RESTART;
+      *string_id = IDS_WIN_DESKTOP_RESTART;
+    }
+    return true;
+  }
+#endif
+  return false;
+}
+#endif
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -926,30 +962,13 @@
 #endif
 
 #if defined(OS_WIN)
-  base::win::Version min_version_for_ash_mode = base::win::VERSION_WIN8;
-  // Windows 7 ASH mode is only supported in DEBUG for now.
-#if !defined(NDEBUG)
-  min_version_for_ash_mode = base::win::VERSION_WIN7;
-#endif
-  // Windows 8 can support ASH mode using WARP, but Windows 7 requires a working
-  // GPU compositor.
-  if ((base::win::GetVersion() >= min_version_for_ash_mode &&
-      content::GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) ||
-      (base::win::GetVersion() >= base::win::VERSION_WIN8)) {
-    if (browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) {
-      // ASH/Metro mode, add the 'Relaunch Chrome in desktop mode'.
-      AddSeparator(ui::NORMAL_SEPARATOR);
-      AddItemWithStringId(IDC_WIN_DESKTOP_RESTART, IDS_WIN_DESKTOP_RESTART);
-    } else {
-      // In Windows 8 desktop, add the 'Relaunch Chrome in Windows 8 mode'.
-      // In Windows 7 desktop, add the 'Relaunch Chrome in Windows ASH mode'
-      AddSeparator(ui::NORMAL_SEPARATOR);
-      if (base::win::GetVersion() == base::win::VERSION_WIN8 ||
-          base::win::GetVersion() == base::win::VERSION_WIN8_1)
-        AddItemWithStringId(IDC_WIN8_METRO_RESTART, IDS_WIN8_METRO_RESTART);
-      else
-        AddItemWithStringId(IDC_WIN_CHROMEOS_RESTART, IDS_WIN_CHROMEOS_RESTART);
-    }
+  int command_id = IDC_WIN_DESKTOP_RESTART;
+  int string_id = IDS_WIN_DESKTOP_RESTART;
+  if (GetRestartMenuItemIfRequired(browser_->host_desktop_type(),
+                                   &command_id,
+                                   &string_id)) {
+    AddSeparator(ui::NORMAL_SEPARATOR);
+    AddItemWithStringId(command_id, string_id);
   }
 #endif
 
diff --git a/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc
new file mode 100644
index 0000000..98be8215
--- /dev/null
+++ b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h"
+
+#include "ui/aura/window.h"
+#include "ui/base/base_window.h"
+
+AppWindowEasyResizeWindowTargeter::AppWindowEasyResizeWindowTargeter(
+    aura::Window* aura_window,
+    const gfx::Insets& insets,
+    ui::BaseWindow* native_app_window)
+    : wm::EasyResizeWindowTargeter(aura_window, insets, insets),
+      native_app_window_(native_app_window) {
+}
+
+AppWindowEasyResizeWindowTargeter::~AppWindowEasyResizeWindowTargeter() {
+}
+
+bool AppWindowEasyResizeWindowTargeter::EventLocationInsideBounds(
+    ui::EventTarget* target,
+    const ui::LocatedEvent& event) const {
+  aura::Window* window = static_cast<aura::Window*>(target);
+  // EasyResizeWindowTargeter intercepts events landing at the edges of the
+  // window. Since maximized and fullscreen windows can't be resized anyway,
+  // skip EasyResizeWindowTargeter so that the web contents receive all mouse
+  // events.
+  if (native_app_window_->IsMaximized() || native_app_window_->IsFullscreen())
+    return WindowTargeter::EventLocationInsideBounds(window, event);
+  else
+    return EasyResizeWindowTargeter::EventLocationInsideBounds(window, event);
+}
diff --git a/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h
new file mode 100644
index 0000000..69b08d6
--- /dev/null
+++ b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_APPS_APP_WINDOW_EASY_RESIZE_WINDOW_TARGETER_H_
+#define CHROME_BROWSER_UI_VIEWS_APPS_APP_WINDOW_EASY_RESIZE_WINDOW_TARGETER_H_
+
+#include "ui/wm/core/easy_resize_window_targeter.h"
+
+namespace ui {
+class BaseWindow;
+}
+
+// An EasyResizeEventTargeter whose behavior depends on the state of the app
+// window.
+class AppWindowEasyResizeWindowTargeter : public wm::EasyResizeWindowTargeter {
+ public:
+  // |aura_window| is the owner of this targeter.
+  AppWindowEasyResizeWindowTargeter(aura::Window* aura_window,
+                                    const gfx::Insets& insets,
+                                    ui::BaseWindow* native_app_window);
+
+  ~AppWindowEasyResizeWindowTargeter() override;
+
+ protected:
+  // ui::EventTargeter:
+  bool EventLocationInsideBounds(ui::EventTarget* target,
+                                 const ui::LocatedEvent& event) const override;
+
+ private:
+  ui::BaseWindow* native_app_window_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppWindowEasyResizeWindowTargeter);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_APPS_APP_WINDOW_EASY_RESIZE_WINDOW_TARGETER_H_
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc
index 8535c131..6fcaf86 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h"
 #include "chrome/browser/ui/host_desktop.h"
+#include "chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h"
 #include "chrome/browser/ui/views/apps/shaped_app_window_targeter.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "ui/aura/client/aura_constants.h"
@@ -28,7 +29,6 @@
 #include "ui/gfx/image/image_skia.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/widget/widget.h"
-#include "ui/wm/core/easy_resize_window_targeter.h"
 
 #if defined(OS_CHROMEOS)
 #include "ash/shell_window_ids.h"
@@ -180,11 +180,11 @@
     int resize_inside = frame->resize_inside_bounds_size();
     gfx::Insets inset(resize_inside, resize_inside, resize_inside,
                       resize_inside);
-    // Add the EasyResizeWindowTargeter on the window, not its root window. The
-    // root window does not have a delegate, which is needed to handle the event
-    // in Linux.
+    // Add the AppWindowEasyResizeWindowTargeter on the window, not its root
+    // window. The root window does not have a delegate, which is needed to
+    // handle the event in Linux.
     window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
-        new wm::EasyResizeWindowTargeter(window, inset, inset)));
+        new AppWindowEasyResizeWindowTargeter(window, inset, this)));
   }
 #endif
 
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
index e49e0b8..984aee66 100644
--- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
+++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -328,7 +328,8 @@
     const gfx::Animation* animation) {
   uint8_t alpha = static_cast<uint8_t>(animation->CurrentValueBetween(0, 255));
   progress_overlay_->SetAlpha(alpha);
-  storage_row_->SetAlpha(255 - alpha);
+  if (storage_row_)
+    storage_row_->SetAlpha(255 - alpha);
 }
 
 void CardUnmaskPromptViews::InitIfNecessary() {
@@ -433,7 +434,7 @@
   progress_overlay_->SetVisible(false);
   AddChildView(progress_overlay_);
 
-  progress_throbber_ = new views::CheckmarkThrobber();
+  progress_throbber_ = new views::MaterialThrobber();
   progress_overlay_->AddChildView(progress_throbber_);
 
   progress_label_ = new views::Label(l10n_util::GetStringUTF16(
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h
index 6318284..b272480 100644
--- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h
+++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h
@@ -17,7 +17,7 @@
 class ImageView;
 class Label;
 class Checkbox;
-class CheckmarkThrobber;
+class MaterialThrobber;
 }
 
 namespace autofill {
@@ -135,7 +135,7 @@
   views::Checkbox* storage_checkbox_;
 
   FadeOutView* progress_overlay_;
-  views::CheckmarkThrobber* progress_throbber_;
+  views::MaterialThrobber* progress_throbber_;
   views::Label* progress_label_;
 
   gfx::SlideAnimation overlay_animation_;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index 98a9bc6..9808dc1 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -68,7 +68,7 @@
                                     Profile* profile,
                                     const GURL& url,
                                     bool newly_bookmarked) {
-  if (IsShowing())
+  if (bookmark_bubble_)
     return;
 
   bookmark_bubble_ = new BookmarkBubbleView(anchor_view,
@@ -86,13 +86,8 @@
     bookmark_bubble_->observer_->OnBookmarkBubbleShown(url);
 }
 
-// static
-bool BookmarkBubbleView::IsShowing() {
-  return bookmark_bubble_ != NULL;
-}
-
 void BookmarkBubbleView::Hide() {
-  if (IsShowing())
+  if (bookmark_bubble_)
     bookmark_bubble_->GetWidget()->Close();
 }
 
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
index 08e46d9..51892ab 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
@@ -40,10 +40,10 @@
                          const GURL& url,
                          bool newly_bookmarked);
 
-  static bool IsShowing();
-
   static void Hide();
 
+  static BookmarkBubbleView* bookmark_bubble() { return bookmark_bubble_; }
+
   ~BookmarkBubbleView() override;
 
   // views::WidgetDelegate:
diff --git a/chrome/browser/ui/views/chrome_constrained_window_views_client.cc b/chrome/browser/ui/views/chrome_constrained_window_views_client.cc
index 767d96d9..2143f22c 100644
--- a/chrome/browser/ui/views/chrome_constrained_window_views_client.cc
+++ b/chrome/browser/ui/views/chrome_constrained_window_views_client.cc
@@ -21,17 +21,8 @@
   // ConstrainedWindowViewsClient:
   content::WebContents* GetEmbedderWebContents(
       content::WebContents* initiator_web_contents) override {
-    // |initiator_web_contents| may be embedded within a chain of nested
-    // GuestViews. If it is, follow the chain of embedders to the outermost
-    // WebContents and return it.
-    while (extensions::GuestViewBase* guest_view =
-               extensions::GuestViewBase::FromWebContents(
-                   initiator_web_contents)) {
-      if (!guest_view->embedder_web_contents())
-        break;
-      initiator_web_contents = guest_view->embedder_web_contents();
-    }
-    return initiator_web_contents;
+    return extensions::GuestViewBase::GetTopLevelWebContents(
+        initiator_web_contents);
   }
   web_modal::ModalDialogHost* GetModalDialogHost(
       gfx::NativeWindow parent) override {
diff --git a/chrome/browser/ui/views/extensions/bookmark_override_browsertest.cc b/chrome/browser/ui/views/extensions/bookmark_override_browsertest.cc
index c61b1e5..aa3f4ae 100644
--- a/chrome/browser/ui/views/extensions/bookmark_override_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/bookmark_override_browsertest.cc
@@ -58,11 +58,11 @@
       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
 
   // Verify that clicking once shows the bookmark bubble.
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
   star_view->OnMousePressed(pressed_event);
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
   star_view->OnMouseReleased(released_event);
-  EXPECT_TRUE(BookmarkBubbleView::IsShowing());
+  EXPECT_TRUE(BookmarkBubbleView::bookmark_bubble());
 }
 
 // Test that invoking the IDC_BOOKMARK_PAGE command (as done by the wrench menu)
@@ -84,7 +84,7 @@
 
   // Check that the BookmarkBubbleView is shown when executing
   // IDC_BOOKMARK_PAGE.
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
   chrome::ExecuteCommand(browser(), IDC_BOOKMARK_PAGE);
-  EXPECT_TRUE(BookmarkBubbleView::IsShowing());
+  EXPECT_TRUE(BookmarkBubbleView::bookmark_bubble());
 }
diff --git a/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
index 771f41d2..99de121 100644
--- a/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
@@ -2,20 +2,20 @@
 // 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 "chrome/browser/extensions/extension_action_test_util.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/ui/extensions/extension_message_bubble_factory.h"
-#include "chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h"
+#include "chrome/browser/ui/extensions/extension_message_bubble_browsertest.h"
 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.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/browser/ui/views/toolbar/wrench_toolbar_button.h"
-#include "extensions/common/feature_switch.h"
 
 namespace {
 
+// Returns the ToolbarView for the given |browser|.
+ToolbarView* GetToolbarViewForBrowser(Browser* browser) {
+  return BrowserView::GetBrowserViewForBrowser(browser)->toolbar();
+}
+
 // Checks that the |bubble| is using the |expected_reference_view|, and is in
 // approximately the correct position.
 void CheckBubbleAndReferenceView(views::BubbleDelegateView* bubble,
@@ -47,100 +47,61 @@
 }  // namespace
 
 class ExtensionMessageBubbleViewBrowserTest
-    : public BrowserActionsBarBrowserTest {
+    : public ExtensionMessageBubbleBrowserTest {
  protected:
   ExtensionMessageBubbleViewBrowserTest() {}
   ~ExtensionMessageBubbleViewBrowserTest() override {}
 
-  void SetUpCommandLine(base::CommandLine* command_line) override;
-
  private:
-  scoped_ptr<extensions::FeatureSwitch::ScopedOverride>
-      dev_mode_bubble_override_;
+  // ExtensionMessageBubbleBrowserTest:
+  void CheckBubble(Browser* browser, AnchorPosition anchor) override;
+  void CloseBubble(Browser* browser) override;
 
   DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleViewBrowserTest);
 };
 
-void ExtensionMessageBubbleViewBrowserTest::SetUpCommandLine(
-    base::CommandLine* command_line) {
-  BrowserActionsBarBrowserTest::SetUpCommandLine(command_line);
-  // The dev mode warning bubble is an easy one to trigger, so we use that for
-  // our testing purposes.
-  dev_mode_bubble_override_.reset(
-      new extensions::FeatureSwitch::ScopedOverride(
-          extensions::FeatureSwitch::force_dev_mode_highlighting(),
-          true));
-  ExtensionMessageBubbleFactory::set_enabled_for_tests(true);
+void ExtensionMessageBubbleViewBrowserTest::CheckBubble(Browser* browser,
+                                                        AnchorPosition anchor) {
+  ToolbarView* toolbar_view = GetToolbarViewForBrowser(browser);
+  BrowserActionsContainer* container = toolbar_view->browser_actions();
+  views::BubbleDelegateView* bubble = container->active_bubble();
+  views::View* anchor_view = nullptr;
+  switch (anchor) {
+    case ANCHOR_BROWSER_ACTION:
+      anchor_view = container->GetToolbarActionViewAt(0);
+      break;
+    case ANCHOR_WRENCH_MENU:
+      anchor_view = toolbar_view->app_menu();
+      break;
+  }
+  CheckBubbleAndReferenceView(bubble, anchor_view);
 }
 
-// Tests that an extension bubble will be anchored to the wrench menu when there
-// aren't any extensions with actions.
-// This also tests that the crashes in crbug.com/476426 are fixed.
-IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
-                       ExtensionBubbleAnchoredToWrenchMenu) {
-  scoped_refptr<const extensions::Extension> action_extension =
-      extensions::extension_action_test_util::CreateActionExtension(
-          "action_extension",
-          extensions::extension_action_test_util::BROWSER_ACTION,
-          extensions::Manifest::UNPACKED);
-  extension_service()->AddExtension(action_extension.get());
-
-  Browser* second_browser = new Browser(
-      Browser::CreateParams(profile(), browser()->host_desktop_type()));
-  base::RunLoop().RunUntilIdle();
-
-  BrowserActionsContainer* second_container =
-      BrowserView::GetBrowserViewForBrowser(second_browser)->toolbar()->
-          browser_actions();
-  views::BubbleDelegateView* bubble = second_container->active_bubble();
-  CheckBubbleAndReferenceView(bubble,
-                              second_container->GetToolbarActionViewAt(0));
-
+void ExtensionMessageBubbleViewBrowserTest::CloseBubble(Browser* browser) {
+  BrowserActionsContainer* container =
+      GetToolbarViewForBrowser(browser)->browser_actions();
+  views::BubbleDelegateView* bubble = container->active_bubble();
+  ASSERT_TRUE(bubble);
   bubble->GetWidget()->Close();
-  EXPECT_EQ(nullptr, second_container->active_bubble());
+  EXPECT_EQ(nullptr, container->active_bubble());
 }
 
-// Tests that an extension bubble will be anchored to an extension action when
-// there are extensions with actions.
 IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
                        ExtensionBubbleAnchoredToExtensionAction) {
-  scoped_refptr<const extensions::Extension> no_action_extension =
-      extensions::extension_action_test_util::CreateActionExtension(
-          "action_extension",
-          extensions::extension_action_test_util::NO_ACTION,
-          extensions::Manifest::UNPACKED);
-  extension_service()->AddExtension(no_action_extension.get());
-
-  Browser* second_browser = new Browser(
-      Browser::CreateParams(profile(), browser()->host_desktop_type()));
-  ASSERT_TRUE(second_browser);
-  base::RunLoop().RunUntilIdle();
-
-  ToolbarView* toolbar =
-      BrowserView::GetBrowserViewForBrowser(second_browser)->toolbar();
-  BrowserActionsContainer* second_container = toolbar->browser_actions();
-  views::BubbleDelegateView* bubble = second_container->active_bubble();
-  CheckBubbleAndReferenceView(bubble, toolbar->app_menu());
-
-  bubble->GetWidget()->Close();
-  EXPECT_EQ(nullptr, second_container->active_bubble());
+  TestBubbleAnchoredToExtensionAction();
 }
 
-// Tests that the extension bubble will show on startup.
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
+                       ExtensionBubbleAnchoredToWrenchMenu) {
+  TestBubbleAnchoredToWrenchMenu();
+}
+
 IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
                        PRE_ExtensionBubbleShowsOnStartup) {
-  LoadExtension(test_data_dir_.AppendASCII("good_unpacked"));
+  PreBubbleShowsOnStartup();
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
                        ExtensionBubbleShowsOnStartup) {
-  base::RunLoop().RunUntilIdle();
-  BrowserActionsContainer* container =
-      BrowserView::GetBrowserViewForBrowser(browser())->toolbar()->
-          browser_actions();
-  views::BubbleDelegateView* bubble = container->active_bubble();
-  CheckBubbleAndReferenceView(bubble, container->GetToolbarActionViewAt(0));
-
-  bubble->GetWidget()->Close();
-  EXPECT_EQ(nullptr, container->active_bubble());
+  TestBubbleShowsOnStartup();
 }
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
index 5868fa9..c5a6fb1 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -581,12 +581,21 @@
     // This will reset the icon which we set in the throbber code.
     // WM_SETICON with null icon restores the icon for title bar but not
     // for taskbar. See http://crbug.com/29996
-    SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
-                static_cast<WPARAM>(ICON_SMALL),
-                reinterpret_cast<LPARAM>(small_icon));
-    SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
-                static_cast<WPARAM>(ICON_BIG),
-                reinterpret_cast<LPARAM>(big_icon));
+    HICON previous_small_icon = reinterpret_cast<HICON>(
+        SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
+                    static_cast<WPARAM>(ICON_SMALL),
+                    reinterpret_cast<LPARAM>(small_icon)));
+
+    HICON previous_big_icon = reinterpret_cast<HICON>(
+        SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
+                    static_cast<WPARAM>(ICON_BIG),
+                    reinterpret_cast<LPARAM>(big_icon)));
+
+    if (previous_small_icon)
+      ::DestroyIcon(previous_small_icon);
+
+    if (previous_big_icon)
+      ::DestroyIcon(previous_big_icon);
   }
 }
 
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 d74f329..8d49ced 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/command_updater.h"
 #include "ui/accessibility/ax_view_state.h"
 #include "ui/events/event.h"
+#include "ui/views/bubble/bubble_delegate.h"
 
 BubbleIconView::BubbleIconView(CommandUpdater* command_updater, int command_id)
     : command_updater_(command_updater),
@@ -18,6 +19,12 @@
 BubbleIconView::~BubbleIconView() {
 }
 
+bool BubbleIconView::IsBubbleShowing() const {
+  // If the bubble is being destroyed, it's considered showing though it may be
+  // already invisible currently.
+  return GetBubble() != NULL;
+}
+
 void BubbleIconView::GetAccessibleState(ui::AXViewState* state) {
   views::ImageView::GetAccessibleState(state);
   state->role = ui::AX_ROLE_BUTTON;
@@ -74,3 +81,9 @@
   if (command_updater_)
     command_updater_->ExecuteCommand(command_id_);
 }
+
+void BubbleIconView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
+  views::BubbleDelegateView* bubble = GetBubble();
+  if (bubble)
+    bubble->OnAnchorBoundsChanged();
+}
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 504cf870..94e6143 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.h
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.h
@@ -9,6 +9,10 @@
 
 class CommandUpdater;
 
+namespace views {
+class BubbleDelegateView;
+}
+
 // Represents an icon on the omnibox that shows a bubble when clicked.
 class BubbleIconView : public views::ImageView {
  protected:
@@ -22,7 +26,7 @@
   ~BubbleIconView() override;
 
   // Returns true if a related bubble is showing.
-  virtual bool IsBubbleShowing() const = 0;
+  bool IsBubbleShowing() const;
 
   // Invoked prior to executing the command.
   virtual void OnExecuting(ExecuteSource execute_source) = 0;
@@ -42,6 +46,12 @@
   // Calls OnExecuting and runs |command_id_| with a valid |command_updater_|.
   virtual void ExecuteCommand(ExecuteSource source);
 
+  // Returns the bubble instance for the icon.
+  virtual views::BubbleDelegateView* GetBubble() const = 0;
+
+  // views::View:
+  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
+
  private:
   // The CommandUpdater for the Browser object that owns the location bar.
   CommandUpdater* command_updater_;
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc
index 368119d..080d5255 100644
--- a/chrome/browser/ui/views/location_bar/star_view.cc
+++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -32,10 +32,6 @@
       on ? IDR_STAR_LIT : IDR_STAR));
 }
 
-bool StarView::IsBubbleShowing() const {
-  return BookmarkBubbleView::IsShowing();
-}
-
 void StarView::OnExecuting(
     BubbleIconView::ExecuteSource execute_source) {
   BookmarkEntryPoint entry_point = BOOKMARK_ENTRY_POINT_STAR_MOUSE;
@@ -63,3 +59,7 @@
     BubbleIconView::ExecuteCommand(source);
   }
 }
+
+views::BubbleDelegateView* StarView::GetBubble() const {
+  return BookmarkBubbleView::bookmark_bubble();
+}
diff --git a/chrome/browser/ui/views/location_bar/star_view.h b/chrome/browser/ui/views/location_bar/star_view.h
index 1b0e63c..57da0f2 100644
--- a/chrome/browser/ui/views/location_bar/star_view.h
+++ b/chrome/browser/ui/views/location_bar/star_view.h
@@ -21,9 +21,9 @@
 
  protected:
   // BubbleIconView:
-  bool IsBubbleShowing() const override;
   void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
   void ExecuteCommand(ExecuteSource source) override;
+  views::BubbleDelegateView* GetBubble() const override;
 
  private:
   Browser* browser_;
diff --git a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
index 717562ba..f5c620df 100644
--- a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
@@ -50,11 +50,11 @@
       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
 
   // Verify that clicking once shows the bookmark bubble.
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
   star_view->OnMousePressed(pressed_event);
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
   star_view->OnMouseReleased(released_event);
-  EXPECT_TRUE(BookmarkBubbleView::IsShowing());
+  EXPECT_TRUE(BookmarkBubbleView::bookmark_bubble());
 
   // Verify that clicking again doesn't reshow it.
   star_view->OnMousePressed(pressed_event);
@@ -62,9 +62,9 @@
   // the event processing.
   BookmarkBubbleView::Hide();
   base::MessageLoop::current()->RunUntilIdle();
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
   star_view->OnMouseReleased(released_event);
-  EXPECT_FALSE(BookmarkBubbleView::IsShowing());
+  EXPECT_FALSE(BookmarkBubbleView::bookmark_bubble());
 }
 
 #if defined(OS_WIN)
@@ -138,7 +138,7 @@
       runner->QuitClosure());
   runner->Run();
 
-  EXPECT_TRUE(BookmarkBubbleView::IsShowing());
+  EXPECT_TRUE(BookmarkBubbleView::bookmark_bubble());
 
   result = GetWindowRgnBox(child, &region_after);
   if (result == NULLREGION) {
diff --git a/chrome/browser/ui/views/location_bar/translate_icon_view.cc b/chrome/browser/ui/views/location_bar/translate_icon_view.cc
index 3a7add4..a73564f2 100644
--- a/chrome/browser/ui/views/location_bar/translate_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/translate_icon_view.cc
@@ -29,10 +29,10 @@
       on ? IDR_TRANSLATE_ACTIVE : IDR_TRANSLATE));
 }
 
-bool TranslateIconView::IsBubbleShowing() const {
-  return TranslateBubbleView::IsShowing();
+void TranslateIconView::OnExecuting(
+  BubbleIconView::ExecuteSource execute_source) {
 }
 
-void TranslateIconView::OnExecuting(
-    BubbleIconView::ExecuteSource execute_source) {
+views::BubbleDelegateView* TranslateIconView::GetBubble() const {
+  return TranslateBubbleView::GetCurrentBubble();
 }
diff --git a/chrome/browser/ui/views/location_bar/translate_icon_view.h b/chrome/browser/ui/views/location_bar/translate_icon_view.h
index 4ebafd3..bc57187 100644
--- a/chrome/browser/ui/views/location_bar/translate_icon_view.h
+++ b/chrome/browser/ui/views/location_bar/translate_icon_view.h
@@ -21,8 +21,8 @@
 
  protected:
   // BubbleIconView:
-  bool IsBubbleShowing() const override;
   void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
+  views::BubbleDelegateView* GetBubble() const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TranslateIconView);
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 eff898a..9308b6dc 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -101,14 +101,7 @@
 }
 
 // static
-bool ZoomBubbleView::IsShowing() {
-  // The bubble is considered showing while closing.
-  return zoom_bubble_ != NULL && (zoom_bubble_->GetWidget()->IsVisible() ||
-                                  zoom_bubble_->GetWidget()->IsClosed());
-}
-
-// static
-const ZoomBubbleView* ZoomBubbleView::GetZoomBubbleForTest() {
+ZoomBubbleView* ZoomBubbleView::GetZoomBubble() {
   return zoom_bubble_;
 }
 
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 b8039e6..83bb3f34 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -43,12 +43,9 @@
   // Closes the showing bubble (if one exists).
   static void CloseBubble();
 
-  // Whether the zoom bubble is currently showing.
-  static bool IsShowing();
-
   // Returns the zoom bubble if the zoom bubble is showing. Returns NULL
   // otherwise.
-  static const ZoomBubbleView* GetZoomBubbleForTest();
+  static ZoomBubbleView* GetZoomBubble();
 
  private:
   FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, ImmersiveFullscreen);
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 207c029..db9e61c6 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
@@ -27,8 +27,8 @@
 
   // The zoom bubble should be anchored when not in fullscreen.
   ZoomBubbleView::ShowBubble(web_contents, true);
-  ASSERT_TRUE(ZoomBubbleView::IsShowing());
-  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubbleForTest();
+  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
+  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble();
   EXPECT_TRUE(zoom_bubble->GetAnchorView());
 
   // Entering fullscreen should close the bubble. (We enter into tab fullscreen
@@ -45,13 +45,13 @@
     waiter->Wait();
   }
   ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
-  EXPECT_FALSE(ZoomBubbleView::IsShowing());
+  EXPECT_FALSE(ZoomBubbleView::GetZoomBubble());
 
   // The bubble should not be anchored when it is shown in non-immersive
   // fullscreen.
   ZoomBubbleView::ShowBubble(web_contents, true);
-  ASSERT_TRUE(ZoomBubbleView::IsShowing());
-  zoom_bubble = ZoomBubbleView::GetZoomBubbleForTest();
+  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
+  zoom_bubble = ZoomBubbleView::GetZoomBubble();
   EXPECT_FALSE(zoom_bubble->GetAnchorView());
 
   // Exit fullscreen before ending the test for the sake of sanity.
@@ -88,8 +88,8 @@
   // The zoom bubble should not be anchored when it is shown in immersive
   // fullscreen and the top-of-window views are not revealed.
   ZoomBubbleView::ShowBubble(web_contents, true);
-  ASSERT_TRUE(ZoomBubbleView::IsShowing());
-  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubbleForTest();
+  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
+  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble();
   EXPECT_FALSE(zoom_bubble->GetAnchorView());
 
   // An immersive reveal should hide the zoom bubble.
@@ -102,8 +102,8 @@
   // The zoom bubble should be anchored when it is shown in immersive fullscreen
   // and the top-of-window views are revealed.
   ZoomBubbleView::ShowBubble(web_contents, true);
-  ASSERT_TRUE(ZoomBubbleView::IsShowing());
-  zoom_bubble = ZoomBubbleView::GetZoomBubbleForTest();
+  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
+  zoom_bubble = ZoomBubbleView::GetZoomBubble();
   EXPECT_TRUE(zoom_bubble->GetAnchorView());
 
   // The top-of-window views should not hide till the zoom bubble hides. (It
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.cc b/chrome/browser/ui/views/location_bar/zoom_view.cc
index 6883537..a2f79cd 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_view.cc
@@ -47,10 +47,6 @@
   SetVisible(true);
 }
 
-bool ZoomView::IsBubbleShowing() const {
-  return ZoomBubbleView::IsShowing();
-}
-
 void ZoomView::OnExecuting(BubbleIconView::ExecuteSource source) {
   ZoomBubbleView::ShowBubble(location_bar_delegate_->GetWebContents(), false);
 }
@@ -59,3 +55,7 @@
   BubbleIconView::GetAccessibleState(state);
   state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_ZOOM);
 }
+
+views::BubbleDelegateView* ZoomView::GetBubble() const {
+  return ZoomBubbleView::GetZoomBubble();
+}
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.h b/chrome/browser/ui/views/location_bar/zoom_view.h
index 3ec315e..1224f8c 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_view.h
@@ -29,9 +29,9 @@
 
  protected:
   // BubbleIconView:
-  bool IsBubbleShowing() const override;
   void OnExecuting(BubbleIconView::ExecuteSource source) override;
   void GetAccessibleState(ui::AXViewState* state) override;
+  views::BubbleDelegateView* GetBubble() const override;
 
  private:
   // The delegate used to get the currently visible WebContents.
diff --git a/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc b/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc
index 9a867d2e..04e5cc5 100644
--- a/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc
+++ b/chrome/browser/ui/views/managed_full_screen_bubble_delegate_view.cc
@@ -41,7 +41,9 @@
 }
 
 void ManagedFullScreenBubbleDelegateView::Close() {
-  GetWidget()->Close();
+  views::Widget* widget = GetWidget();
+  if (!widget->IsClosed())
+    widget->Close();
 }
 
 void ManagedFullScreenBubbleDelegateView::AdjustForFullscreen(
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 283f9e4..5111e835 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -375,6 +375,9 @@
     separator_width_ = separator_rendertext_->GetContentWidth();
   }
 
+  contents->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0)));
+  if (description)
+    description->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0)));
   int contents_max_width, description_max_width;
   OmniboxPopupModel::ComputeMatchMaxWidths(
       contents->GetContentWidth(),
@@ -544,7 +547,8 @@
 
 int OmniboxResultView::GetMatchContentsWidth() const {
   InitContentsRenderTextIfNecessary();
-  return contents_rendertext_ ? contents_rendertext_->GetContentWidth() : 0;
+  contents_rendertext_->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0)));
+  return contents_rendertext_->GetContentWidth();
 }
 
 void OmniboxResultView::SetAnswerImage(const gfx::ImageSkia& image) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index a2b04d6..b50d8e6 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -416,10 +416,8 @@
   if (!views::FocusManager::IsTabTraversalKeyEvent(event))
     return false;
 
-  if (model()->is_keyword_hint() && !event.IsShiftDown()) {
-    model()->AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_TAB);
-    return true;
-  }
+  if (model()->is_keyword_hint() && !event.IsShiftDown())
+    return model()->AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_TAB);
 
   if (!model()->popup_model()->IsOpen())
     return false;
@@ -427,7 +425,7 @@
   if (event.IsShiftDown() &&
       (model()->popup_model()->selected_line_state() ==
           OmniboxPopupModel::KEYWORD))
-    model()->ClearKeyword(text());
+    model()->ClearKeyword();
   else
     model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1);
 
@@ -468,7 +466,8 @@
 
   // Prevent inline autocomplete when the caret isn't at the end of the text.
   const gfx::Range sel = GetSelectedRange();
-  model()->StartAutocomplete(!sel.is_empty(), sel.GetMax() < text().length());
+  model()->StartAutocomplete(!sel.is_empty(), sel.GetMax() < text().length(),
+                             false);
 }
 
 void OmniboxViewViews::ApplyCaretVisibility() {
@@ -929,7 +928,7 @@
     if (model()->is_keyword_hint() || model()->keyword().empty() ||
         HasSelection() || GetCursorPosition() != 0)
       return false;
-    model()->ClearKeyword(text());
+    model()->ClearKeyword();
     return true;
   }
 
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 b1bede3a..0daf101f 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -1058,9 +1058,8 @@
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
   DCHECK(browser);
   DCHECK(browser->window());
-
-  if (IsShowing())
-    return;
+  DCHECK(!manage_passwords_bubble_ ||
+         !manage_passwords_bubble_->GetWidget()->IsVisible());
 
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
   bool is_fullscreen = browser_view->IsFullscreen();
@@ -1095,18 +1094,11 @@
 
 // static
 void ManagePasswordsBubbleView::ActivateBubble() {
-  if (!IsShowing())
-    return;
+  DCHECK(manage_passwords_bubble_);
+  DCHECK(manage_passwords_bubble_->GetWidget()->IsVisible());
   manage_passwords_bubble_->GetWidget()->Activate();
 }
 
-// static
-bool ManagePasswordsBubbleView::IsShowing() {
-  // The bubble may be in the process of closing.
-  return (manage_passwords_bubble_ != NULL) &&
-      manage_passwords_bubble_->GetWidget()->IsVisible();
-}
-
 content::WebContents* ManagePasswordsBubbleView::web_contents() const {
   return model()->web_contents();
 }
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 173b995d..01c0ea15 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
@@ -35,11 +35,8 @@
   // Makes the bubble the foreground window.
   static void ActivateBubble();
 
-  // Whether the bubble is currently showing.
-  static bool IsShowing();
-
   // Returns a pointer to the bubble.
-  static const ManagePasswordsBubbleView* manage_password_bubble() {
+  static ManagePasswordsBubbleView* manage_password_bubble() {
     return manage_passwords_bubble_;
   }
 
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 654b1d56..2100e804 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
@@ -48,6 +48,12 @@
   MOCK_METHOD1(OnRequestDone, void(const GURL&));
 };
 
+bool IsBubbleShowing() {
+  return ManagePasswordsBubbleView::manage_password_bubble() &&
+      ManagePasswordsBubbleView::manage_password_bubble()->
+          GetWidget()->IsVisible();
+}
+
 }  // namespace
 
 namespace metrics_util = password_manager::metrics_util;
@@ -69,18 +75,18 @@
 };
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, BasicOpenAndClose) {
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
   ManagePasswordsBubbleView::ShowBubble(
       browser()->tab_strip_model()->GetActiveWebContents(),
       ManagePasswordsBubble::USER_ACTION);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   const ManagePasswordsBubbleView* bubble =
       ManagePasswordsBubbleView::manage_password_bubble();
   EXPECT_TRUE(bubble->initially_focused_view());
   EXPECT_EQ(bubble->initially_focused_view(),
             bubble->GetFocusManager()->GetFocusedView());
   ManagePasswordsBubbleView::CloseBubble();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 
   // And, just for grins, ensure that we can re-open the bubble.
   ManagePasswordsBubbleView::ShowBubble(
@@ -88,9 +94,9 @@
       ManagePasswordsBubble::USER_ACTION);
   EXPECT_TRUE(ManagePasswordsBubbleView::manage_password_bubble()->
       GetFocusManager()->GetFocusedView());
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   ManagePasswordsBubbleView::CloseBubble();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
 
 // Same as 'BasicOpenAndClose', but use the command rather than the static
@@ -98,30 +104,30 @@
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, CommandControlsBubble) {
   // The command only works if the icon is visible, so get into management mode.
   SetupManagingPasswords();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
   ExecuteManagePasswordsCommand();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   const ManagePasswordsBubbleView* bubble =
       ManagePasswordsBubbleView::manage_password_bubble();
   EXPECT_TRUE(bubble->initially_focused_view());
   EXPECT_EQ(bubble->initially_focused_view(),
             bubble->GetFocusManager()->GetFocusedView());
   ManagePasswordsBubbleView::CloseBubble();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 
   // And, just for grins, ensure that we can re-open the bubble.
   ExecuteManagePasswordsCommand();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   ManagePasswordsBubbleView::CloseBubble();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest,
                        CommandExecutionInManagingState) {
   SetupManagingPasswords();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
   ExecuteManagePasswordsCommand();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 
   scoped_ptr<base::HistogramSamples> samples(
       GetSamples(kDisplayDispositionMetric));
@@ -141,7 +147,7 @@
                        CommandExecutionInAutomaticState) {
   // Open with pending password: automagical!
   SetupPendingPassword();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 
   // Bubble should not be focused by default.
   EXPECT_FALSE(ManagePasswordsBubbleView::manage_password_bubble()->
@@ -168,11 +174,11 @@
                        CommandExecutionInPendingState) {
   // Open once with pending password: automagical!
   SetupPendingPassword();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   ManagePasswordsBubbleView::CloseBubble();
   // This opening should be measured as manual.
   ExecuteManagePasswordsCommand();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 
   scoped_ptr<base::HistogramSamples> samples(
       GetSamples(kDisplayDispositionMetric));
@@ -191,12 +197,12 @@
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest,
                        CommandExecutionInAutomaticSaveState) {
   SetupAutomaticPassword();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   ManagePasswordsBubbleView::CloseBubble();
   content::RunAllPendingInMessageLoop();
   // Re-opening should count as manual.
   ExecuteManagePasswordsCommand();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 
   scoped_ptr<base::HistogramSamples> samples(
       GetSamples(kDisplayDispositionMetric));
@@ -216,11 +222,11 @@
   ManagePasswordsBubbleView::ShowBubble(
       browser()->tab_strip_model()->GetActiveWebContents(),
       ManagePasswordsBubble::AUTOMATIC);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   EXPECT_FALSE(ManagePasswordsBubbleView::manage_password_bubble()->
       GetFocusManager()->GetFocusedView());
   ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER);
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, CloseOnKey) {
@@ -235,41 +241,41 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   ManagePasswordsBubbleView::ShowBubble(web_contents,
                                         ManagePasswordsBubble::AUTOMATIC);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   EXPECT_FALSE(ManagePasswordsBubbleView::manage_password_bubble()->
       GetFocusManager()->GetFocusedView());
   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_TAB_CONTAINER));
   EXPECT_TRUE(web_contents->GetRenderViewHost()->IsFocusedElementEditable());
   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_K,
       false, false, false, false));
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, CloseOnChangedState) {
   SetupPendingPassword();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   // User navigated very fast and landed on another page with an autofilled
   // password. The save password bubble should disappear.
   SetupManagingPasswords();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, TwoTabsWithBubble) {
   // Set up the first tab with the bubble.
   SetupPendingPassword();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   // Set up the second tab.
   AddTabAtIndex(0, GURL("chrome://newtab"), ui::PAGE_TRANSITION_TYPED);
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
   ManagePasswordsBubbleView::ShowBubble(
       browser()->tab_strip_model()->GetActiveWebContents(),
       ManagePasswordsBubble::AUTOMATIC);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   TabStripModel* tab_model = browser()->tab_strip_model();
   EXPECT_EQ(0, tab_model->active_index());
   // Back to the first tab.
   tab_model->ActivateTabAt(1, true);
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, ChooseCredential) {
@@ -299,7 +305,7 @@
 
   SetupChooseCredentials(local_credentials.Pass(), federated_credentials.Pass(),
                          origin);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   EXPECT_CALL(*this, OnChooseCredential(
       Field(&password_manager::CredentialInfo::type,
             password_manager::CredentialType::CREDENTIAL_TYPE_EMPTY)));
@@ -323,7 +329,7 @@
   EXPECT_FALSE(browser()->window()->IsActive());
   SetupChooseCredentials(local_credentials.Pass(), federated_credentials.Pass(),
                          origin);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, AutoSignin) {
@@ -349,11 +355,11 @@
   EXPECT_CALL(url_callback, OnRequestDone(avatar_url));
 
   SetupAutoSignin(local_credentials.Pass());
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
   ::testing::Mock::VerifyAndClearExpectations(&url_callback);
 
   ManagePasswordsBubbleView::CloseBubble();
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
   content::RunAllPendingInMessageLoop();
 
   // Open the bubble to manage accounts.
@@ -362,7 +368,7 @@
   ManagePasswordsBubbleView::ShowBubble(
         browser()->tab_strip_model()->GetActiveWebContents(),
         ManagePasswordsBubble::USER_ACTION);
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 }
 
 IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, AutoSigninNoFocus) {
@@ -381,12 +387,12 @@
   ManagePasswordsBubbleView::set_auto_signin_toast_timeout(0);
   SetupAutoSignin(local_credentials.Pass());
   content::RunAllPendingInMessageLoop();
-  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_TRUE(IsBubbleShowing());
 
   // Bring the first window back. The toast closes by timeout.
   focused_window->window()->Close();
   browser()->window()->Activate();
   content::RunAllPendingInMessageLoop();
   EXPECT_TRUE(browser()->window()->IsActive());
-  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  EXPECT_FALSE(IsBubbleShowing());
 }
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc
index a0a54b1e..2527a88 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc
@@ -42,12 +42,6 @@
     ManagePasswordsBubbleView::CloseBubble();
 }
 
-bool ManagePasswordsIconView::IsBubbleShowing() const {
-  // If the bubble is being destroyed, it's considered showing though it may be
-  // already invisible currently.
-  return ManagePasswordsBubbleView::manage_password_bubble() != NULL;
-}
-
 void ManagePasswordsIconView::OnExecuting(
     BubbleIconView::ExecuteSource source) {
 }
@@ -78,3 +72,7 @@
   if (active())
     ManagePasswordsBubbleView::ActivateBubble();
 }
+
+views::BubbleDelegateView* ManagePasswordsIconView::GetBubble() const {
+  return ManagePasswordsBubbleView::manage_password_bubble();
+}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h
index 2d0c3d0..0b901c1 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h
@@ -22,7 +22,6 @@
   ~ManagePasswordsIconView() override;
 
   // BubbleIconView:
-  bool IsBubbleShowing() const override;
   void OnExecuting(BubbleIconView::ExecuteSource source) override;
   bool OnMousePressed(const ui::MouseEvent& event) override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
@@ -40,6 +39,9 @@
   void UpdateVisibleUI() override;
   void OnChangingState() override;
 
+  // BubbleIconView:
+  views::BubbleDelegateView* GetBubble() const override;
+
  private:
 
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsIconView);
diff --git a/chrome/browser/ui/views/tab_dialogs_views.cc b/chrome/browser/ui/views/tab_dialogs_views.cc
index f235dce..517764d9 100644
--- a/chrome/browser/ui/views/tab_dialogs_views.cc
+++ b/chrome/browser/ui/views/tab_dialogs_views.cc
@@ -53,7 +53,7 @@
 }
 
 void TabDialogsViews::ShowManagePasswordsBubble(bool user_action) {
-  if (ManagePasswordsBubbleView::IsShowing()) {
+  if (ManagePasswordsBubbleView::manage_password_bubble()) {
     // The bubble is currently shown for some other tab. We should close it now
     // and open for |web_contents_|.
     ManagePasswordsBubbleView::CloseBubble();
@@ -64,7 +64,7 @@
 }
 
 void TabDialogsViews::HideManagePasswordsBubble() {
-  if (!ManagePasswordsBubbleView::IsShowing())
+  if (!ManagePasswordsBubbleView::manage_password_bubble())
     return;
   content::WebContents* bubble_web_contents =
       ManagePasswordsBubbleView::manage_password_bubble()->web_contents();
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 9be153ab..3e505ff 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -1325,8 +1326,14 @@
   ASSERT_TRUE(TabDragController::IsActive());
   ASSERT_EQ(2u, browser_list->size());
 
-  // Add another tab. This should trigger exiting the nested loop.
-  test->AddBlankTabAndShow(browser_list->GetLastActive());
+  // Add another tab. This should trigger exiting the nested loop. Add at the
+  // to exercise past crash when model/tabstrip got out of sync (474082).
+  content::WindowedNotificationObserver observer(
+      content::NOTIFICATION_LOAD_STOP,
+      content::NotificationService::AllSources());
+  chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL),
+                   0, false);
+  observer.Wait();
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 816f023..b01e196 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -630,14 +630,6 @@
 void TabStrip::AddTabAt(int model_index,
                         const TabRendererData& data,
                         bool is_active) {
-  // Stop dragging when a new tab is added and dragging a window. Doing
-  // otherwise results in a confusing state if the user attempts to reattach. We
-  // could allow this and make TabDragController update itself during the add,
-  // but this comes up infrequently enough that it's not work the complexity.
-  if (drag_controller_.get() && !drag_controller_->is_mutating() &&
-      drag_controller_->is_dragging_window()) {
-    EndDrag(END_DRAG_COMPLETE);
-  }
   Tab* tab = CreateTab();
   tab->SetData(data);
   UpdateTabsClosingMap(model_index, 1);
@@ -665,6 +657,20 @@
 
   FOR_EACH_OBSERVER(TabStripObserver, observers_,
                     TabStripAddedTabAt(this, model_index));
+
+  // Stop dragging when a new tab is added and dragging a window. Doing
+  // otherwise results in a confusing state if the user attempts to reattach. We
+  // could allow this and make TabDragController update itself during the add,
+  // but this comes up infrequently enough that it's not worth the complexity.
+  //
+  // At the start of AddTabAt() the model and tabs are out sync. Any queries to
+  // find a tab given a model index can go off the end of |tabs_|. As such, it
+  // is important that we complete the drag *after* adding the tab so that the
+  // model and tabstrip are in sync.
+  if (drag_controller_.get() && !drag_controller_->is_mutating() &&
+      drag_controller_->is_dragging_window()) {
+    EndDrag(END_DRAG_COMPLETE);
+  }
 }
 
 void TabStrip::MoveTab(int from_model_index,
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 1c8f05ec..5373da2 100644
--- a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
@@ -351,8 +351,7 @@
   // Hide action A. This results in it being sent to overflow, and reducing the
   // visible size to 1, so the order should be C A B, with only C visible in the
   // main bar.
-  extensions::ExtensionActionAPI::SetBrowserActionVisibility(
-      extensions::ExtensionPrefs::Get(profile()),
+  extensions::ExtensionActionAPI::Get(profile())->SetBrowserActionVisibility(
       extension_a()->id(),
       false);
   overflow_bar()->Layout();  // Kick.
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 145d4443..d86cd49 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -85,7 +85,7 @@
     translate::TranslateStep step,
     translate::TranslateErrors::Type error_type,
     bool is_user_gesture) {
-  if (IsShowing()) {
+  if (translate_bubble_view_) {
     // When the user reads the advanced setting panel, the bubble should not be
     // changed because he/she is focusing on the bubble.
     if (translate_bubble_view_->web_contents() == web_contents &&
@@ -133,18 +133,13 @@
 
 // static
 void TranslateBubbleView::CloseBubble() {
-  if (!IsShowing())
+  if (!translate_bubble_view_)
     return;
 
   translate_bubble_view_->GetWidget()->Close();
 }
 
 // static
-bool TranslateBubbleView::IsShowing() {
-  return translate_bubble_view_ != NULL;
-}
-
-// static
 TranslateBubbleView* TranslateBubbleView::GetCurrentBubble() {
   return translate_bubble_view_;
 }
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h
index 014aa4d..61506e8 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.h
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -54,9 +54,6 @@
   // Closes the current bubble if existing.
   static void CloseBubble();
 
-  // If true, the Translate bubble is being shown.
-  static bool IsShowing();
-
   // Returns the bubble view currently shown. This may return NULL.
   static TranslateBubbleView* GetCurrentBubble();
 
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc b/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc
index fa856e43..1c0e41b6c 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc
@@ -40,7 +40,7 @@
 // Flaky: crbug.com/394066
 IN_PROC_BROWSER_TEST_F(TranslateBubbleViewBrowserTest,
                        DISABLED_CloseBrowserWithoutTranslating) {
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 
   // Show a French page and wait until the bubble is shown.
   content::WebContents* current_web_contents =
@@ -54,17 +54,17 @@
       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("french_page.html")));
   ui_test_utils::NavigateToURL(browser(), french_url);
   fr_language_detected_signal.Wait();
-  EXPECT_TRUE(TranslateBubbleView::IsShowing());
+  EXPECT_TRUE(TranslateBubbleView::GetCurrentBubble());
 
   // Close the window without translating.
   chrome::CloseWindow(browser());
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 }
 
 // http://crbug.com/378061
 IN_PROC_BROWSER_TEST_F(TranslateBubbleViewBrowserTest,
                        DISABLED_CloseLastTabWithoutTranslating) {
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 
   // Show a French page and wait until the bubble is shown.
   content::WebContents* current_web_contents =
@@ -78,17 +78,17 @@
       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("french_page.html")));
   ui_test_utils::NavigateToURL(browser(), french_url);
   fr_language_detected_signal.Wait();
-  EXPECT_TRUE(TranslateBubbleView::IsShowing());
+  EXPECT_TRUE(TranslateBubbleView::GetCurrentBubble());
 
   // Close the tab without translating.
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
   chrome::CloseWebContents(browser(), current_web_contents, false);
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 }
 
 IN_PROC_BROWSER_TEST_F(TranslateBubbleViewBrowserTest,
                        CloseAnotherTabWithoutTranslating) {
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 
   int active_index = browser()->tab_strip_model()->active_index();
 
@@ -111,13 +111,13 @@
   fr_language_detected_signal.Wait();
 
   // The bubble is not shown because the tab is not activated.
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 
   // Close the French page tab immediately.
   chrome::CloseWebContents(browser(), web_contents, false);
   EXPECT_EQ(active_index, browser()->tab_strip_model()->active_index());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_FALSE(TranslateBubbleView::IsShowing());
+  EXPECT_FALSE(TranslateBubbleView::GetCurrentBubble());
 
   // Close the last tab.
   chrome::CloseWebContents(browser(),
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc
index 210ff38..a7f9b60 100644
--- a/chrome/browser/ui/webui/certificate_viewer_webui.cc
+++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
@@ -204,8 +204,7 @@
 
 void CertificateViewerModalDialog::OnCloseContents(WebContents* source,
                                               bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool CertificateViewerModalDialog::ShouldShowDialogTitle() const {
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 2f0caa60..01673ca 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h"
 
+#include "ash/system/system_notifier.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
@@ -19,9 +20,11 @@
 #include "chrome/browser/chromeos/idle_detector.h"
 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
 #include "chrome/browser/chromeos/login/screens/network_model.h"
+#include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
 #include "chrome/browser/chromeos/system/input_device_settings.h"
 #include "chrome/browser/chromeos/system/timezone_util.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/common/pref_names.h"
@@ -32,14 +35,41 @@
 #include "components/login/localized_values_builder.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_thread.h"
+#include "grit/ash_strings.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/notification.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/widget.h"
 
 namespace {
+
 const char kJsScreenPath[] = "login.NetworkScreen";
+const char kNewGAIAKillSwitch[] = "new_gaia_kill_switch";
+
+void ShowNewLoginUIPopup() {
+  // Show new login UI popup message, if necessary
+  if (g_browser_process->local_state()->GetBoolean(prefs::kNewLoginUIPopup)) {
+    base::string16 message = l10n_util::GetStringUTF16(
+        chromeos::StartupUtils::IsWebviewSigninEnabled()
+            ? IDS_ASH_STATUS_TRAY_NEW_LOGIN_UI_ENABLED
+            : IDS_ASH_STATUS_TRAY_NEW_LOGIN_UI_DISABLED);
+    scoped_ptr<message_center::Notification> notification(
+        new message_center::Notification(
+            message_center::NOTIFICATION_TYPE_SIMPLE, kNewGAIAKillSwitch,
+            base::string16(), message, gfx::Image(), base::string16(),
+            message_center::NotifierId(
+                message_center::NotifierId::SYSTEM_COMPONENT,
+                ash::system_notifier::kNotifierOobeScreen),
+            message_center::RichNotificationData(), nullptr));
+    message_center::MessageCenter::Get()->AddNotification(notification.Pass());
+    g_browser_process->local_state()->SetBoolean(prefs::kNewLoginUIPopup,
+                                                 false);
+  }
+}
+
 }  // namespace
 
 namespace chromeos {
@@ -96,6 +126,8 @@
           chromeos::switches::kSystemDevMode));
   ShowScreen(OobeUI::kScreenOobeNetwork, &network_screen_params);
   core_oobe_actor_->InitDemoModeDetection();
+
+  ShowNewLoginUIPopup();
 }
 
 void NetworkScreenHandler::Hide() {
@@ -138,6 +170,12 @@
 
 // NetworkScreenHandler, BaseScreenHandler implementation: --------------------
 
+void NetworkScreenHandler::RegisterMessages() {
+  AddCallback("toggleNewLoginUI",
+              &NetworkScreenHandler::HandleToggleNewLoginUI);
+  BaseScreenHandler::RegisterMessages();
+}
+
 void NetworkScreenHandler::DeclareLocalizedValues(
     ::login::LocalizedValuesBuilder* builder) {
   if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
@@ -222,6 +260,14 @@
     ReloadLocalizedContent();
 }
 
+void NetworkScreenHandler::HandleToggleNewLoginUI() {
+  if (StartupUtils::EnableWebviewSignin(
+          !StartupUtils::IsWebviewSigninEnabled())) {
+    g_browser_process->local_state()->SetBoolean(prefs::kNewLoginUIPopup, true);
+    chrome::AttemptRestart();
+  }
+}
+
 // NetworkScreenHandler, private: ----------------------------------------------
 
 // static
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 78813817d..32b4cf4 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h
@@ -44,11 +44,15 @@
   void ReloadLocalizedContent() override;
 
   // BaseScreenHandler implementation:
+  void RegisterMessages() override;
   void DeclareLocalizedValues(
       ::login::LocalizedValuesBuilder* builder) override;
   void GetAdditionalParameters(base::DictionaryValue* dict) override;
   void Initialize() override;
 
+  // WebUI message handlers.
+  void HandleToggleNewLoginUI();
+
  private:
   // Returns available timezones. Caller gets the ownership.
   static base::ListValue* GetTimezoneList();
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 2f3a1cb..b271920 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -294,18 +294,8 @@
   error_screen_handler_ = new ErrorScreenHandler();
   AddScreenHandler(error_screen_handler_);
 
-  // Initialize ErrorScreen if it hasn't initialized so that NetworkErrorModel
-  // is binded properly.
-  NetworkErrorModel* network_error_model = nullptr;
-  if (WizardController::default_controller()) {
-    network_error_model = static_cast<NetworkErrorModel*>(
-        WizardController::default_controller()->GetScreen(
-            WizardController::kErrorScreenName));
-    CHECK(network_error_model);
-  } else {
-    error_screen_.reset(new ErrorScreen(nullptr, error_screen_handler_));
-    network_error_model = error_screen_.get();
-  }
+  error_screen_.reset(new ErrorScreen(nullptr, error_screen_handler_));
+  NetworkErrorModel* network_error_model = error_screen_.get();
 
   EnrollmentScreenHandler* enrollment_screen_handler =
       new EnrollmentScreenHandler(network_state_informer_, network_error_model);
@@ -468,8 +458,8 @@
   return user_image_view_;
 }
 
-NetworkErrorView* OobeUI::GetNetworkErrorView() {
-  return error_screen_handler_;
+ErrorScreen* OobeUI::GetErrorScreen() {
+  return error_screen_.get();
 }
 
 SupervisedUserCreationScreenHandler*
@@ -527,10 +517,6 @@
   localized_strings->SetString("newKioskUI", new_kiosk_ui ? "on" : "off");
 }
 
-scoped_ptr<ErrorScreen> OobeUI::GetErrorScreen() {
-  return error_screen_.Pass();
-}
-
 void OobeUI::InitializeScreenMaps() {
   screen_names_.resize(SCREEN_UNKNOWN);
   screen_names_[SCREEN_OOBE_HID_DETECTION] = kScreenOobeHIDDetection;
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
index 59a9a3a..45b05aa 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -110,7 +110,7 @@
   KioskEnableScreenActor* GetKioskEnableScreenActor() override;
   TermsOfServiceScreenActor* GetTermsOfServiceScreenActor() override;
   UserImageView* GetUserImageView() override;
-  NetworkErrorView* GetNetworkErrorView() override;
+  ErrorScreen* GetErrorScreen() override;
   WrongHWIDScreenActor* GetWrongHWIDScreenActor() override;
   AutoEnrollmentCheckScreenActor* GetAutoEnrollmentCheckScreenActor() override;
   SupervisedUserCreationScreenHandler* GetSupervisedUserCreationScreenActor()
@@ -168,11 +168,6 @@
     return network_state_informer_.get();
   }
 
-  // If an error screen was created during initialization, then it may be
-  // fetched using this method, while also passing the ownership of
-  // |error_screen_|.
-  scoped_ptr<ErrorScreen> GetErrorScreen();
-
  private:
   // Initializes |screen_ids_| and |screen_names_| structures.
   void InitializeScreenMaps();
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
index 8efe307..4a015d78 100644
--- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
@@ -165,6 +165,9 @@
   AddCallback("abortLocalSupervisedUserCreation",
               &SupervisedUserCreationScreenHandler::
                   HandleAbortLocalSupervisedUserCreation);
+  AddCallback("hideLocalSupervisedUserCreation",
+              &SupervisedUserCreationScreenHandler::
+                  HandleHideLocalSupervisedUserCreation);
   AddCallback("checkSupervisedUserName",
               &SupervisedUserCreationScreenHandler::
                   HandleCheckSupervisedUserName);
@@ -286,6 +289,11 @@
   delegate_->AbortFlow();
 }
 
+void SupervisedUserCreationScreenHandler::
+    HandleHideLocalSupervisedUserCreation() {
+  delegate_->HideFlow();
+}
+
 void SupervisedUserCreationScreenHandler::HandleManagerSelected(
     const std::string& manager_id) {
   if (!delegate_)
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h
index 1395d5b..4d9284be8 100644
--- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h
@@ -56,6 +56,7 @@
 
     virtual void AbortFlow() = 0;
     virtual void FinishFlow() = 0;
+    virtual void HideFlow() = 0;
 
     virtual void OnPhotoTaken(const std::string& raw_data) = 0;
     virtual void OnImageSelected(const std::string& image_url,
@@ -110,6 +111,7 @@
 
   void HandleFinishLocalSupervisedUserCreation();
   void HandleAbortLocalSupervisedUserCreation();
+  void HandleHideLocalSupervisedUserCreation();
   void HandleRetryLocalSupervisedUserCreation(const base::ListValue* args);
   void HandleCurrentSupervisedUserPage(const std::string& current_page);
 
diff --git a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
index d8a0567..b1d3d56 100644
--- a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
+++ b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/sys_info.h"
 #include "base/values.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
@@ -94,11 +95,12 @@
 
 }  // namespace
 
-KioskAppsHandler::KioskAppsHandler()
+KioskAppsHandler::KioskAppsHandler(OwnerSettingsServiceChromeOS* service)
     : kiosk_app_manager_(KioskAppManager::Get()),
       initialized_(false),
       is_kiosk_enabled_(false),
       is_auto_launch_enabled_(false),
+      owner_settings_service_(service),
       weak_ptr_factory_(this) {
   kiosk_app_manager_->AddObserver(this);
 }
@@ -281,7 +283,7 @@
     return;
   }
 
-  kiosk_app_manager_->AddApp(app_id);
+  kiosk_app_manager_->AddApp(app_id, owner_settings_service_);
 }
 
 void KioskAppsHandler::HandleRemoveKioskApp(const base::ListValue* args) {
@@ -291,7 +293,7 @@
   std::string app_id;
   CHECK(args->GetString(0, &app_id));
 
-  kiosk_app_manager_->RemoveApp(app_id);
+  kiosk_app_manager_->RemoveApp(app_id, owner_settings_service_);
 }
 
 void KioskAppsHandler::HandleEnableKioskAutoLaunch(
@@ -302,7 +304,7 @@
   std::string app_id;
   CHECK(args->GetString(0, &app_id));
 
-  kiosk_app_manager_->SetAutoLaunchApp(app_id);
+  kiosk_app_manager_->SetAutoLaunchApp(app_id, owner_settings_service_);
 }
 
 void KioskAppsHandler::HandleDisableKioskAutoLaunch(
@@ -317,7 +319,7 @@
   if (startup_app_id != app_id)
     return;
 
-  kiosk_app_manager_->SetAutoLaunchApp("");
+  kiosk_app_manager_->SetAutoLaunchApp("", owner_settings_service_);
 }
 
 void KioskAppsHandler::HandleSetDisableBailoutShortcut(
@@ -328,7 +330,7 @@
   bool disable_bailout_shortcut;
   CHECK(args->GetBoolean(0, &disable_bailout_shortcut));
 
-  CrosSettings::Get()->SetBoolean(
+  owner_settings_service_->SetBoolean(
       kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
       !disable_bailout_shortcut);
 }
@@ -350,7 +352,7 @@
   web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.showError",
                                    app_id_value);
 
-  kiosk_app_manager_->RemoveApp(app_id);
+  kiosk_app_manager_->RemoveApp(app_id, owner_settings_service_);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h
index 23df3a1450..83fa88e 100644
--- a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h
+++ b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h
@@ -25,11 +25,12 @@
 namespace chromeos {
 
 class KioskAppManager;
+class OwnerSettingsServiceChromeOS;
 
 class KioskAppsHandler : public content::WebUIMessageHandler,
                          public KioskAppManagerObserver {
  public:
-  KioskAppsHandler();
+  explicit KioskAppsHandler(OwnerSettingsServiceChromeOS* service);
   ~KioskAppsHandler() override;
 
   void GetLocalizedValues(content::WebUIDataSource* source);
@@ -69,6 +70,7 @@
   bool initialized_;
   bool is_kiosk_enabled_;
   bool is_auto_launch_enabled_;
+  OwnerSettingsServiceChromeOS* const owner_settings_service_;  // not owned
   base::WeakPtrFactory<KioskAppsHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(KioskAppsHandler);
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
index 0ba6bc2c..dc6f1958 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -35,9 +35,6 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/google/core/browser/google_util.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/site_instance.h"
@@ -309,16 +306,6 @@
                  AsWeakPtr()));
 }
 
-void ExtensionSettingsHandler::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(
-      extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-      type);
-  MaybeUpdateAfterNotification();
-}
-
 void ExtensionSettingsHandler::OnExtensionDisableReasonsChanged(
     const std::string& extension_id, int disable_reasons) {
   MaybeUpdateAfterNotification();
@@ -350,17 +337,12 @@
 
 void ExtensionSettingsHandler::HandleRegisterMessage(
     const base::ListValue* args) {
-  if (!registrar_.IsEmpty())
+  if (content::WebContentsObserver::web_contents())
     return;  // Only register once.
 
-  Profile* profile = Profile::FromWebUI(web_ui());
-  registrar_.Add(
-      this,
-      extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-      content::Source<ExtensionPrefs>(ExtensionPrefs::Get(profile)));
-
   content::WebContentsObserver::Observe(web_ui()->GetWebContents());
 
+  Profile* profile = Profile::FromWebUI(web_ui());
   warning_service_observer_.Add(WarningService::Get(profile));
   extension_management_observer_.Add(
       ExtensionManagementFactory::GetForBrowserContext(profile));
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.h b/chrome/browser/ui/webui/extensions/extension_settings_handler.h
index 1e7a95b..69793c0 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.h
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.h
@@ -11,8 +11,6 @@
 #include "base/scoped_observer.h"
 #include "chrome/browser/extensions/extension_management.h"
 #include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_ui_message_handler.h"
 #include "extensions/browser/extension_prefs_observer.h"
@@ -41,7 +39,6 @@
 // Extension Settings UI handler.
 class ExtensionSettingsHandler
     : public content::WebUIMessageHandler,
-      public content::NotificationObserver,
       public content::WebContentsObserver,
       public ExtensionManagement::Observer,
       public ExtensionPrefsObserver,
@@ -65,11 +62,6 @@
   // WebUIMessageHandler implementation.
   void RegisterMessages() override;
 
-  // content::NotificationObserver implementation.
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   // ExtensionPrefsObserver implementation.
   void OnExtensionDisableReasonsChanged(const std::string& extension_id,
                                         int disable_reasons) override;
@@ -92,8 +84,6 @@
   // Our model.  Outlives us since it's owned by our containing profile.
   ExtensionService* extension_service_;
 
-  content::NotificationRegistrar registrar_;
-
   ScopedObserver<WarningService, WarningService::Observer>
       warning_service_observer_;
 
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc
index 49d921b..681fd3f 100644
--- a/chrome/browser/ui/webui/extensions/extensions_ui.cc
+++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -18,6 +18,7 @@
 #include "ui/base/resource/resource_bundle.h"
 
 #if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
 #include "chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h"
 #endif
 
@@ -65,7 +66,9 @@
 
 #if defined(OS_CHROMEOS)
   chromeos::KioskAppsHandler* kiosk_app_handler =
-      new chromeos::KioskAppsHandler();
+      new chromeos::KioskAppsHandler(
+          chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(
+              profile));
   kiosk_app_handler->GetLocalizedValues(source);
   web_ui->AddMessageHandler(kiosk_app_handler);
 #endif
diff --git a/chrome/browser/ui/webui/large_icon_source.cc b/chrome/browser/ui/webui/large_icon_source.cc
index df1e285f..6c74b0ef 100644
--- a/chrome/browser/ui/webui/large_icon_source.cc
+++ b/chrome/browser/ui/webui/large_icon_source.cc
@@ -4,53 +4,29 @@
 
 #include "chrome/browser/ui/webui/large_icon_source.h"
 
+#include <vector>
+
 #include "base/memory/ref_counted_memory.h"
 #include "chrome/browser/search/instant_io_context.h"
 #include "chrome/common/favicon/large_icon_url_parser.h"
 #include "chrome/common/url_constants.h"
 #include "components/favicon/core/fallback_icon_service.h"
-#include "components/favicon/core/favicon_service.h"
+#include "components/favicon/core/large_icon_service.h"
 #include "components/favicon_base/fallback_icon_style.h"
+#include "components/favicon_base/favicon_types.h"
 #include "net/url_request/url_request.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/color_analysis.h"
-#include "ui/gfx/color_utils.h"
 
 namespace {
 
-const int kDefaultLargeIconSize = 96;
 const int kMaxLargeIconSize = 192;  // Arbitrary bound to safeguard endpoint.
 
-const double kMaxBackgroundLuminance = 0.67;
-const SkColor kDarkGray = SkColorSetRGB(0x78, 0x78, 0x78);
-const SkColor kTextColor = SK_ColorWHITE;
-const SkColor kDefaultBackgroundColor = kDarkGray;
-
 }  // namespace
 
-LargeIconSource::IconRequest::IconRequest() : size(kDefaultLargeIconSize) {
-}
-
-LargeIconSource::IconRequest::IconRequest(
-    const content::URLDataSource::GotDataCallback& callback_in,
-    const GURL& url_in,
-    int size_in)
-    : callback(callback_in),
-      url(url_in),
-      size(size_in) {
-}
-
-LargeIconSource::IconRequest::~IconRequest() {
-}
-
 LargeIconSource::LargeIconSource(
-    favicon::FaviconService* favicon_service,
-    favicon::FallbackIconService* fallback_icon_service)
-    : favicon_service_(favicon_service),
-      fallback_icon_service_(fallback_icon_service) {
-  large_icon_types_.push_back(favicon_base::IconType::FAVICON);
-  large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
-  large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
+    favicon::FallbackIconService* fallback_icon_service,
+    favicon::LargeIconService* large_icon_service)
+    : fallback_icon_service_(fallback_icon_service),
+      large_icon_service_(large_icon_service) {
 }
 
 LargeIconSource::~LargeIconSource() {
@@ -65,7 +41,7 @@
     int render_process_id,
     int render_frame_id,
     const content::URLDataSource::GotDataCallback& callback) {
-  if (!favicon_service_) {
+  if (!large_icon_service_) {
     SendNotFoundResponse(callback);
     return;
   }
@@ -85,14 +61,12 @@
     return;
   }
 
-  favicon_service_->GetLargestRawFaviconForPageURL(
+  large_icon_service_->GetLargeIconOrFallbackStyle(
       url,
-      large_icon_types_,
       parser.size_in_pixels(),
-      base::Bind(
-          &LargeIconSource::OnIconDataAvailable,
-          base::Unretained(this),
-          IconRequest(callback, url, parser.size_in_pixels())),
+      base::Bind(&LargeIconSource::OnLargeIconDataAvailable,
+                 base::Unretained(this), callback, url,
+                 parser.size_in_pixels()),
       &cancelable_task_tracker_);
 }
 
@@ -115,54 +89,25 @@
   return URLDataSource::ShouldServiceRequest(request);
 }
 
-void LargeIconSource::OnIconDataAvailable(
-    const IconRequest& request,
-    const favicon_base::FaviconRawBitmapResult& bitmap_result) {
-  if (!bitmap_result.is_valid()) {
-    SendDefaultFallbackIcon(request);
+void LargeIconSource::OnLargeIconDataAvailable(
+    const content::URLDataSource::GotDataCallback& callback,
+    const GURL& url,
+    int size,
+    const favicon_base::LargeIconResult& result) {
+  if (result.bitmap.is_valid()) {
+    callback.Run(result.bitmap.bitmap_data.get());
     return;
   }
 
-  // If we found a bitmap, but it's smaller than the requested size, we
-  // generate a fallback using the dominant color from the too-small bitmap.
-  // We adjust the luminance of the background so we can put light text over it.
-  if (bitmap_result.pixel_size.width() < request.size ||
-      bitmap_result.pixel_size.height() < request.size) {
-    SkColor background =
-        color_utils::CalculateKMeanColorOfPNG(bitmap_result.bitmap_data);
-    color_utils::HSL background_hsl;
-    color_utils::SkColorToHSL(background, &background_hsl);
-    background_hsl.l = std::min(background_hsl.l, kMaxBackgroundLuminance);
-    background = color_utils::HSLToSkColor(background_hsl, SK_AlphaOPAQUE);
-
-    // Now we can construct the fallback icon.
-    SendFallbackIcon(request, kTextColor, background);
+  // Bitmap is invalid, use the fallback if service is available.
+  if (!fallback_icon_service_ || !result.fallback_icon_style) {
+    SendNotFoundResponse(callback);
     return;
   }
-
-  request.callback.Run(bitmap_result.bitmap_data.get());
-}
-
-void LargeIconSource::SendDefaultFallbackIcon(const IconRequest& request) {
-  SendFallbackIcon(request, kTextColor, kDefaultBackgroundColor);
-}
-
-void LargeIconSource::SendFallbackIcon(const IconRequest& request,
-                                       SkColor text_color,
-                                       SkColor background_color) {
-  if (!fallback_icon_service_) {
-    SendNotFoundResponse(request.callback);
-    return;
-  }
-  favicon_base::FallbackIconStyle style;
-  style.background_color = background_color;
-  style.text_color = text_color;
-  style.font_size_ratio = 0.44;
-  style.roundness = 0;  // Square. Round corners can be applied by JavaScript.
   std::vector<unsigned char> bitmap_data =
       fallback_icon_service_->RenderFallbackIconBitmap(
-          request.url, request.size, style);
-  request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data));
+          url, size, *result.fallback_icon_style);
+  callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data));
 }
 
 void LargeIconSource::SendNotFoundResponse(
diff --git a/chrome/browser/ui/webui/large_icon_source.h b/chrome/browser/ui/webui/large_icon_source.h
index 05872d2..fb573ea 100644
--- a/chrome/browser/ui/webui/large_icon_source.h
+++ b/chrome/browser/ui/webui/large_icon_source.h
@@ -6,18 +6,19 @@
 #define CHROME_BROWSER_UI_WEBUI_LARGE_ICON_SOURCE_H_
 
 #include <string>
-#include <vector>
 
 #include "base/memory/scoped_ptr.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "components/favicon/core/fallback_icon_service.h"
-#include "components/favicon_base/favicon_types.h"
 #include "content/public/browser/url_data_source.h"
-#include "third_party/skia/include/core/SkColor.h"
 
 namespace favicon {
 class FallbackIconService;
-class FaviconService;
+class LargeIconService;
+}
+
+namespace favicon_base {
+struct LargeIconResult;
 }
 
 // LargeIconSource services explicit chrome:// requests for large icons.
@@ -35,10 +36,10 @@
 //    This requests a 48x48 large icon for http://www.google.com.
 class LargeIconSource : public content::URLDataSource {
  public:
-  // |favicon_service| and |fallback_icon_service| are owned by caller and may
-  // be null.
-  LargeIconSource(favicon::FaviconService* favicon_service,
-                  favicon::FallbackIconService* fallback_icon_service);
+  // |fallback_icon_service| and |large_icon_service| are owned by caller and
+  // may be null.
+  LargeIconSource(favicon::FallbackIconService* fallback_icon_service,
+                  favicon::LargeIconService* large_icon_service);
 
   ~LargeIconSource() override;
 
@@ -53,34 +54,13 @@
   bool ShouldReplaceExistingSource() const override;
   bool ShouldServiceRequest(const net::URLRequest* request) const override;
 
- protected:
-  struct IconRequest {
-    IconRequest();
-    IconRequest(const content::URLDataSource::GotDataCallback& callback_in,
-                const GURL& path_in,
-                int size_in);
-    ~IconRequest();
-
-    content::URLDataSource::GotDataCallback callback;
-    GURL url;
-    int size;
-  };
-
  private:
-  // Callback for icon data retrieval request.
-  void OnIconDataAvailable(
-      const IconRequest& request,
-      const favicon_base::FaviconRawBitmapResult& bitmap_result);
-
-  // Renders and sends a default fallback icon. This is used when there is no
-  // known text and/or foreground color to use for the generated icon (it
-  // defaults to a light text color on a dark gray background).
-  void SendDefaultFallbackIcon(const IconRequest& request);
-
-  // Renders and sends a fallback icon using the given colors.
-  void SendFallbackIcon(const IconRequest& request,
-                        SkColor text_color,
-                        SkColor background_color);
+  // Called with results of large icon retrieval request.
+  void OnLargeIconDataAvailable(
+      const content::URLDataSource::GotDataCallback& callback,
+      const GURL& url,
+      int size,
+      const favicon_base::LargeIconResult& bitmap_result);
 
   // Returns null to trigger "Not Found" response.
   void SendNotFoundResponse(
@@ -88,15 +68,11 @@
 
   base::CancelableTaskTracker cancelable_task_tracker_;
 
-  favicon::FaviconService* favicon_service_;
-
+  // Owned by client.
   favicon::FallbackIconService* fallback_icon_service_;
 
-  // A pre-populated list of the types of icon files to consider when looking
-  // for the largest matching icon.
-  // Note: this is simply an optimization over populating an icon type vector
-  //     on each request.
-  std::vector<int> large_icon_types_;
+  // Owned by client.
+  favicon::LargeIconService* large_icon_service_;
 
   DISALLOW_COPY_AND_ASSIGN(LargeIconSource);
 };
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
index 45d41c8..859b831 100644
--- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
@@ -20,7 +20,6 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chrome/test/base/web_ui_browser_test.h"
-#include "chromeos/chromeos_switches.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/browser/signin_manager_base.h"
@@ -33,6 +32,7 @@
 #if defined(OS_CHROMEOS)
 #include "base/prefs/pref_service.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/chromeos_switches.h"
 #endif
 
 using testing::InvokeWithoutArgs;
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 78ca7bcc..c80cfbe 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -299,7 +299,7 @@
 #if defined(OS_WIN)
   void OnGetServiceProviders(const base::ListValue* list);
 #endif
-  void OnSetLogLevel(const base::ListValue* list);
+  void OnSetCaptureMode(const base::ListValue* list);
 
   // ChromeNetLog::ThreadSafeObserver implementation:
   void OnAddEntry(const net::NetLog::Entry& entry) override;
@@ -466,9 +466,8 @@
 #endif
 
   web_ui()->RegisterMessageCallback(
-      "setLogLevel",
-      base::Bind(&IOThreadImpl::CallbackHelper,
-                 &IOThreadImpl::OnSetLogLevel, proxy_));
+      "setCaptureMode", base::Bind(&IOThreadImpl::CallbackHelper,
+                                   &IOThreadImpl::OnSetCaptureMode, proxy_));
   web_ui()->RegisterMessageCallback(
       "clearBrowserCache",
       base::Bind(&NetInternalsMessageHandler::OnClearBrowserCache,
@@ -683,8 +682,8 @@
   PrePopulateEventList();
 
   // Register with network stack to observe events.
-  io_thread_->net_log()->DeprecatedAddObserver(this,
-      net::NetLog::LOG_ALL_BUT_BYTES);
+  io_thread_->net_log()->DeprecatedAddObserver(
+      this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
 }
 
 void NetInternalsMessageHandler::IOThreadImpl::OnGetNetInfo(
@@ -1070,20 +1069,25 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
-void NetInternalsMessageHandler::IOThreadImpl::OnSetLogLevel(
+void NetInternalsMessageHandler::IOThreadImpl::OnSetCaptureMode(
     const base::ListValue* list) {
-  int log_level;
-  std::string log_level_string;
-  if (!list->GetString(0, &log_level_string) ||
-      !base::StringToInt(log_level_string, &log_level)) {
+  std::string capture_mode_string;
+  if (!list->GetString(0, &capture_mode_string)) {
     NOTREACHED();
     return;
   }
 
-  DCHECK_GE(log_level, net::NetLog::LOG_ALL);
-  DCHECK_LT(log_level, net::NetLog::LOG_NONE);
-  net_log()->SetObserverLogLevel(
-      this, static_cast<net::NetLog::LogLevel>(log_level));
+  // Convert the string to a NetLogCaptureMode.
+  net::NetLogCaptureMode mode;
+  if (capture_mode_string == "IncludeSocketBytes") {
+    mode = net::NetLogCaptureMode::IncludeSocketBytes();
+  } else if (capture_mode_string == "IncludeCookiesAndCredentials") {
+    mode = net::NetLogCaptureMode::IncludeCookiesAndCredentials();
+  } else {
+    NOTREACHED();
+  }
+
+  net_log()->SetObserverCaptureMode(this, mode);
 }
 
 // Note that unlike other methods of IOThreadImpl, this function
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index 801ba18..69899bc 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -71,7 +71,6 @@
 using extensions::ExtensionPrefs;
 using extensions::ExtensionRegistry;
 using extensions::ExtensionSet;
-using extensions::UnloadedExtensionInfo;
 
 namespace {
 
@@ -104,7 +103,9 @@
     RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_SHOWN);
 }
 
-AppLauncherHandler::~AppLauncherHandler() {}
+AppLauncherHandler::~AppLauncherHandler() {
+  ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this);
+}
 
 void AppLauncherHandler::CreateAppInfo(
     const Extension* extension,
@@ -261,71 +262,6 @@
     return;
 
   switch (type) {
-    case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
-      const Extension* extension =
-          content::Details<const Extension>(details).ptr();
-      if (!extension->is_app())
-        return;
-
-      if (!extensions::ui_util::ShouldDisplayInNewTabPage(
-              extension, Profile::FromWebUI(web_ui()))) {
-        return;
-      }
-
-      scoped_ptr<base::DictionaryValue> app_info(GetAppInfo(extension));
-      if (app_info.get()) {
-        visible_apps_.insert(extension->id());
-
-        ExtensionPrefs* prefs =
-            ExtensionPrefs::Get(extension_service_->profile());
-        base::FundamentalValue highlight(
-            prefs->IsFromBookmark(extension->id()) &&
-            attempted_bookmark_app_install_);
-        attempted_bookmark_app_install_ = false;
-        web_ui()->CallJavascriptFunction("ntp.appAdded", *app_info, highlight);
-      }
-
-      break;
-    }
-    case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED:
-    case extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED: {
-      const Extension* extension = NULL;
-      bool uninstalled = false;
-      if (type == extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED) {
-        extension = content::Details<const Extension>(details).ptr();
-        uninstalled = true;
-      } else {  // NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED
-        if (content::Details<UnloadedExtensionInfo>(details)->reason ==
-            UnloadedExtensionInfo::REASON_UNINSTALL) {
-          // Uninstalls are tracked by
-          // NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED.
-          return;
-        }
-        extension = content::Details<extensions::UnloadedExtensionInfo>(
-            details)->extension;
-        uninstalled = false;
-      }
-      if (!extension->is_app())
-        return;
-
-      if (!extensions::ui_util::ShouldDisplayInNewTabPage(
-              extension, Profile::FromWebUI(web_ui()))) {
-        return;
-      }
-
-      scoped_ptr<base::DictionaryValue> app_info(GetAppInfo(extension));
-      if (app_info.get()) {
-        if (uninstalled)
-          visible_apps_.erase(extension->id());
-
-        web_ui()->CallJavascriptFunction(
-            "ntp.appRemoved",
-            *app_info,
-            base::FundamentalValue(uninstalled),
-            base::FundamentalValue(!extension_id_prompting_.empty()));
-      }
-      break;
-    }
     case chrome::NOTIFICATION_APP_LAUNCHER_REORDERED: {
       const std::string* id =
           content::Details<const std::string>(details).ptr();
@@ -364,6 +300,38 @@
   }
 }
 
+void AppLauncherHandler::OnExtensionLoaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension) {
+  if (!ShouldShow(extension))
+    return;
+
+  scoped_ptr<base::DictionaryValue> app_info(GetAppInfo(extension));
+  if (!app_info.get())
+    return;
+
+  visible_apps_.insert(extension->id());
+  ExtensionPrefs* prefs = ExtensionPrefs::Get(extension_service_->profile());
+  base::FundamentalValue highlight(prefs->IsFromBookmark(extension->id()) &&
+                                   attempted_bookmark_app_install_);
+  attempted_bookmark_app_install_ = false;
+  web_ui()->CallJavascriptFunction("ntp.appAdded", *app_info, highlight);
+}
+
+void AppLauncherHandler::OnExtensionUnloaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    extensions::UnloadedExtensionInfo::Reason reason) {
+  AppRemoved(extension, false);
+}
+
+void AppLauncherHandler::OnExtensionUninstalled(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    extensions::UninstallReason reason) {
+  AppRemoved(extension, true);
+}
+
 void AppLauncherHandler::FillAppDictionary(base::DictionaryValue* dictionary) {
   // CreateAppInfo and ClearOrdinals can change the extension prefs.
   base::AutoReset<bool> auto_reset(&ignore_changes_, true);
@@ -462,15 +430,7 @@
         extensions::pref_names::kExtensions, callback);
     extension_pref_change_registrar_.Add(prefs::kNtpAppPageNames, callback);
 
-    registrar_.Add(this,
-                   extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
-                   content::Source<Profile>(profile));
-    registrar_.Add(this,
-                   extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
-                   content::Source<Profile>(profile));
-    registrar_.Add(this,
-                   extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED,
-                   content::Source<Profile>(profile));
+    ExtensionRegistry::Get(profile)->AddObserver(this);
     registrar_.Add(this,
                    chrome::NOTIFICATION_APP_LAUNCHER_REORDERED,
                    content::Source<AppSorting>(
@@ -875,3 +835,25 @@
   }
   return extension_uninstall_dialog_.get();
 }
+
+void AppLauncherHandler::AppRemoved(const Extension* extension,
+                                    bool is_uninstall) {
+  if (!ShouldShow(extension))
+    return;
+
+  scoped_ptr<base::DictionaryValue> app_info(GetAppInfo(extension));
+  if (!app_info.get())
+    return;
+
+  web_ui()->CallJavascriptFunction(
+      "ntp.appRemoved", *app_info, base::FundamentalValue(is_uninstall),
+      base::FundamentalValue(!extension_id_prompting_.empty()));
+}
+
+bool AppLauncherHandler::ShouldShow(const Extension* extension) const {
+  if (ignore_changes_ || !has_loaded_apps_ || !extension->is_app())
+    return false;
+
+  Profile* profile = Profile::FromWebUI(web_ui());
+  return extensions::ui_util::ShouldDisplayInNewTabPage(extension, profile);
+}
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
index 0e31f88..85c451e 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
@@ -19,6 +19,7 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_ui_message_handler.h"
+#include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/extension.h"
 #include "sync/api/string_ordinal.h"
 
@@ -36,7 +37,8 @@
     : public content::WebUIMessageHandler,
       public extensions::ExtensionUninstallDialog::Delegate,
       public ExtensionEnableFlowDelegate,
-      public content::NotificationObserver {
+      public content::NotificationObserver,
+      public extensions::ExtensionRegistryObserver {
  public:
   explicit AppLauncherHandler(ExtensionService* extension_service);
   ~AppLauncherHandler() override;
@@ -47,14 +49,25 @@
       ExtensionService* service,
       base::DictionaryValue* value);
 
-  // WebUIMessageHandler implementation.
+  // WebUIMessageHandler:
   void RegisterMessages() override;
 
-  // content::NotificationObserver
+  // content::NotificationObserver:
   void Observe(int type,
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
+  // extensions::ExtensionRegistryObserver:
+  void OnExtensionLoaded(content::BrowserContext* browser_context,
+                         const extensions::Extension* extension) override;
+  void OnExtensionUnloaded(
+      content::BrowserContext* browser_context,
+      const extensions::Extension* extension,
+      extensions::UnloadedExtensionInfo::Reason reason) override;
+  void OnExtensionUninstalled(content::BrowserContext* browser_context,
+                              const extensions::Extension* extension,
+                              extensions::UninstallReason reason) override;
+
   // Populate the given dictionary with all installed app info.
   void FillAppDictionary(base::DictionaryValue* value);
 
@@ -149,6 +162,12 @@
 
   void OnLocalStatePreferenceChanged();
 
+  // Called when an app is removed (unloaded or uninstalled). Updates the UI.
+  void AppRemoved(const extensions::Extension* extension, bool is_uninstall);
+
+  // True if the extension should be displayed.
+  bool ShouldShow(const extensions::Extension* extension) const;
+
   // The apps are represented in the extensions model, which
   // outlives us since it's owned by our containing profile.
   ExtensionService* const extension_service_;
diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.cc b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
index cff19a6..e8e8a3f 100644
--- a/chrome/browser/ui/webui/ntp/most_visited_handler.cc
+++ b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
@@ -21,7 +21,7 @@
 #include "base/threading/thread.h"
 #include "base/values.h"
 #include "chrome/browser/favicon/fallback_icon_service_factory.h"
-#include "chrome/browser/favicon/favicon_service_factory.h"
+#include "chrome/browser/favicon/large_icon_service_factory.h"
 #include "chrome/browser/history/top_sites_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/thumbnails/thumbnail_list_source.h"
@@ -38,7 +38,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/favicon/core/fallback_icon_service.h"
-#include "components/favicon/core/favicon_service.h"
+#include "components/favicon/core/large_icon_service.h"
 #include "components/history/core/browser/page_usage_data.h"
 #include "components/history/core/browser/top_sites.h"
 #include "components/keyed_service/core/service_access_type.h"
@@ -86,15 +86,12 @@
   // Set up our sources for top-sites data.
   content::URLDataSource::Add(profile, new ThumbnailListSource(profile));
 
-  favicon::FaviconService* favicon_service =
-      FaviconServiceFactory::GetForProfile(profile,
-                                           ServiceAccessType::EXPLICIT_ACCESS);
   favicon::FallbackIconService* fallback_icon_service =
       FallbackIconServiceFactory::GetForBrowserContext(profile);
+  favicon::LargeIconService* large_icon_service =
+      LargeIconServiceFactory::GetForBrowserContext(profile);
 
-  // Register chrome://large-icon as a data source for large icons.
-  content::URLDataSource::Add(profile,
-      new LargeIconSource(favicon_service, fallback_icon_service));
+  // Register chrome://fallback-icon as a data source for fallback icons.
   content::URLDataSource::Add(profile,
                               new FallbackIconSource(fallback_icon_service));
 
@@ -102,6 +99,10 @@
   content::URLDataSource::Add(
       profile, new FaviconSource(profile, FaviconSource::FAVICON));
 
+  // Register chrome://large-icon as a data source for large icons.
+  content::URLDataSource::Add(
+      profile, new LargeIconSource(fallback_icon_service, large_icon_service));
+
   scoped_refptr<history::TopSites> top_sites =
       TopSitesFactory::GetForProfile(profile);
   if (top_sites) {
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index f19127f..d1f6f6f0 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -69,7 +69,6 @@
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/locale_settings.h"
-#include "chromeos/chromeos_switches.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_namespace.h"
 #include "components/policy/core/common/policy_service.h"
@@ -120,6 +119,7 @@
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/policy/profile_policy_connector_factory.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager_client.h"
 #include "components/user_manager/user.h"
diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
index 2af44e0f..b6de55d1 100644
--- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
@@ -77,9 +77,7 @@
 }  // namespace
 
 ChangePictureOptionsHandler::ChangePictureOptionsHandler()
-    : ImageRequest(
-          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
-      previous_image_url_(url::kAboutBlankURL),
+    : previous_image_url_(url::kAboutBlankURL),
       previous_image_index_(user_manager::User::USER_IMAGE_INVALID) {
   registrar_.Add(this, chrome::NOTIFICATION_PROFILE_IMAGE_UPDATED,
       content::NotificationService::AllSources());
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
index d354743..ca4cc50 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
@@ -124,7 +124,7 @@
 
 base::DictionaryValue* ConvertDisplayModeToValue(int64 display_id,
                                                  const ash::DisplayMode& mode) {
-  bool is_internal = GetDisplayManager()->IsInternalDisplayId(display_id);
+  bool is_internal = gfx::Display::InternalDisplayId() == display_id;
   base::DictionaryValue* result = new base::DictionaryValue();
   gfx::Size size_dip = mode.GetSizeInDIP(is_internal);
   result->SetInteger("width", size_dip.width());
@@ -260,7 +260,7 @@
 void DisplayOptionsHandler::SendDisplayInfo(
     const std::vector<gfx::Display>& displays) {
   DisplayManager* display_manager = GetDisplayManager();
-  base::FundamentalValue mirroring(display_manager->IsMirrored());
+  base::FundamentalValue mirroring(display_manager->IsInMirrorMode());
 
   int64 primary_id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
   base::ListValue js_displays;
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
index 774433f..036770a 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
@@ -13,16 +13,10 @@
 #include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/mobile_config.h"
-#include "chrome/browser/chromeos/net/onc_utils.h"
 #include "chrome/browser/chromeos/options/network_config_view.h"
-#include "chrome/browser/chromeos/options/network_property_ui_data.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
@@ -32,23 +26,9 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h"
-#include "chromeos/chromeos_switches.h"
 #include "chromeos/login/login_state.h"
-#include "chromeos/network/device_state.h"
-#include "chromeos/network/managed_network_configuration_handler.h"
-#include "chromeos/network/network_connection_handler.h"
-#include "chromeos/network/network_device_handler.h"
-#include "chromeos/network/network_event_log.h"
-#include "chromeos/network/network_ip_config.h"
-#include "chromeos/network/network_profile.h"
-#include "chromeos/network/network_profile_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
-#include "chromeos/network/network_util.h"
-#include "chromeos/network/onc/onc_signature.h"
-#include "chromeos/network/onc/onc_translation_tables.h"
-#include "chromeos/network/onc/onc_translator.h"
-#include "chromeos/network/onc/onc_utils.h"
 #include "components/onc/onc_constants.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/web_contents.h"
@@ -74,26 +54,14 @@
 // Keys for the initial "localized" dictionary values.
 const char kLoggedInAsOwnerKey[] = "loggedInAsOwner";
 const char kShowCarrierSelectKey[] = "showCarrierSelect";
-const char kNetworkDataKey[] = "networkData";
-
-// Keys for the network description dictionary passed to the web ui. Make sure
-// to keep the strings in sync with what the JavaScript side uses.
-const char kNetworkInfoKeyPolicyManaged[] = "policyManaged";
 
 // Functions we call in JavaScript.
 const char kSetVPNProvidersFunction[] = "options.VPNProviders.setProviders";
-const char kRefreshNetworkDataFunction[] =
-    "options.network.NetworkList.refreshNetworkData";
-const char kUpdateConnectionDataFunction[] =
-    "options.internet.DetailsInternetPage.updateConnectionData";
 
 // JS methods to show additional UI.
 const char kShowMorePlanInfoMessage[] = "showMorePlanInfo";
 const char kSimOperationMessage[] = "simOperation";
 
-// TODO(stevenjb): Deprecate this once we handle events in the JS.
-const char kSetNetworkGuidMessage[] = "setNetworkGuid";
-
 // TODO(stevenjb): Deprecate these and integrate with settings Web UI.
 const char kAddVPNConnectionMessage[] = "addVPNConnection";
 const char kAddNonVPNConnectionMessage[] = "addNonVPNConnection";
@@ -102,10 +70,6 @@
 const char kLoadVPNProviders[] = "loadVPNProviders";
 
 // These are strings used to communicate with JavaScript.
-const char kTagCellularSimAbsent[] = "cellularSimAbsent";
-const char kTagCellularSimLockType[] = "cellularSimLockType";
-const char kTagCellularSupportsScan[] = "cellularSupportsScan";
-const char kTagRememberedList[] = "rememberedList";
 const char kTagSimOpChangePin[] = "changePin";
 const char kTagSimOpConfigure[] = "configure";
 const char kTagSimOpSetLocked[] = "setLocked";
@@ -113,21 +77,6 @@
 const char kTagSimOpUnlock[] = "unlock";
 const char kTagVPNProviderName[] = "name";
 const char kTagVPNProviderExtensionID[] = "extensionID";
-const char kTagVpnList[] = "vpnList";
-const char kTagWiredList[] = "wiredList";
-const char kTagWirelessList[] = "wirelessList";
-
-void ShillError(const std::string& function,
-                const std::string& error_name,
-                scoped_ptr<base::DictionaryValue> error_data) {
-  // UpdateConnectionData may send requests for stale services; ignore
-  // these errors.
-  if (function == "UpdateConnectionData" &&
-      error_name == network_handler::kDBusFailedError)
-    return;
-  NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name,
-                function);
-}
 
 const NetworkState* GetNetworkState(const std::string& service_path) {
   return NetworkHandler::Get()->network_state_handler()->
@@ -141,22 +90,6 @@
   return network ? network->path() : "";
 }
 
-// Builds a dictionary with network information for the NetworkList on the
-// settings page. Ownership of the returned pointer is transferred to the
-// caller. TODO(stevenjb): Replace with calls to networkingPrivate.getNetworks.
-base::DictionaryValue* BuildNetworkDictionary(
-    const NetworkState* network,
-    const PrefService* profile_prefs) {
-  scoped_ptr<base::DictionaryValue> network_info =
-      network_util::TranslateNetworkStateToONC(network);
-
-  bool has_policy = onc::HasPolicyForNetwork(
-      profile_prefs, g_browser_process->local_state(), *network);
-  network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, has_policy);
-
-  return network_info.release();
-}
-
 bool IsVPNProvider(const extensions::Extension* extension) {
   return extension->permissions_data()->HasAPIPermission(
       extensions::APIPermission::kVpnProvider);
@@ -188,14 +121,9 @@
 InternetOptionsHandler::InternetOptionsHandler()
     : weak_factory_(this) {
   GetExtensionRegistryForPrimaryUser()->AddObserver(this);
-  NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
 }
 
 InternetOptionsHandler::~InternetOptionsHandler() {
-  if (NetworkHandler::IsInitialized()) {
-    NetworkHandler::Get()->network_state_handler()->RemoveObserver(
-        this, FROM_HERE);
-  }
   GetExtensionRegistryForPrimaryUser()->RemoveObserver(this);
 }
 
@@ -213,18 +141,11 @@
   localized_strings->SetBoolean(kLoggedInAsOwnerKey, logged_in_as_owner);
   // TODO(anujsharma): Remove kShowCarrierSelectKey, as it is not
   // required anymore.
-  localized_strings->SetBoolean(
-      kShowCarrierSelectKey, false);
-
-  base::DictionaryValue* network_dictionary = new base::DictionaryValue;
-  FillNetworkInfo(network_dictionary);
-  localized_strings->Set(kNetworkDataKey, network_dictionary);
+  localized_strings->SetBoolean(kShowCarrierSelectKey, false);
 }
 
 void InternetOptionsHandler::InitializePage() {
   UpdateVPNProviders();
-  NetworkHandler::Get()->network_state_handler()->RequestScan();
-  RefreshNetworkData();
 }
 
 void InternetOptionsHandler::RegisterMessages() {
@@ -247,10 +168,6 @@
       kLoadVPNProviders,
       base::Bind(&InternetOptionsHandler::LoadVPNProvidersCallback,
                  base::Unretained(this)));
-
-  web_ui()->RegisterMessageCallback(kSetNetworkGuidMessage,
-      base::Bind(&InternetOptionsHandler::SetNetworkGuidCallback,
-                 base::Unretained(this)));
 }
 
 void InternetOptionsHandler::OnExtensionLoaded(
@@ -320,19 +237,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// TODO(stevenjb): Deprecate this once events are handled in the JS.
-
-void InternetOptionsHandler::SetNetworkGuidCallback(
-    const base::ListValue* args) {
-  std::string guid;
-  if (args->GetSize() != 1 || !args->GetString(0, &guid)) {
-    NOTREACHED();
-    return;
-  }
-  details_guid_ = guid;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 
 void InternetOptionsHandler::UpdateVPNProviders() {
   extensions::ExtensionRegistry* const registry =
@@ -354,73 +258,6 @@
   web_ui()->CallJavascriptFunction(kSetVPNProvidersFunction, vpn_providers);
 }
 
-void InternetOptionsHandler::RefreshNetworkData() {
-  base::DictionaryValue dictionary;
-  FillNetworkInfo(&dictionary);
-  web_ui()->CallJavascriptFunction(kRefreshNetworkDataFunction, dictionary);
-}
-
-void InternetOptionsHandler::UpdateConnectionData(
-    const std::string& service_path) {
-  NetworkHandler::Get()
-      ->managed_network_configuration_handler()
-      ->GetManagedProperties(
-          LoginState::Get()->primary_user_hash(), service_path,
-          base::Bind(&InternetOptionsHandler::GetManagedPropertiesResult,
-                     weak_factory_.GetWeakPtr(), kUpdateConnectionDataFunction),
-          base::Bind(&ShillError, "UpdateConnectionData"));
-}
-
-void InternetOptionsHandler::GetManagedPropertiesResult(
-    const std::string& js_callback_function,
-    const std::string& service_path,
-    const base::DictionaryValue& onc_properties) {
-  scoped_ptr<base::DictionaryValue> dictionary(onc_properties.DeepCopy());
-  web_ui()->CallJavascriptFunction(js_callback_function, *dictionary);
-}
-
-void InternetOptionsHandler::DeviceListChanged() {
-  if (!web_ui())
-    return;
-  RefreshNetworkData();
-}
-
-void InternetOptionsHandler::NetworkListChanged() {
-  if (!web_ui())
-    return;
-  RefreshNetworkData();
-}
-
-void InternetOptionsHandler::NetworkConnectionStateChanged(
-    const NetworkState* network) {
-  if (!web_ui())
-    return;
-  if (network->guid() == details_guid_)
-    UpdateConnectionData(network->path());
-}
-
-void InternetOptionsHandler::NetworkPropertiesUpdated(
-    const NetworkState* network) {
-  if (!web_ui())
-    return;
-  RefreshNetworkData();
-  if (network->guid() == details_guid_)
-    UpdateConnectionData(network->path());
-}
-
-void InternetOptionsHandler::DevicePropertiesUpdated(
-    const DeviceState* device) {
-  if (!web_ui())
-    return;
-  if (device->type() != shill::kTypeCellular)
-    return;
-  const NetworkState* network =
-      NetworkHandler::Get()->network_state_handler()->FirstNetworkByType(
-          NetworkTypePattern::Cellular());
-  if (network && network->path() == details_guid_)
-    UpdateConnectionData(network->path());
-}
-
 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
   return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
 }
@@ -496,84 +333,5 @@
   UpdateVPNProviders();
 }
 
-base::ListValue* InternetOptionsHandler::GetWiredList() {
-  base::ListValue* list = new base::ListValue();
-  const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
-      FirstNetworkByType(NetworkTypePattern::Ethernet());
-  if (!network)
-    return list;
-  list->Append(BuildNetworkDictionary(network, GetPrefs()));
-  return list;
-}
-
-base::ListValue* InternetOptionsHandler::GetWirelessList() {
-  base::ListValue* list = new base::ListValue();
-
-  NetworkStateHandler::NetworkStateList networks;
-  NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
-      NetworkTypePattern::Wireless(), &networks);
-  for (NetworkStateHandler::NetworkStateList::const_iterator iter =
-           networks.begin(); iter != networks.end(); ++iter) {
-    list->Append(BuildNetworkDictionary(*iter, GetPrefs()));
-  }
-
-  return list;
-}
-
-base::ListValue* InternetOptionsHandler::GetVPNList() {
-  base::ListValue* list = new base::ListValue();
-
-  NetworkStateHandler::NetworkStateList networks;
-  NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
-      NetworkTypePattern::VPN(), &networks);
-  for (NetworkStateHandler::NetworkStateList::const_iterator iter =
-           networks.begin(); iter != networks.end(); ++iter) {
-    list->Append(BuildNetworkDictionary(*iter, GetPrefs()));
-  }
-
-  return list;
-}
-
-base::ListValue* InternetOptionsHandler::GetRememberedList() {
-  base::ListValue* list = new base::ListValue();
-
-  NetworkStateHandler::NetworkStateList networks;
-  NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
-      NetworkTypePattern::Default(),
-      true /* configured_only */,
-      false /* visible_only */,
-      0 /* no limit */,
-      &networks);
-  for (NetworkStateHandler::NetworkStateList::const_iterator iter =
-           networks.begin(); iter != networks.end(); ++iter) {
-    const NetworkState* network = *iter;
-    if (network->type() != shill::kTypeWifi &&
-        network->type() != shill::kTypeVPN) {
-      continue;
-    }
-    list->Append(BuildNetworkDictionary(network, GetPrefs()));
-  }
-
-  return list;
-}
-
-void InternetOptionsHandler::FillNetworkInfo(
-    base::DictionaryValue* dictionary) {
-  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-  dictionary->Set(kTagWiredList, GetWiredList());
-  dictionary->Set(kTagWirelessList, GetWirelessList());
-  dictionary->Set(kTagVpnList, GetVPNList());
-  dictionary->Set(kTagRememberedList, GetRememberedList());
-
-  const DeviceState* cellular =
-      handler->GetDeviceStateByType(NetworkTypePattern::Mobile());
-  dictionary->SetBoolean(kTagCellularSupportsScan,
-                         cellular && cellular->support_network_scan());
-  dictionary->SetBoolean(kTagCellularSimAbsent,
-                         cellular && cellular->IsSimAbsent());
-  dictionary->SetString(kTagCellularSimLockType,
-                        cellular ? cellular->sim_lock_type() : "");
-}
-
 }  // namespace options
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
index c7e91887..17c3030 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
@@ -10,19 +10,12 @@
 #include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/webui/options/options_ui.h"
-#include "chromeos/network/network_state_handler_observer.h"
 #include "extensions/browser/extension_registry_observer.h"
 #include "ui/gfx/native_widget_types.h"
 
 class Browser;
 class PrefService;
 
-namespace chromeos {
-class DeviceState;
-class NetworkState;
-class NetworkStateHandlerObserver;
-}
-
 namespace gfx {
 class ImageSkia;
 }
@@ -36,7 +29,6 @@
 
 // ChromeOS internet options page UI handler.
 class InternetOptionsHandler : public ::options::OptionsPageUIHandler,
-                               public chromeos::NetworkStateHandlerObserver,
                                public extensions::ExtensionRegistryObserver {
  public:
   InternetOptionsHandler();
@@ -63,39 +55,9 @@
   void ShowMorePlanInfoCallback(const base::ListValue* args);
   void SimOperationCallback(const base::ListValue* args);
 
-  // Sets details_guid_ for event forwarding.
-  void SetNetworkGuidCallback(const base::ListValue* args);
-
-  // networkingPrvate callbacks
-  void GetManagedPropertiesCallback(const base::ListValue* args);
-
   // Updates the list of VPN providers enabled in the primary user's profile.
   void UpdateVPNProviders();
 
-  // Refreshes the display of network information.
-  void RefreshNetworkData();
-
-  // Updates the display of network connection information for the details page
-  // if visible.
-  void UpdateConnectionData(const std::string& service_path);
-
-  // Callback for ManagedNetworkConnectionHandler::GetManagedProperties.
-  // Calls the JS callback |js_callback_function| with the result.
-  void GetManagedPropertiesResult(const std::string& js_callback_function,
-                                  const std::string& service_path,
-                                  const base::DictionaryValue& onc_properties);
-
-  // NetworkStateHandlerObserver
-  void DeviceListChanged() override;
-  void NetworkListChanged() override;
-  void NetworkConnectionStateChanged(
-      const chromeos::NetworkState* network) override;
-  void NetworkPropertiesUpdated(const chromeos::NetworkState* network) override;
-  void DevicePropertiesUpdated(const chromeos::DeviceState* device) override;
-
-  // Updates the logged in user type.
-  void UpdateLoggedInUserType();
-
   // Gets the native window for hosting dialogs, etc.
   gfx::NativeWindow GetNativeWindow() const;
 
@@ -111,24 +73,6 @@
   // profile be sent to JavaScript.
   void LoadVPNProvidersCallback(const base::ListValue* args);
 
-  // Creates the map of wired networks.
-  base::ListValue* GetWiredList();
-
-  // Creates the map of wireless networks.
-  base::ListValue* GetWirelessList();
-
-  // Creates the map of virtual networks.
-  base::ListValue* GetVPNList();
-
-  // Creates the map of remembered networks.
-  base::ListValue* GetRememberedList();
-
-  // Fills network information into JS dictionary for displaying network lists.
-  void FillNetworkInfo(base::DictionaryValue* dictionary);
-
-  // Keep track of the service path for the network shown in the Details view.
-  std::string details_guid_;
-
   // Weak pointer factory so we can start connections at a later time
   // without worrying that they will actually try to happen after the lifetime
   // of this object.
diff --git a/chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.cc b/chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.cc
index f431323..1c688bb 100644
--- a/chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.cc
+++ b/chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.cc
@@ -186,8 +186,7 @@
 void ProfileSigninConfirmationDialog::OnCloseContents(
     content::WebContents* source,
     bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+  *out_close_dialog = true;
 }
 
 bool ProfileSigninConfirmationDialog::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index 627d78f..55b69307 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -383,7 +383,7 @@
     const ShortcutLocations& locations,
     scoped_ptr<ShortcutInfo> shortcut_info,
     const extensions::FileHandlersInfo& file_handlers_info) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // If the shortcut is for an application shortcut with the new bookmark app
   // flow disabled, there will be no corresponding extension.
@@ -419,7 +419,7 @@
                      const ShortcutLocations& locations,
                      Profile* profile,
                      const extensions::Extension* app) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (!ShouldCreateShortcutFor(reason, profile, app))
     return;
@@ -429,7 +429,7 @@
 }
 
 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   scoped_ptr<ShortcutInfo> shortcut_info(
       ShortcutInfoForExtensionAndProfile(app, profile));
@@ -443,7 +443,7 @@
 void UpdateAllShortcuts(const base::string16& old_app_title,
                         Profile* profile,
                         const extensions::Extension* app) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   GetInfoForApp(app,
                 profile,
diff --git a/chrome/browser/web_applications/web_app_linux.cc b/chrome/browser/web_applications/web_app_linux.cc
index e6636dd..193375c 100644
--- a/chrome/browser/web_applications/web_app_linux.cc
+++ b/chrome/browser/web_applications/web_app_linux.cc
@@ -25,7 +25,7 @@
     const ShortcutLocations& creation_locations,
     ShortcutCreationReason /*creation_reason*/) {
 #if !defined(OS_CHROMEOS)
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   return shell_integration_linux::CreateDesktopShortcut(*shortcut_info,
                                                         creation_locations);
 #else
@@ -46,7 +46,7 @@
     const base::string16& /*old_app_title*/,
     scoped_ptr<ShortcutInfo> shortcut_info,
     const extensions::FileHandlersInfo& file_handlers_info) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   scoped_ptr<base::Environment> env(base::Environment::Create());
 
diff --git a/chrome/browser/web_applications/web_app_mac.mm b/chrome/browser/web_applications/web_app_mac.mm
index 6c80590..aaa8446 100644
--- a/chrome/browser/web_applications/web_app_mac.mm
+++ b/chrome/browser/web_applications/web_app_mac.mm
@@ -221,7 +221,7 @@
 
 void LaunchShimOnFileThread(scoped_ptr<web_app::ShortcutInfo> shortcut_info,
                             bool launched_after_rebuild) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   base::FilePath shim_path = web_app::GetAppInstallPath(*shortcut_info);
 
   if (shim_path.empty() ||
@@ -258,7 +258,7 @@
     const base::string16& old_app_title,
     const web_app::ShortcutInfo& shortcut_info,
     const extensions::FileHandlersInfo& file_handlers_info) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   if (AppShimsDisabledForTest() &&
       !g_app_shims_allow_update_and_launch_in_tests) {
     return;
@@ -1153,7 +1153,7 @@
     const extensions::FileHandlersInfo& file_handlers_info,
     const ShortcutLocations& creation_locations,
     ShortcutCreationReason creation_reason) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   if (AppShimsDisabledForTest())
     return true;
 
@@ -1164,7 +1164,7 @@
 
 void DeletePlatformShortcuts(const base::FilePath& app_data_path,
                              scoped_ptr<ShortcutInfo> shortcut_info) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info.get(),
                                          extensions::FileHandlersInfo());
   shortcut_creator.DeleteShortcuts();
diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc
index 2630c61..b9cd61e2 100644
--- a/chrome/browser/web_applications/web_app_win.cc
+++ b/chrome/browser/web_applications/web_app_win.cc
@@ -287,7 +287,7 @@
     const base::string16& title,
     bool* was_pinned_to_taskbar,
     std::vector<base::FilePath>* shortcut_paths) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK(content::BrowserThread::FILE);
 
   // Get all possible locations for shortcuts.
   web_app::ShortcutLocations all_shortcut_locations;
@@ -584,7 +584,7 @@
     const extensions::FileHandlersInfo& file_handlers_info,
     const ShortcutLocations& creation_locations,
     ShortcutCreationReason creation_reason) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   // Nothing to do on Windows for hidden apps.
   if (creation_locations.applications_menu_location == APP_MENU_LOCATION_HIDDEN)
@@ -636,7 +636,7 @@
     const base::string16& old_app_title,
     scoped_ptr<ShortcutInfo> shortcut_info,
     const extensions::FileHandlersInfo& file_handlers_info) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   // Generates file name to use with persisted ico and shortcut file.
   base::FilePath file_name =
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 82d534d4..0ba338a3 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -174,8 +174,8 @@
       'browser/android/tab_state.h',
       'browser/android/thumbnail/thumbnail.cc',
       'browser/android/thumbnail/thumbnail.h',
-      'browser/android/thumbnail/thumbnail_store.cc',
-      'browser/android/thumbnail/thumbnail_store.h',
+      'browser/android/thumbnail/thumbnail_cache.cc',
+      'browser/android/thumbnail/thumbnail_cache.h',
       'browser/android/transition_page_helper.cc',
       'browser/android/transition_page_helper.h',
       'browser/android/url_utilities.cc',
@@ -1336,6 +1336,14 @@
       'browser/content_settings/web_site_settings_uma_util.cc',
       'browser/content_settings/web_site_settings_uma_util.h',
     ],
+    'chrome_browser_engagement_sources': [
+      'browser/engagement/site_engagement_helper.cc',
+      'browser/engagement/site_engagement_helper.h',
+      'browser/engagement/site_engagement_service.cc',
+      'browser/engagement/site_engagement_service.h',
+      'browser/engagement/site_engagement_service_factory.cc',
+      'browser/engagement/site_engagement_service_factory.h',
+    ],
     'chrome_browser_extensions_sources': [
       'browser/accessibility/accessibility_extension_api.cc',
       'browser/accessibility/accessibility_extension_api.h',
@@ -1552,6 +1560,8 @@
       'browser/favicon/favicon_helper.h',
       'browser/favicon/favicon_service_factory.cc',
       'browser/favicon/favicon_service_factory.h',
+      'browser/favicon/large_icon_service_factory.cc',
+      'browser/favicon/large_icon_service_factory.h',
     ],
     'chrome_browser_gnome_keyring_sources': [
       'browser/password_manager/native_backend_gnome_x.cc',
@@ -2528,6 +2538,10 @@
       'browser/services/gcm/gcm_profile_service.h',
       'browser/services/gcm/gcm_profile_service_factory.cc',
       'browser/services/gcm/gcm_profile_service_factory.h',
+      'browser/services/gcm/instance_id/instance_id_profile_service.cc',
+      'browser/services/gcm/instance_id/instance_id_profile_service.h',
+      'browser/services/gcm/instance_id/instance_id_profile_service_factory.cc',
+      'browser/services/gcm/instance_id/instance_id_profile_service_factory.h',
     ],
     'chrome_browser_session_sources': [
       'browser/sessions/base_session_service_delegate.h',
@@ -3141,6 +3155,7 @@
             '<@(chrome_browser_bookmark_sources)',
             '<@(chrome_browser_browser_process_sources)',
             '<@(chrome_browser_content_settings_sources)',
+            '<@(chrome_browser_engagement_sources)',
             '<@(chrome_browser_favicon_sources)',
             '<@(chrome_browser_google_sources)',
             '<@(chrome_browser_history_sources)',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 7f895c5..3331795 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -1979,6 +1979,8 @@
       'browser/ui/views/apps/app_window_desktop_native_widget_aura_win.h',
       'browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc',
       'browser/ui/views/apps/app_window_desktop_window_tree_host_win.h',
+      'browser/ui/views/apps/app_window_easy_resize_window_targeter.cc',
+      'browser/ui/views/apps/app_window_easy_resize_window_targeter.h',
       'browser/ui/views/apps/chrome_app_window_client_views_win.cc',
       'browser/ui/views/apps/chrome_native_app_window_views_aura.cc',
       'browser/ui/views/apps/chrome_native_app_window_views_aura.h',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 2f7ccad..7faa5e6 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -634,45 +634,33 @@
         }, {  # OS == ios
           'sources!': [
             'common/net/net_resource_provider.cc',
+          ],
+        }],
+        ['OS == "android" or OS == "ios"', {
+          'sources!': [
             'common/net/x509_certificate_model.cc',
           ],
         }],
-        ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
-            'dependencies': [
-              '../build/linux/system.gyp:ssl',
-            ],
-          },
-        ],
-        ['os_posix != 1 or OS == "mac" or OS == "ios"', {
-            'sources!': [
-              'common/net/x509_certificate_model_nss.cc',
-              'common/net/x509_certificate_model_openssl.cc',
-            ],
-          },
-        ],
-        ['OS == "android"', {
-            'dependencies': [
-              '../third_party/boringssl/boringssl.gyp:boringssl',
-            ],
-            'sources!': [
-              'common/net/x509_certificate_model.cc',
-              'common/net/x509_certificate_model_openssl.cc',
-            ],
-        }],
-        ['use_openssl==1', {
-            'sources!': [
-              'common/net/x509_certificate_model_nss.cc',
-            ],
+        ['use_openssl_certs == 1 and OS != "android"', {
             'dependencies': [
               '<(DEPTH)/third_party/boringssl/boringssl.gyp:boringssl',
             ],
-          },
-          {  # else !use_openssl: remove the unneeded files
+        }, {
             'sources!': [
               'common/net/x509_certificate_model_openssl.cc',
             ],
           },
         ],
+        ['use_nss_certs == 1', {
+            'dependencies': [
+              '../build/linux/system.gyp:ssl',
+            ],
+        }, {
+            'sources!': [
+              'common/net/x509_certificate_model_nss.cc',
+            ],
+          },
+        ],
         ['OS=="win"', {
             # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
             'msvs_disabled_warnings': [4267, ],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index fdc032a..190001f 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -292,6 +292,7 @@
       'browser/history/history_browsertest.cc',
       'browser/history/redirect_browsertest.cc',
       'browser/iframe_browsertest.cc',
+      'browser/image_decoder_browsertest.cc',
       'browser/importer/firefox_importer_browsertest.cc',
       'browser/importer/ie_importer_browsertest_win.cc',
       'browser/importer/importer_unittest_utils.cc',
@@ -459,6 +460,7 @@
       'browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_unittest.mm',
       'browser/ui/cocoa/dev_tools_controller_browsertest.mm',
       'browser/ui/cocoa/extensions/extension_install_dialog_controller_browsertest.mm',
+      'browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm',
       'browser/ui/cocoa/extensions/extension_install_prompt_test_utils.h',
       'browser/ui/cocoa/extensions/extension_install_prompt_test_utils.mm',
       'browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_browsertest.mm',
@@ -474,6 +476,8 @@
       'browser/ui/cocoa/view_id_util_browsertest.mm',
       'browser/ui/content_settings/content_setting_bubble_model_browsertest.cc',
       'browser/ui/exclusive_access/fullscreen_controller_browsertest.cc',
+      'browser/ui/extensions/extension_message_bubble_browsertest.cc',
+      'browser/ui/extensions/extension_message_bubble_browsertest.h',
       'browser/ui/extensions/bookmark_app_browsertest.cc',
       'browser/ui/find_bar/find_bar_host_browsertest.cc',
       'browser/ui/global_error/global_error_service_browsertest.cc',
@@ -727,6 +731,8 @@
       'browser/chromeos/login/wizard_controller_browsertest.cc',
       'browser/chromeos/memory/oom_priority_manager_browsertest.cc',
       'browser/chromeos/net/network_portal_detector_impl_browsertest.cc',
+      'browser/chromeos/ownership/fake_owner_settings_service.cc',
+      'browser/chromeos/ownership/fake_owner_settings_service.h',
       'browser/chromeos/policy/blocking_login_browsertest.cc',
       'browser/chromeos/policy/device_cloud_policy_browsertest.cc',
       'browser/chromeos/policy/device_local_account_browsertest.cc',
@@ -740,12 +746,15 @@
       'browser/chromeos/policy/login_screen_default_policy_browsertest.cc',
       'browser/chromeos/policy/policy_cert_verifier_browsertest.cc',
       'browser/chromeos/policy/power_policy_browsertest.cc',
+      'browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc',
       'browser/chromeos/policy/user_cloud_external_data_manager_browsertest.cc',
       'browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc',
       'browser/chromeos/policy/variations_service_policy_browsertest.cc',
       'browser/chromeos/power/peripheral_battery_observer_browsertest.cc',
       'browser/chromeos/preferences_browsertest.cc',
       'browser/chromeos/profiles/profile_helper_browsertest.cc',
+      'browser/chromeos/settings/scoped_cros_settings_test_helper.cc',
+      'browser/chromeos/settings/scoped_cros_settings_test_helper.h',
       'browser/chromeos/shutdown_policy_browsertest.cc',
       'browser/chromeos/system/device_disabling_browsertest.cc',
       'browser/chromeos/system/tray_accessibility_browsertest.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 948a773..a5ac421 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -94,6 +94,7 @@
       'browser/download/download_ui_controller_unittest.cc',
       'browser/enumerate_modules_model_unittest_win.cc',
       'browser/external_protocol/external_protocol_handler_unittest.cc',
+      'browser/favicon/chrome_fallback_icon_client_unittest.cc',
       'browser/file_select_helper_unittest.cc',
       'browser/geolocation/geolocation_permission_context_unittest.cc',
       'browser/global_keyboard_shortcuts_mac_unittest.mm',
@@ -1300,6 +1301,8 @@
       'browser/chromeos/settings/device_oauth2_token_service_unittest.cc',
       'browser/chromeos/settings/device_settings_provider_unittest.cc',
       'browser/chromeos/settings/device_settings_service_unittest.cc',
+      'browser/chromeos/settings/scoped_cros_settings_test_helper.cc',
+      'browser/chromeos/settings/scoped_cros_settings_test_helper.h',
       'browser/chromeos/settings/session_manager_operation_unittest.cc',
       'browser/chromeos/settings/shutdown_policy_handler_unittest.cc',
       'browser/chromeos/settings/stub_cros_settings_provider_unittest.cc',
@@ -1426,6 +1429,7 @@
       'browser/diagnostics/diagnostics_model_unittest.cc',
       'browser/download/download_commands_unittest.cc',
       'browser/download/download_shelf_unittest.cc',
+      'browser/engagement/site_engagement_service_unittest.cc',
       'browser/first_run/first_run_unittest.cc',
       'browser/font_family_cache_unittest.cc',
       'browser/importer/firefox_profile_lock_unittest.cc',
diff --git a/chrome/chrome_utility.gypi b/chrome/chrome_utility.gypi
index d076a1b..08d58b24 100644
--- a/chrome/chrome_utility.gypi
+++ b/chrome/chrome_utility.gypi
@@ -133,20 +133,6 @@
             },
           },
         }],
-        ['OS!="win" and OS!="mac" and use_openssl==1', {
-          'sources!': [
-            'utility/importer/nss_decryptor.cc',
-          ]
-        }],
-        ['OS!="win" and OS!="mac" and use_openssl==0', {
-          'dependencies': [
-            '../crypto/crypto.gyp:crypto',
-          ],
-          'sources': [
-            'utility/importer/nss_decryptor_system_nss.cc',
-            'utility/importer/nss_decryptor_system_nss.h',
-          ],
-        }],
         ['OS!="android"', {
           'dependencies': [
             '../net/net.gyp:net_utility_services',
@@ -155,6 +141,15 @@
             '<@(chrome_utility_importer_sources)',
           ],
         }],
+        ['use_nss_certs==1', {
+          'dependencies': [
+            '../crypto/crypto.gyp:crypto',
+          ],
+          'sources': [
+            'utility/importer/nss_decryptor_system_nss.cc',
+            'utility/importer/nss_decryptor_system_nss.h',
+          ],
+        }],
         ['OS=="android" and use_seccomp_bpf==1', {
           'dependencies': [
             '../sandbox/sandbox.gyp:seccomp_bpf',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 0ddcae1..fe6b9416 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -342,6 +342,10 @@
 // Disables using bubbles for session restore request.
 const char kDisableSessionCrashedBubble[] = "disable-session-crashed-bubble";
 
+// Disables the Site Engagement service, which records interaction with sites
+// and allocates certain resources accordingly.
+const char kDisableSiteEngagementService[] = "disable-site-engagement-service";
+
 // Disables the suggestions service.
 const char kDisableSuggestionsService[]     = "disable-suggestions-service";
 
@@ -552,6 +556,10 @@
 const char kEnableSettingsWindow[]           = "enable-settings-window";
 const char kDisableSettingsWindow[]          = "disable-settings-window";
 
+// Enable the Site Engagement service, which records interaction with sites and
+// allocates certain resources accordingly.
+const char kEnableSiteEngagementService[]   = "enable-site-engagement-service";
+
 // Enable SPDY/4, aka HTTP/2. This is a temporary testing flag.
 const char kEnableSpdy4[]                   = "enable-spdy4";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index c70f7f1..e12d932 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -101,6 +101,7 @@
 extern const char kDisableSavePasswordBubble[];
 extern const char kDisableSdchPersistence[];
 extern const char kDisableSessionCrashedBubble[];
+extern const char kDisableSiteEngagementService[];
 extern const char kDisableSuggestionsService[];
 extern const char kDisableSync[];
 extern const char kDisableSyncTypes[];
@@ -161,6 +162,7 @@
 extern const char kEnableSessionCrashedBubble[];
 extern const char kEnableSettingsWindow[];
 extern const char kDisableSettingsWindow[];
+extern const char kEnableSiteEngagementService[];
 extern const char kEnableSpdy4[];
 extern const char kEnableSuggestionsService[];
 extern const char kEnableSupervisedUserManagedBookmarksFolder[];
diff --git a/chrome/common/chrome_utility_messages.h b/chrome/common/chrome_utility_messages.h
index 70c5aa60..cd828af 100644
--- a/chrome/common/chrome_utility_messages.h
+++ b/chrome/common/chrome_utility_messages.h
@@ -284,6 +284,4 @@
 // of kernel support for seccomp-bpf.
 IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl,
                      bool /* seccomp prctl supported */)
-IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall,
-                     bool /* seccomp syscall supported */)
 #endif
diff --git a/chrome/common/extensions/api/developer_private.idl b/chrome/common/extensions/api/developer_private.idl
index a1d817b..276cf64 100644
--- a/chrome/common/extensions/api/developer_private.idl
+++ b/chrome/common/extensions/api/developer_private.idl
@@ -284,7 +284,8 @@
     VIEW_REGISTERED,
     // window / view closed.
     VIEW_UNREGISTERED,
-    ERROR_ADDED
+    ERROR_ADDED,
+    PREFS_CHANGED
   };
 
   dictionary PackDirectoryResponse {
diff --git a/chrome/common/extensions/api/webview_tag.json b/chrome/common/extensions/api/webview_tag.json
index 5485f6d..30603b0 100644
--- a/chrome/common/extensions/api/webview_tag.json
+++ b/chrome/common/extensions/api/webview_tag.json
@@ -30,7 +30,7 @@
         "description": "A set of data types. Missing properties are interpreted as <code>false</code>.",
         "properties": {
           "appcache": { "type": "boolean", "optional": true, "description": "Websites' appcaches." },
-          "cache": { "type": "boolean", "optional": true, "description": "The browser's cache. Note: when removing data, this clears the entire cache; it is not limited to the range you specify." },
+          "cache": { "type": "boolean", "optional": true, "description": "Since Chrome 43.<br>The browser's cache. Note: when removing data, this clears the entire cache; it is not limited to the range you specify." },
           "cookies": { "type": "boolean", "optional": true, "description": "The partition's cookies." },
           "fileSystems": { "type": "boolean", "optional": true, "description": "Websites' filesystems." },
           "indexedDB": { "type": "boolean", "optional": true, "description": "Websites' IndexedDB data." },
diff --git a/chrome/common/favicon/fallback_icon_url_parser_unittest.cc b/chrome/common/favicon/fallback_icon_url_parser_unittest.cc
index f22bb95..2d88f3e 100644
--- a/chrome/common/favicon/fallback_icon_url_parser_unittest.cc
+++ b/chrome/common/favicon/fallback_icon_url_parser_unittest.cc
@@ -20,11 +20,11 @@
 
 // Default values for FallbackIconStyle, from
 // /components/favicon_base/fallback_icon_style.h
-SkColor kDefaultBackgroundColor = SkColorSetRGB(0x80, 0x80, 0x80);
-SkColor kDefaultTextColorDark = SK_ColorBLACK;
-SkColor kDefaultTextColorLight = SK_ColorWHITE;
-double kDefaultFontSizeRatio = 0.8;
-double kDefaultRoundness = 0.125;  // 1 / 8.
+const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78);
+const SkColor kDefaultTextColorDark = SK_ColorBLACK;
+const SkColor kDefaultTextColorLight = SK_ColorWHITE;
+const double kDefaultFontSizeRatio = 0.44;
+const double kDefaultRoundness = 0;
 
 const char kTestUrlStr[] = "https://www.google.ca/imghp?hl=en&tab=wi";
 
diff --git a/chrome/common/net/BUILD.gn b/chrome/common/net/BUILD.gn
index b69512ca..b73de58 100644
--- a/chrome/common/net/BUILD.gn
+++ b/chrome/common/net/BUILD.gn
@@ -30,31 +30,25 @@
   ]
 
   if (is_ios) {
-    sources -= [
-      "net_resource_provider.cc",
-      "x509_certificate_model.cc",
-    ]
+    sources -= [ "net_resource_provider.cc" ]
   } else {
     deps += [ "//gpu/ipc" ]
   }
 
-  if (is_win || is_mac || is_ios) {
-    sources -= [
-      "x509_certificate_model_nss.cc",
-      "x509_certificate_model_openssl.cc",
-    ]
-  } else if (use_openssl) {
-    sources -= [ "x509_certificate_model_nss.cc" ]
+  if (is_android || is_ios) {
+    sources -= [ "x509_certificate_model.cc" ]
+  }
+
+  if (use_openssl_certs && !is_android) {
+    deps += [ "//third_party/boringssl" ]
   } else {
     sources -= [ "x509_certificate_model_openssl.cc" ]
   }
 
-  if (is_android) {
-    sources -= [
-      "x509_certificate_model.cc",
-      "x509_certificate_model_openssl.cc",
-    ]
-    deps += [ "//third_party/boringssl" ]
+  if (use_nss_certs) {
+    deps += [ "//crypto:platform" ]
+  } else {
+    sources -= [ "x509_certificate_model_nss.cc" ]
   }
 
   configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
diff --git a/chrome/common/origin_util.cc b/chrome/common/origin_util.cc
index 2884d74e..b2f7d63 100644
--- a/chrome/common/origin_util.cc
+++ b/chrome/common/origin_util.cc
@@ -10,7 +10,7 @@
 #include "url/gurl.h"
 
 bool IsOriginSecure(const GURL& url) {
-  if (url.SchemeUsesTLS() || url.SchemeIsFile())
+  if (url.SchemeIsCryptographic() || url.SchemeIsFile())
     return true;
 
   if (url.SchemeIsFileSystem() && url.inner_url() &&
diff --git a/chrome/common/partial_circular_buffer.cc b/chrome/common/partial_circular_buffer.cc
index 4161cc1..6e3e017e 100644
--- a/chrome/common/partial_circular_buffer.cc
+++ b/chrome/common/partial_circular_buffer.cc
@@ -139,30 +139,49 @@
 
 void PartialCircularBuffer::Write(const void* buffer, uint32 buffer_size) {
   DCHECK(buffer_data_);
-  uint32 position_before_write = position_;
+  const uint8* input = static_cast<const uint8*>(buffer);
+  uint32 wrap_position = buffer_data_->wrap_position;
+  uint32 cycle_size = data_size_ - wrap_position;
 
-  uint32 to_eof = data_size_ - position_;
-  uint32 to_write = std::min(buffer_size, to_eof);
-  DoWrite(buffer_data_->data + position_, buffer, to_write);
-  if (position_ >= data_size_) {
-    DCHECK_EQ(position_, data_size_);
-    position_ = buffer_data_->wrap_position;
+  // First write the non-wrapping part.
+  if (position_ < wrap_position) {
+    uint32 space_left = wrap_position - position_;
+    uint32 write_size = std::min(buffer_size, space_left);
+    DoWrite(input, write_size);
+    input += write_size;
+    buffer_size -= write_size;
   }
 
-  if (to_write < buffer_size) {
-    uint32 remainder_to_write = buffer_size - to_write;
-    DCHECK_LT(position_, position_before_write);
-    DCHECK_LE(position_ + remainder_to_write, position_before_write);
-    DoWrite(buffer_data_->data + position_,
-            reinterpret_cast<const uint8*>(buffer) + to_write,
-            remainder_to_write);
+  // Skip the part that would overlap.
+  if (buffer_size > cycle_size) {
+    uint32 skip = buffer_size - cycle_size;
+    input += skip;
+    buffer_size -= skip;
+    position_ = wrap_position + (position_ - wrap_position + skip) % cycle_size;
   }
+
+  // Finally write the wrapping part.
+  DoWrite(input, buffer_size);
 }
 
-void PartialCircularBuffer::DoWrite(void* dest, const void* src, uint32 num) {
-  memcpy(dest, src, num);
-  position_ += num;
+void PartialCircularBuffer::DoWrite(const uint8* input, uint32 input_size) {
+  DCHECK_LT(position_, data_size_);
   buffer_data_->total_written =
-      std::min(buffer_data_->total_written + num, data_size_);
+      std::min(buffer_data_->total_written + input_size, data_size_);
+
+  // Write() skips any overlapping part, so this loop will run at most twice.
+  while (input_size > 0) {
+    uint32 space_left = data_size_ - position_;
+    uint32 write_size = std::min(input_size, space_left);
+    memcpy(buffer_data_->data + position_, input, write_size);
+    input += write_size;
+    input_size -= write_size;
+    position_ += write_size;
+    if (position_ >= data_size_) {
+      DCHECK_EQ(position_, data_size_);
+      position_ = buffer_data_->wrap_position;
+    }
+  }
+
   buffer_data_->end_position = position_;
 }
diff --git a/chrome/common/partial_circular_buffer.h b/chrome/common/partial_circular_buffer.h
index 1f986cc..e1fb118 100644
--- a/chrome/common/partial_circular_buffer.h
+++ b/chrome/common/partial_circular_buffer.h
@@ -52,7 +52,7 @@
   };
 #pragma pack(pop)
 
-  void DoWrite(void* dest, const void* src, uint32 num);
+  void DoWrite(const uint8* input, uint32 input_size);
 
   // Used for reading and writing.
   BufferData* buffer_data_;
diff --git a/chrome/common/partial_circular_buffer_unittest.cc b/chrome/common/partial_circular_buffer_unittest.cc
index 85153fa..701aefa 100644
--- a/chrome/common/partial_circular_buffer_unittest.cc
+++ b/chrome/common/partial_circular_buffer_unittest.cc
@@ -189,3 +189,24 @@
 
   EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
 }
+
+TEST_F(PartialCircularBufferTest, WrapTwiceWithSingleWrite) {
+  const size_t kInputSize = sizeof(kInputData);
+  const size_t kLargeSize = kInputSize * 7;
+  uint8 large_input[kLargeSize] = {0};
+  for (size_t offset = 0; offset < kLargeSize; offset += kInputSize)
+    memcpy(large_input + offset, kInputData, kInputSize);
+
+  InitWriteBuffer(false);
+  pcb_write_->Write(large_input, kLargeSize);
+  InitReadBuffer();
+
+  uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+  EXPECT_EQ(sizeof(output_data),
+            pcb_read_->Read(output_data, sizeof(output_data)));
+
+  EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+  EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 8f874ca..eca2d70 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1915,6 +1915,10 @@
 // A boolean pref. If set to true, experimental webview based signin flow
 // is deactivated.
 const char kWebviewSigninDisabled[] = "webview_signin_disabled";
+
+// A boolean pref. If set to true, then on the network screen we should display
+// whether the WebView-based sign-in flow is active.
+const char kNewLoginUIPopup[] = "new_login_ui_popup";
 #endif  // defined(OS_CHROMEOS)
 
 // Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 2d5e3098..6344211 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -677,6 +677,7 @@
 extern const char kNewOobe[];
 extern const char kConsumerManagementEnrollmentStage[];
 extern const char kWebviewSigninDisabled[];
+extern const char kNewLoginUIPopup[];
 #endif  // defined(OS_CHROMEOS)
 
 extern const char kClearPluginLSODataEnabled[];
diff --git a/chrome/installer/linux/rpm/expected_deps_i386 b/chrome/installer/linux/rpm/expected_deps_i386
index 698b085..00900a9 100644
--- a/chrome/installer/linux/rpm/expected_deps_i386
+++ b/chrome/installer/linux/rpm/expected_deps_i386
@@ -60,6 +60,7 @@
 libstdc++.so.6(GLIBCXX_3.4.10)
 libstdc++.so.6(GLIBCXX_3.4.11)
 libstdc++.so.6(GLIBCXX_3.4.15)
+libstdc++.so.6(GLIBCXX_3.4.5)
 libstdc++.so.6(GLIBCXX_3.4.9)
 libX11.so.6
 libXcomposite.so.1
diff --git a/chrome/installer/linux/rpm/expected_deps_x86_64 b/chrome/installer/linux/rpm/expected_deps_x86_64
index 7e9538d..1b5cd370 100644
--- a/chrome/installer/linux/rpm/expected_deps_x86_64
+++ b/chrome/installer/linux/rpm/expected_deps_x86_64
@@ -48,6 +48,7 @@
 libstdc++.so.6(GLIBCXX_3.4.10)(64bit)
 libstdc++.so.6(GLIBCXX_3.4.11)(64bit)
 libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
+libstdc++.so.6(GLIBCXX_3.4.5)(64bit)
 libstdc++.so.6(GLIBCXX_3.4)(64bit)
 libstdc++.so.6(GLIBCXX_3.4.9)(64bit)
 libX11.so.6()(64bit)
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index a67f8fcc..c65fc50 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -197,8 +197,10 @@
 void ChromeRenderFrameObserver::OnAppBannerPromptRequest(
     int request_id, const std::string& platform) {
   blink::WebAppBannerPromptReply reply = blink::WebAppBannerPromptReply::None;
+  blink::WebString web_platform(base::UTF8ToUTF16(platform));
+  blink::WebVector<blink::WebString> web_platforms(&web_platform, 1);
   render_frame()->GetWebFrame()->willShowInstallBannerPrompt(
-      blink::WebString(base::UTF8ToUTF16(platform)), &reply);
+      web_platforms, &reply);
 
   Send(new ChromeViewHostMsg_AppBannerPromptReply(
       routing_id(), request_id, reply));
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index 5e7c96a..3769a85cc 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -11,7 +11,7 @@
 #include "content/public/renderer/document_state.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_view.h"
-#include "third_party/WebKit/public/platform/WebPermissionCallbacks.h"
+#include "third_party/WebKit/public/platform/WebContentSettingCallbacks.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebDataSource.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
@@ -30,10 +30,10 @@
 #include "extensions/renderer/dispatcher.h"
 #endif
 
+using blink::WebContentSettingCallbacks;
 using blink::WebDataSource;
 using blink::WebDocument;
 using blink::WebFrame;
-using blink::WebPermissionCallbacks;
 using blink::WebSecurityOrigin;
 using blink::WebString;
 using blink::WebURL;
@@ -285,11 +285,11 @@
 }
 
 void ContentSettingsObserver::requestFileSystemAccessAsync(
-    const WebPermissionCallbacks& callbacks) {
+    const WebContentSettingCallbacks& callbacks) {
   WebFrame* frame = render_frame()->GetWebFrame();
   if (frame->securityOrigin().isUnique() ||
       frame->top()->securityOrigin().isUnique()) {
-    WebPermissionCallbacks permissionCallbacks(callbacks);
+    WebContentSettingCallbacks permissionCallbacks(callbacks);
     permissionCallbacks.doDeny();
     return;
   }
@@ -628,7 +628,7 @@
   if (it == permission_requests_.end())
     return;
 
-  WebPermissionCallbacks callbacks = it->second;
+  WebContentSettingCallbacks callbacks = it->second;
   permission_requests_.erase(it);
 
   if (allowed) {
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h
index 736fd0da..6e21be7 100644
--- a/chrome/renderer/content_settings_observer.h
+++ b/chrome/renderer/content_settings_observer.h
@@ -59,31 +59,31 @@
   // blink::WebContentSettingsClient implementation.
   virtual bool allowDatabase(const blink::WebString& name,
                              const blink::WebString& display_name,
-                             unsigned long estimated_size) override;
+                             unsigned long estimated_size);
   virtual void requestFileSystemAccessAsync(
-      const blink::WebPermissionCallbacks& callbacks) override;
+      const blink::WebContentSettingCallbacks& callbacks);
   virtual bool allowImage(bool enabled_per_settings,
-                          const blink::WebURL& image_url) override;
+                          const blink::WebURL& image_url);
   virtual bool allowIndexedDB(const blink::WebString& name,
-                              const blink::WebSecurityOrigin& origin) override;
-  virtual bool allowPlugins(bool enabled_per_settings) override;
-  virtual bool allowScript(bool enabled_per_settings) override;
+                              const blink::WebSecurityOrigin& origin);
+  virtual bool allowPlugins(bool enabled_per_settings);
+  virtual bool allowScript(bool enabled_per_settings);
   virtual bool allowScriptFromSource(bool enabled_per_settings,
-                                     const blink::WebURL& script_url) override;
-  virtual bool allowStorage(bool local) override;
-  virtual bool allowReadFromClipboard(bool default_value) override;
-  virtual bool allowWriteToClipboard(bool default_value) override;
-  virtual bool allowMutationEvents(bool default_value) override;
-  virtual void didNotAllowPlugins() override;
-  virtual void didNotAllowScript() override;
+                                     const blink::WebURL& script_url);
+  virtual bool allowStorage(bool local);
+  virtual bool allowReadFromClipboard(bool default_value);
+  virtual bool allowWriteToClipboard(bool default_value);
+  virtual bool allowMutationEvents(bool default_value);
+  virtual void didNotAllowPlugins();
+  virtual void didNotAllowScript();
   virtual bool allowDisplayingInsecureContent(
       bool allowed_per_settings,
       const blink::WebSecurityOrigin& context,
-      const blink::WebURL& url) override;
+      const blink::WebURL& url);
   virtual bool allowRunningInsecureContent(
       bool allowed_per_settings,
       const blink::WebSecurityOrigin& context,
-      const blink::WebURL& url) override;
+      const blink::WebURL& url);
 
   // This is used for cases when the NPAPI plugins malfunction if used.
   bool AreNPAPIPluginsBlocked() const;
@@ -159,7 +159,7 @@
   bool npapi_plugins_blocked_;
 
   int current_request_id_;
-  typedef std::map<int, blink::WebPermissionCallbacks> PermissionRequestMap;
+  typedef std::map<int, blink::WebContentSettingCallbacks> PermissionRequestMap;
   PermissionRequestMap permission_requests_;
 
   // If true, IsWhitelistedForContentSettings will always return true.
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
index 63d4734..7f4c8362 100644
--- a/chrome/renderer/media/chrome_key_systems.cc
+++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -87,11 +87,11 @@
   info.max_video_robustness = media::EmeRobustness::EMPTY;
 
   // Persistent sessions are faked.
-  info.persistent_license_support = media::EME_SESSION_TYPE_SUPPORTED;
+  info.persistent_license_support = media::EmeSessionTypeSupport::SUPPORTED;
   info.persistent_release_message_support =
-      media::EME_SESSION_TYPE_NOT_SUPPORTED;
-  info.persistent_state_support = media::EME_FEATURE_REQUESTABLE;
-  info.distinctive_identifier_support = media::EME_FEATURE_NOT_SUPPORTED;
+      media::EmeSessionTypeSupport::NOT_SUPPORTED;
+  info.persistent_state_support = media::EmeFeatureSupport::REQUESTABLE;
+  info.distinctive_identifier_support = media::EmeFeatureSupport::NOT_SUPPORTED;
 
   info.pepper_type = kExternalClearKeyPepperType;
 
@@ -193,20 +193,22 @@
   cdm::AddWidevineWithCodecs(
       cdm::WIDEVINE, supported_codecs,
 #if defined(OS_CHROMEOS)
-      media::EmeRobustness::HW_SECURE_ALL,     // Maximum audio robustness.
-      media::EmeRobustness::HW_SECURE_ALL,     // Maximim video robustness.
-      // persistent-license.
-      media::EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER,
-      media::EME_SESSION_TYPE_NOT_SUPPORTED,   // persistent-release-message.
-      media::EME_FEATURE_REQUESTABLE,          // Persistent state.
-      media::EME_FEATURE_REQUESTABLE,          // Distinctive identifier.
+      media::EmeRobustness::HW_SECURE_ALL,  // Maximum audio robustness.
+      media::EmeRobustness::HW_SECURE_ALL,  // Maximim video robustness.
+      media::EmeSessionTypeSupport::
+          SUPPORTED_WITH_IDENTIFIER,  // Persistent-license.
+      media::EmeSessionTypeSupport::
+          NOT_SUPPORTED,                      // Persistent-release-message.
+      media::EmeFeatureSupport::REQUESTABLE,  // Persistent state.
+      media::EmeFeatureSupport::REQUESTABLE,  // Distinctive identifier.
 #else   // (Desktop)
-      media::EmeRobustness::SW_SECURE_CRYPTO,  // Maximum audio robustness.
-      media::EmeRobustness::SW_SECURE_DECODE,  // Maximum video robustness.
-      media::EME_SESSION_TYPE_NOT_SUPPORTED,   // persistent-license.
-      media::EME_SESSION_TYPE_NOT_SUPPORTED,   // persistent-release-message.
-      media::EME_FEATURE_REQUESTABLE,          // Persistent state.
-      media::EME_FEATURE_NOT_SUPPORTED,        // Distinctive identifier.
+      media::EmeRobustness::SW_SECURE_CRYPTO,       // Maximum audio robustness.
+      media::EmeRobustness::SW_SECURE_DECODE,       // Maximum video robustness.
+      media::EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
+      media::EmeSessionTypeSupport::
+          NOT_SUPPORTED,                        // persistent-release-message.
+      media::EmeFeatureSupport::REQUESTABLE,    // Persistent state.
+      media::EmeFeatureSupport::NOT_SUPPORTED,  // Distinctive identifier.
 #endif  // defined(OS_CHROMEOS)
       concrete_key_systems);
 }
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
index 8f7f29884..50141be 100644
--- a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
@@ -407,7 +407,14 @@
   EXPECT_CALL(*classifier_, CancelPendingClassification());
 }
 
-IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer) {
+// Flaky: crbug.com/479757
+#if defined(LEAK_SANITIZER)
+#define MAYBE_NoScorer DISABLED_NoScorer
+#else
+#define MAYBE_NoScorer NoScorer
+#endif
+
+IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, MAYBE_NoScorer) {
   // For this test, we'll create the delegate with no scorer available yet.
   ASSERT_FALSE(classifier_->is_ready());
 
diff --git a/chrome/renderer/worker_content_settings_client_proxy.cc b/chrome/renderer/worker_content_settings_client_proxy.cc
index 31d83d2..05c6b945 100644
--- a/chrome/renderer/worker_content_settings_client_proxy.cc
+++ b/chrome/renderer/worker_content_settings_client_proxy.cc
@@ -9,7 +9,6 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "ipc/ipc_sync_message_filter.h"
-#include "third_party/WebKit/public/platform/WebPermissionCallbacks.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index cf446018..6a9af83 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -380,6 +380,10 @@
         "//third_party/wtl",
         "//ui/resources",
       ]
+
+      configs -= [ "//build/config/win:default_incremental_linking" ]
+      configs +=
+          [ "//build/config/win:default_large_module_incremental_linking" ]
     }
 
     if (is_mac) {
@@ -737,6 +741,9 @@
         deps += [
           #'chrome.gyp:chrome_nacl_win64',  TODO(GYP)
         ]
+        configs -= [ "//build/config/win:default_incremental_linking" ]
+        configs +=
+            [ "//build/config/win:default_large_module_incremental_linking" ]
       }
       if (is_linux) {
         deps += [
@@ -1070,6 +1077,10 @@
         "//third_party/wtl",
         "//ui/resources",
       ]
+
+      configs -= [ "//build/config/win:default_incremental_linking" ]
+      configs +=
+          [ "//build/config/win:default_large_module_incremental_linking" ]
     } else {
       sources -= [ "../app/chrome_version.rc.version" ]
     }
@@ -1135,6 +1146,9 @@
         "//third_party/wtl",
         "//ui/resources",
       ]
+      configs -= [ "//build/config/win:default_incremental_linking" ]
+      configs +=
+          [ "//build/config/win:default_large_module_incremental_linking" ]
     } else {
       sources -= [ "../app/chrome_version.rc.version" ]
     }
@@ -1604,6 +1618,10 @@
         "//third_party/wtl",
       ]
 
+      configs -= [ "//build/config/win:default_incremental_linking" ]
+      configs +=
+          [ "//build/config/win:default_large_module_incremental_linking" ]
+
       libs = [
         "comsupp.lib",
         "oleacc.lib",
@@ -1718,7 +1736,11 @@
         "//testing/perf",
       ]
 
-      if (!is_win) {
+      if (is_win) {
+        configs -= [ "//build/config/win:default_incremental_linking" ]
+        configs +=
+            [ "//build/config/win:default_large_module_incremental_linking" ]
+      } else {
         sources -= [
           "../app/chrome_command_ids.h",
 
diff --git a/chrome/test/base/testing_io_thread_state.cc b/chrome/test/base/testing_io_thread_state.cc
index e79423f..30b90698 100644
--- a/chrome/test/base/testing_io_thread_state.cc
+++ b/chrome/test/base/testing_io_thread_state.cc
@@ -79,7 +79,7 @@
 }
 
 void TestingIOThreadState::Initialize(const base::Closure& done) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   io_thread_state_->SetGlobalsForTesting(new IOThread::Globals());
 
@@ -87,7 +87,7 @@
 }
 
 void TestingIOThreadState::Shutdown(const base::Closure& done) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   delete io_thread_state_->globals();
   io_thread_state_->SetGlobalsForTesting(NULL);
diff --git a/chrome/test/base/tracing.cc b/chrome/test/base/tracing.cc
index f9d9f57a..2120b9f7 100644
--- a/chrome/test/base/tracing.cc
+++ b/chrome/test/base/tracing.cc
@@ -55,7 +55,7 @@
   virtual ~InProcessTraceController() {}
 
   bool BeginTracing(const std::string& category_patterns) {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
     return content::TracingController::GetInstance()->EnableRecording(
         base::trace_event::CategoryFilter(category_patterns),
         base::trace_event::TraceOptions(),
@@ -66,7 +66,7 @@
                              const std::string& category_name,
                              const std::string& event_name,
                              int num_occurrences) {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
     DCHECK(num_occurrences > 0);
     watch_notification_count_ = num_occurrences;
     if (!content::TracingController::GetInstance()->SetWatchEvent(
@@ -89,7 +89,7 @@
   }
 
   bool WaitForWatchEvent(base::TimeDelta timeout) {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
     if (watch_notification_count_ == 0)
       return true;
 
@@ -107,7 +107,7 @@
   }
 
   bool EndTracing(std::string* json_trace_output) {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
     using namespace base::debug;
 
     if (!content::TracingController::GetInstance()->DisableRecording(
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc
index 90e73ff9..33b34d2 100644
--- a/chrome/test/chromedriver/capabilities.cc
+++ b/chrome/test/chromedriver/capabilities.cc
@@ -108,7 +108,9 @@
   }
 
   capabilities->device_metrics.reset(device->device_metrics.release());
-  capabilities->switches.SetSwitch("user-agent", device->user_agent);
+  // Don't override the user agent if blank (like for notebooks).
+  if (!device->user_agent.empty())
+    capabilities->switches.SetSwitch("user-agent", device->user_agent);
 
   return Status(kOk);
 }
@@ -139,13 +141,25 @@
     int width = 0;
     int height = 0;
     double device_scale_factor = 0;
+    bool touch = true;
+    bool mobile = true;
     if (!metrics->GetInteger("width", &width) ||
         !metrics->GetInteger("height", &height) ||
         !metrics->GetDouble("pixelRatio", &device_scale_factor))
       return Status(kUnknownError, "invalid 'deviceMetrics'");
 
+    if (metrics->HasKey("touch")) {
+      if (!metrics->GetBoolean("touch", &touch))
+        return Status(kUnknownError, "'touch' must be a boolean");
+    }
+
+    if (metrics->HasKey("mobile")) {
+      if (!metrics->GetBoolean("mobile", &mobile))
+        return Status(kUnknownError, "'mobile' must be a boolean");
+    }
+
     DeviceMetrics* device_metrics =
-        new DeviceMetrics(width, height, device_scale_factor);
+        new DeviceMetrics(width, height, device_scale_factor, touch, mobile);
     capabilities->device_metrics =
         scoped_ptr<DeviceMetrics>(device_metrics);
   }
diff --git a/chrome/test/chromedriver/capabilities_unittest.cc b/chrome/test/chromedriver/capabilities_unittest.cc
index b05aced..9b8a4e0ef8 100644
--- a/chrome/test/chromedriver/capabilities_unittest.cc
+++ b/chrome/test/chromedriver/capabilities_unittest.cc
@@ -510,9 +510,9 @@
   ASSERT_EQ(1u, capabilities.switches.GetSize());
   ASSERT_TRUE(capabilities.switches.HasSwitch("user-agent"));
   ASSERT_EQ(
-      "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) "
-      "AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 "
-      "Mobile Safari/535.19",
+      "Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 5 Build/JOP40D) "
+      "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 "
+      "Mobile Safari/537.36",
       capabilities.switches.GetSwitchValue("user-agent"));
 
   ASSERT_EQ(360, capabilities.device_metrics->width);
diff --git a/chrome/test/chromedriver/chrome/device_metrics.cc b/chrome/test/chromedriver/chrome/device_metrics.cc
index df43587..76d45eee 100644
--- a/chrome/test/chromedriver/chrome/device_metrics.cc
+++ b/chrome/test/chromedriver/chrome/device_metrics.cc
@@ -4,11 +4,13 @@
 
 #include "chrome/test/chromedriver/chrome/device_metrics.h"
 
-DeviceMetrics::DeviceMetrics(int width, int height, double device_scale_factor)
+DeviceMetrics::DeviceMetrics(int width, int height, double device_scale_factor,
+                             bool touch, bool mobile)
   : width(width),
     height(height),
     device_scale_factor(device_scale_factor),
-    mobile(true),
+    touch(touch),
+    mobile(mobile),
     fit_window(false),
     text_autosizing(true),
     font_scale_factor(1) {}
diff --git a/chrome/test/chromedriver/chrome/device_metrics.h b/chrome/test/chromedriver/chrome/device_metrics.h
index 1e238ef6..9af274c 100644
--- a/chrome/test/chromedriver/chrome/device_metrics.h
+++ b/chrome/test/chromedriver/chrome/device_metrics.h
@@ -6,12 +6,14 @@
 #define CHROME_TEST_CHROMEDRIVER_CHROME_DEVICE_METRICS_H_
 
 struct DeviceMetrics {
-  DeviceMetrics(int width, int height, double device_scale_factor);
+  DeviceMetrics(int width, int height, double device_scale_factor, bool touch,
+                bool mobile);
   ~DeviceMetrics();
 
   int width;
   int height;
   double device_scale_factor;
+  bool touch;
   bool mobile;
   bool fit_window;
   bool text_autosizing;
diff --git a/chrome/test/chromedriver/chrome/mobile_device.cc b/chrome/test/chromedriver/chrome/mobile_device.cc
index 10b6dbb..683dd6c 100644
--- a/chrome/test/chromedriver/chrome/mobile_device.cc
+++ b/chrome/test/chromedriver/chrome/mobile_device.cc
@@ -54,6 +54,8 @@
       int width = 0;
       int height = 0;
       double device_scale_factor = 0.0;
+      bool touch = true;
+      bool mobile = true;
       if (!device->GetInteger("width",  &width)) {
         return Status(kUnknownError,
                       "malformed device width: should be an integer");
@@ -66,8 +68,16 @@
         return Status(kUnknownError,
                       "malformed device scale factor: should be a double");
       }
+      if (!device->GetBoolean("touch", &touch)) {
+        return Status(kUnknownError,
+                      "malformed touch: should be a bool");
+      }
+      if (!device->GetBoolean("mobile", &mobile)) {
+        return Status(kUnknownError,
+                      "malformed mobile: should be a bool");
+      }
       tmp_mobile_device->device_metrics.reset(
-          new DeviceMetrics(width, height, device_scale_factor));
+          new DeviceMetrics(width, height, device_scale_factor, touch, mobile));
 
       *mobile_device = tmp_mobile_device.Pass();
       return Status(kOk);
diff --git a/chrome/test/chromedriver/chrome/mobile_device_list.cc b/chrome/test/chromedriver/chrome/mobile_device_list.cc
index 3c31b0f..aa4704b 100644
--- a/chrome/test/chromedriver/chrome/mobile_device_list.cc
+++ b/chrome/test/chromedriver/chrome/mobile_device_list.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.
 
-// This file was generated at (2015-01-22 12:13:16.600114) by running:
+// This file was generated at (2015-03-30 16:08:35.102812) by running:
 //     chrome/test/chromedriver/embed_mobile_devices_in_cpp.py --directory
 //     chrome/test/chromedriver/chrome/
 //     third_party/WebKit/Source/devtools/front_end/toolbox/OverridesUI.js
@@ -10,158 +10,65 @@
 #include "chrome/test/chromedriver/chrome/mobile_device_list.h"
 
 const char kMobileDevices[] =
-    "[{\"title\": \"Apple iPhone 3GS\", \"width\": 320, \"height\": 480, "
-    "\"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (iPhone; U; CPU "
+    "[{\"title\": \"Apple iPhone 4\", \"width\": 320, \"height\": 480, "
+    "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (iPhone; U; CPU "
     "iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like "
     "Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Apple iPhone 4\", \"width\": 320, "
-    "\"height\": 480, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
-    "(iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) "
-    "AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 "
-    "Safari/6533.18.5\", \"touch\": true, \"mobile\": true},{\"title\": "
-    "\"Apple iPhone 5\", \"width\": 320, \"height\": 568, "
-    "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (iPhone; CPU "
-    "iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like "
-    "Gecko) Version/7.0 Mobile/11A465 Safari/9537.53\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Apple iPhone 6\", \"width\": 375, "
-    "\"height\": 667, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
-    "(iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, "
-    "like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4\", \"touch\": "
-    "true, \"mobile\": true},{\"title\": \"Apple iPhone 6 Plus\", \"width\": "
-    "414, \"height\": 736, \"deviceScaleFactor\": 3, \"userAgent\": "
+    "\"mobile\": true},{\"title\": \"Apple iPhone 5\", \"width\": 320, "
+    "\"height\": 568, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
+    "(iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 "
+    "(KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53\", "
+    "\"touch\": true, \"mobile\": true},{\"title\": \"Apple iPhone 6\", "
+    "\"width\": 375, \"height\": 667, \"deviceScaleFactor\": 2, \"userAgent\": "
     "\"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) "
     "AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d "
+    "Safari/600.1.4\", \"touch\": true, \"mobile\": true},{\"title\": \"Apple "
+    "iPhone 6 Plus\", \"width\": 414, \"height\": 736, \"deviceScaleFactor\": "
+    "3, \"userAgent\": \"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) "
+    "AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d "
     "Safari/600.1.4\", \"touch\": true, \"mobile\": true},{\"title\": "
-    "\"BlackBerry Z10\", \"width\": 384, \"height\": 640, "
-    "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (BB10; Touch) "
-    "AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile "
-    "Safari/537.10+\", \"touch\": true, \"mobile\": true},{\"title\": "
     "\"BlackBerry Z30\", \"width\": 360, \"height\": 640, "
     "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (BB10; Touch) "
     "AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile "
     "Safari/537.10+\", \"touch\": true, \"mobile\": true},{\"title\": \"Google "
     "Nexus 4\", \"width\": 384, \"height\": 640, \"deviceScaleFactor\": 2, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 "
-    "Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 "
-    "Mobile Safari/535.19\", \"touch\": true, \"mobile\": true},{\"title\": "
+    "\"userAgent\": \"Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 4 "
+    "Build/JOP40D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 "
+    "Mobile Safari/537.36\", \"touch\": true, \"mobile\": true},{\"title\": "
     "\"Google Nexus 5\", \"width\": 360, \"height\": 640, "
     "\"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 (Linux; Android "
-    "4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like "
-    "Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Google Nexus S\", \"width\": 320, "
-    "\"height\": 533, \"deviceScaleFactor\": 1.5, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 "
-    "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"HTC Evo, Touch HD, Desire HD, Desire\", "
-    "\"width\": 320, \"height\": 533, \"deviceScaleFactor\": 1.5, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint "
-    "APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 "
-    "Mobile Safari/533.1\", \"touch\": true, \"mobile\": true},{\"title\": "
-    "\"HTC One X, EVO LTE\", \"width\": 360, \"height\": 640, "
-    "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; Android "
-    "4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) "
-    "Chrome/18.0.1025.133 Mobile Safari/535.19\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"HTC Sensation, Evo 3D\", \"width\": 360, \"height\": "
-    "640, \"deviceScaleFactor\": 1.5, \"userAgent\": \"Mozilla/5.0 (Linux; U; "
-    "Android 4.0.3; en-us; HTC Sensation Build/IML74K) AppleWebKit/534.30 "
-    "(KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"LG Optimus 2X, Optimus 3D, Optimus "
-    "Black\", \"width\": 320, \"height\": 533, \"deviceScaleFactor\": 1.5, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.2; en-us; LG-P990/V08c "
-    "Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile "
-    "Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"LG Optimus G\", \"width\": 384, \"height\": 640, "
-    "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; Android "
-    "4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) "
-    "Chrome/18.0.1025.166 Mobile Safari/535.19\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"LG Optimus LTE, Optimus 4X HD\", \"width\": 424, "
-    "\"height\": 753, \"deviceScaleFactor\": 1.7, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 2.3; en-us; LG-P930 Build/GRJ90) AppleWebKit/533.1 "
-    "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"LG Optimus One\", \"width\": 213, "
-    "\"height\": 320, \"deviceScaleFactor\": 1.5, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 "
-    "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Motorola Defy, Droid, Droid X, "
-    "Milestone\", \"width\": 320, \"height\": 569, \"deviceScaleFactor\": 1.5, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.0; en-us; Milestone "
-    "Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like Gecko) "
-    "Version/4.0 Mobile Safari/530.17\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Motorola Droid 3, Droid 4, Droid Razr, Atrix 4G, "
-    "Atrix 2\", \"width\": 540, \"height\": 960, \"deviceScaleFactor\": 1, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid "
-    "Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile "
-    "Safari/533.1\", \"touch\": true, \"mobile\": true},{\"title\": \"Motorola "
-    "Droid Razr HD\", \"width\": 720, \"height\": 1280, \"deviceScaleFactor\": "
-    "1, \"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR "
-    "4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) "
-    "Version/4.0 Mobile Safari/533.1\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Nokia C5, C6, C7, N97, N8, X7\", \"width\": 360, "
-    "\"height\": 640, \"deviceScaleFactor\": 1, \"userAgent\": "
-    "\"NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; "
-    "Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like "
-    "Gecko) BrowserNG/7.1.4\", \"touch\": true, \"mobile\": true},{\"title\": "
-    "\"Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800, N810, N900\", \"width\": "
-    "320, \"height\": 533, \"deviceScaleFactor\": 1.5, \"userAgent\": "
-    "\"Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; "
-    "IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Samsung Galaxy Note 3\", \"width\": 360, "
-    "\"height\": 640, \"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 "
-    "(KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Samsung Galaxy Note II\", \"width\": 360, "
-    "\"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 "
-    "(KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Samsung Galaxy Note\", \"width\": 400, "
-    "\"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 2.3; en-us; SAMSUNG-SGH-I717 Build/GINGERBREAD) "
-    "AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\", "
-    "\"touch\": true, \"mobile\": true},{\"title\": \"Samsung Galaxy S III, "
-    "Galaxy Nexus\", \"width\": 360, \"height\": 640, \"deviceScaleFactor\": "
-    "2, \"userAgent\": \"Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 "
-    "Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile "
-    "Safari/534.30\", \"touch\": true, \"mobile\": true},{\"title\": \"Samsung "
-    "Galaxy S, S II, W\", \"width\": 320, \"height\": 533, "
-    "\"deviceScaleFactor\": 1.5, \"userAgent\": \"Mozilla/5.0 (Linux; U; "
-    "Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, "
-    "like Gecko) Version/3.0.4 Mobile Safari/523.12.2\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Samsung Galaxy S4\", \"width\": 360, "
-    "\"height\": 640, \"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, "
-    "like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Sony Xperia S, Ion\", \"width\": 360, "
-    "\"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) "
+    "4.4.4; en-us; Nexus 5 Build/JOP40D) AppleWebKit/537.36 (KHTML, like "
+    "Gecko) Chrome/42.0.2307.2 Mobile Safari/537.36\", \"touch\": true, "
+    "\"mobile\": true},{\"title\": \"LG Optimus L70\", \"width\": 384, "
+    "\"height\": 640, \"deviceScaleFactor\": 1.25, \"userAgent\": "
+    "\"Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 "
+    "Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 "
+    "Chrome/30.0.1599.103 Mobile Safari/537.36\", \"touch\": true, \"mobile\": "
+    "true},{\"title\": \"Nokia N9\", \"width\": 360, \"height\": 640, "
+    "\"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (MeeGo; NokiaN9) "
+    "AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile "
+    "Safari/534.13\", \"touch\": true, \"mobile\": true},{\"title\": \"Nokia "
+    "Lumia 520\", \"width\": 320, \"height\": 533, \"deviceScaleFactor\": 1.4, "
+    "\"userAgent\": \"Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; "
+    "Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)\", \"touch\": "
+    "true, \"mobile\": true},{\"title\": \"Samsung Galaxy S III\", \"width\": "
+    "360, \"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": "
+    "\"Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) "
     "AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile "
-    "Safari/534.30\", \"touch\": true, \"mobile\": true},{\"title\": \"Sony "
-    "Xperia Sola, U\", \"width\": 480, \"height\": 854, \"deviceScaleFactor\": "
-    "1, \"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.3; en-us; "
-    "SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like "
-    "Gecko) Version/4.0 Mobile Safari/533.1\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Sony Xperia Z, Z1\", \"width\": 360, \"height\": 640, "
-    "\"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 (Linux; U; Android "
-    "4.2; en-us; SonyC6903 Build/14.1.G.1.518) AppleWebKit/534.30 (KHTML, like "
-    "Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Amazon Kindle Fire HDX 7″\", \"width\": 1920, "
-    "\"height\": 1200, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like "
-    "Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true\", \"touch\": true, "
-    "\"mobile\": true},{\"title\": \"Amazon Kindle Fire HDX 8.9″\", \"width\": "
-    "2560, \"height\": 1600, \"deviceScaleFactor\": 2, \"userAgent\": "
-    "\"Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 "
-    "(KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true\", "
-    "\"touch\": true, \"mobile\": true},{\"title\": \"Amazon Kindle Fire "
-    "(First Generation)\", \"width\": 1024, \"height\": 600, "
-    "\"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (Macintosh; U; "
-    "Intel Mac OS X 10_6_3; en-us; Silk/1.0.141.16-Gen4_11004310) "
-    "AppleWebkit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 "
-    "Silk-Accelerated=true\", \"touch\": true, \"mobile\": true},{\"title\": "
-    "\"Apple iPad 1 / 2 / iPad Mini\", \"width\": 1024, \"height\": 768, "
+    "Safari/534.30\", \"touch\": true, \"mobile\": true},{\"title\": \"Samsung "
+    "Galaxy S4\", \"width\": 360, \"height\": 640, \"deviceScaleFactor\": 3, "
+    "\"userAgent\": \"Mozilla/5.0 (Linux; Android 4.4.2; GT-I9505 Build/JDQ39) "
+    "AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 "
+    "Mobile Safari/537.36\", \"touch\": true, \"mobile\": true},{\"title\": "
+    "\"Amazon Kindle Fire HDX\", \"width\": 2560, \"height\": 1600, "
+    "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; U; en-us; "
+    "KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 "
+    "Safari/535.19 Silk-Accelerated=true\", \"touch\": true, \"mobile\": "
+    "true},{\"title\": \"Apple iPad Mini\", \"width\": 1024, \"height\": 768, "
     "\"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (iPad; CPU OS "
     "4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) "
     "Version/5.0.2 Mobile/8L1 Safari/6533.18.5\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Apple iPad 3 / 4\", \"width\": 1024, \"height\": 768, "
+    "true},{\"title\": \"Apple iPad\", \"width\": 1024, \"height\": 768, "
     "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (iPad; CPU OS 7_0 "
     "like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 "
     "Mobile/11A465 Safari/9537.53\", \"touch\": true, \"mobile\": "
@@ -172,25 +79,24 @@
     "true},{\"title\": \"Google Nexus 10\", \"width\": 1280, \"height\": 800, "
     "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; Android "
     "4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) "
-    "Chrome/29.0.1547.72 Safari/537.36\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Google Nexus 7 2\", \"width\": 960, \"height\": 600, "
+    "Chrome/42.0.2307.2 Mobile Safari/537.36\", \"touch\": true, \"mobile\": "
+    "true},{\"title\": \"Google Nexus 7\", \"width\": 960, \"height\": 600, "
     "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; Android "
     "4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) "
-    "Chrome/29.0.1547.72 Safari/537.36\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Google Nexus 7\", \"width\": 966, \"height\": 604, "
-    "\"deviceScaleFactor\": 1.325, \"userAgent\": \"Mozilla/5.0 (Linux; "
-    "Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) "
-    "Chrome/29.0.1547.72 Safari/537.36\", \"touch\": true, \"mobile\": "
-    "true},{\"title\": \"Motorola Xoom, Xyboard\", \"width\": 1280, "
-    "\"height\": 800, \"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 "
-    "(Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 "
-    "(KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2\", \"touch\": "
-    "true, \"mobile\": true},{\"title\": \"Samsung Galaxy Tab 7.7, 8.9, "
-    "10.1\", \"width\": 1280, \"height\": 800, \"deviceScaleFactor\": 1, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 "
-    "Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile "
-    "Safari/533.1\", \"touch\": true, \"mobile\": true},{\"title\": \"Samsung "
-    "Galaxy Tab\", \"width\": 1024, \"height\": 600, \"deviceScaleFactor\": 1, "
-    "\"userAgent\": \"Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 "
-    "Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile "
-    "Safari/533.1\", \"touch\": true, \"mobile\": true}]";
+    "Chrome/42.0.2307.2 Mobile Safari/537.36\", \"touch\": true, \"mobile\": "
+    "true},{\"title\": \"Samsung Galaxy Note 3\", \"width\": 360, \"height\": "
+    "640, \"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 (Linux; U; "
+    "Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, "
+    "like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, "
+    "\"mobile\": true},{\"title\": \"Samsung Galaxy Note II\", \"width\": 360, "
+    "\"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 "
+    "(Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 "
+    "(KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, "
+    "\"mobile\": true},{\"title\": \"Laptop with touch\", \"width\": 1280, "
+    "\"height\": 950, \"deviceScaleFactor\": 1, \"userAgent\": \"\", "
+    "\"touch\": true, \"mobile\": false},{\"title\": \"Laptop with HiDPI "
+    "screen\", \"width\": 1440, \"height\": 900, \"deviceScaleFactor\": 2, "
+    "\"userAgent\": \"\", \"touch\": false, \"mobile\": false},{\"title\": "
+    "\"Laptop with MDPI screen\", \"width\": 1280, \"height\": 800, "
+    "\"deviceScaleFactor\": 1, \"userAgent\": \"\", \"touch\": false, "
+    "\"mobile\": false}]";
diff --git a/chrome/test/chromedriver/chrome/mobile_device_list.h b/chrome/test/chromedriver/chrome/mobile_device_list.h
index e2bb874..e85e3a4 100644
--- a/chrome/test/chromedriver/chrome/mobile_device_list.h
+++ b/chrome/test/chromedriver/chrome/mobile_device_list.h
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// This file was generated at (2015-01-22 12:13:16.600114) by running:
+// This file was generated at (2015-03-30 16:08:35.102812) by running:
 //     chrome/test/chromedriver/embed_mobile_devices_in_cpp.py --directory
 //     chrome/test/chromedriver/chrome/
 //     third_party/WebKit/Source/devtools/front_end/toolbox/OverridesUI.js
diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
index ca3c531..34d6d10 100644
--- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
+++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
@@ -56,9 +56,12 @@
   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);
+  if (overridden_device_metrics_->touch) {
+    base::DictionaryValue emulate_touch_params;
+    emulate_touch_params.SetBoolean("enabled", true);
+    status = client_->SendCommand(
+        "Page.setTouchEmulationEnabled", emulate_touch_params);
+  }
+
+  return Status(kOk);
 }
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 c8cf20c..e980205 100644
--- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc
+++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc
@@ -36,9 +36,9 @@
 
 }  // namespace
 
-TEST(MobileEmulationOverrideManager, SendsCommandOnConnect) {
+TEST(MobileEmulationOverrideManager, SendsCommandWithTouchOnConnect) {
   RecorderDevToolsClient client;
-  DeviceMetrics device_metrics(1, 2, 3.0);
+  DeviceMetrics device_metrics(1, 2, 3.0, true, true);
   MobileEmulationOverrideManager manager(&client, &device_metrics);
   ASSERT_EQ(0u, client.commands_.size());
   ASSERT_EQ(kOk, manager.OnConnected(&client).code());
@@ -50,9 +50,23 @@
       AssertDeviceMetricsCommand(client.commands_[2], device_metrics));
 }
 
+TEST(MobileEmulationOverrideManager, SendsCommandWithoutTouchOnConnect) {
+  RecorderDevToolsClient client;
+  DeviceMetrics device_metrics(1, 2, 3.0, false, true);
+  MobileEmulationOverrideManager manager(&client, &device_metrics);
+  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_NO_FATAL_FAILURE(
+      AssertDeviceMetricsCommand(client.commands_[1], device_metrics));
+}
+
 TEST(MobileEmulationOverrideManager, SendsCommandOnNavigation) {
   RecorderDevToolsClient client;
-  DeviceMetrics device_metrics(1, 2, 3.0);
+  DeviceMetrics device_metrics(1, 2, 3.0, true, true);
   MobileEmulationOverrideManager manager(&client, &device_metrics);
   base::DictionaryValue main_frame_params;
   ASSERT_EQ(kOk,
diff --git a/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py b/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py
index 327012d..2aed44b 100755
--- a/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py
+++ b/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py
@@ -50,6 +50,9 @@
         if 'WebInspector.OverridesUI._tablets = [' in line:
           devices += ','
           inside_list = True
+        if 'WebInspector.OverridesUI._notebooks = [' in line:
+          devices += ','
+          inside_list = True
       else:
         if line.strip() == '];':
           inside_list = False
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 6a417f3..ef0506d3 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -1231,9 +1231,9 @@
     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'
-        'ebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/53'
-        '5.19',
+        'Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 5 Build/JOP40D) '
+        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 Mobile '
+        'Safari/537.36',
         body_tag.GetText())
 
   def testSendKeysToElement(self):
diff --git a/chrome/test/data/android/banners/native_app_manifest.json b/chrome/test/data/android/banners/native_app_manifest.json
new file mode 100644
index 0000000..f17b499e
--- /dev/null
+++ b/chrome/test/data/android/banners/native_app_manifest.json
@@ -0,0 +1,7 @@
+{
+  "prefer_related_applications": true,
+  "related_applications": [{
+    "platform": "play",
+    "id": "test.package"
+  }]
+}
diff --git a/chrome/test/data/android/banners/native_app_test.html b/chrome/test/data/android/banners/native_app_test.html
index 3575a3a0..28f4f6c 100644
--- a/chrome/test/data/android/banners/native_app_test.html
+++ b/chrome/test/data/android/banners/native_app_test.html
@@ -1,7 +1,7 @@
 <html>
   <head>
     <title>AppBannerManager test page</title>
-    <meta name="google-play-id" content="test.package" />
+    <link rel="manifest" href="native_app_manifest.json" />
   </head>
   <body>
     Promoting the "test.package" package.
diff --git a/chrome/test/data/banners/play_app_manifest.json b/chrome/test/data/banners/play_app_manifest.json
new file mode 100644
index 0000000..170015f
--- /dev/null
+++ b/chrome/test/data/banners/play_app_manifest.json
@@ -0,0 +1,7 @@
+{
+  "prefer_related_applications": true,
+  "related_applications": [{
+    "platform": "play",
+    "id": "123456"
+  }]
+}
diff --git a/chrome/test/data/banners/play_app_test_page.html b/chrome/test/data/banners/play_app_test_page.html
new file mode 100644
index 0000000..459d19c
--- /dev/null
+++ b/chrome/test/data/banners/play_app_test_page.html
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <title>Web app banner test page</title>
+    <link rel="manifest" href="play_app_manifest.json" />
+  </head>
+  <body onload="initialize()">
+    Do-nothing page with a service worker. 
+  </body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/bluetooth_private/discovery_filter/manifest.json b/chrome/test/data/extensions/api_test/bluetooth_private/discovery_filter/manifest.json
new file mode 100644
index 0000000..5b6dfb94
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/bluetooth_private/discovery_filter/manifest.json
@@ -0,0 +1,15 @@
+{
+  // extension id: jofgjdphhceggjecimellaapdjjadibj
+  "name": "Test Setting Bluetooth Discovery Filter",
+  "description": "Tests chrome.bluetoothPrivate.setDiscoveryFilter function.",
+  "version": "1.0",
+  "manifest_version": 2,
+  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2nI64+TVbJNYUfte1hEwrWpjgiH3ucfKZ12NC6IT/Pm2pQdjR/3alrdW+rCkYbs0KmfUymb0GOE7fwZ0Gs+EqfxoKmwJaaZiv86GXEkPJctDvjqrJRUrKvM6aXZEkTQeaFLQVY9NDk3grSZzvC365l3c4zRN3A2i8KMWzB9HRQzKnN49zjgcTTu5DERYTzbJZBd0m9Ln1b3x3UVkVgoTUq7DexGMcOq1KYz0VHrFRo/LN1yJvECFmBb2pdl40g4UHq3UqrWDDInZZJ3sr01EePxYYwimMFsGnvH6sz8wHC09rXZ+w1YFYjsQ3P/3Bih1q/NdZ0aop3MEOCbHb4gipQIDAQAB",
+  "app": {
+    "background": {
+      "scripts": ["test.js"]
+    }
+  },
+  "bluetooth": {},
+  "permissions": [ "bluetoothPrivate" ]
+}
diff --git a/chrome/test/data/extensions/api_test/bluetooth_private/discovery_filter/test.js b/chrome/test/data/extensions/api_test/bluetooth_private/discovery_filter/test.js
new file mode 100644
index 0000000..cb30cc6
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/bluetooth_private/discovery_filter/test.js
@@ -0,0 +1,29 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function testSetDiscoveryFilter() {
+  // Pre-set discovery filter
+  chrome.bluetoothPrivate.setDiscoveryFilter(
+    {
+      uuids: ["cafe", "0000bebe-0000-1000-8000-00805f9b34fb"],
+      transport: "le",
+      pathloss: 50
+    },
+    function() {
+      chrome.test.assertNoLastError();
+      // Start discovery with pre-set filter.
+      chrome.bluetooth.startDiscovery(function(){
+        chrome.test.assertNoLastError();
+
+        // Change filter (clear) during scan.
+        chrome.bluetoothPrivate.setDiscoveryFilter({}, function() {
+          chrome.test.assertNoLastError();
+          // Success.
+          chrome.test.succeed();
+        });
+      });
+  });
+}
+
+chrome.test.runTests([ testSetDiscoveryFilter ]);
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/embedded.html b/chrome/test/data/extensions/api_test/mime_handler_view/embedded.html
deleted file mode 100644
index b5648d6..0000000
--- a/chrome/test/data/extensions/api_test/mime_handler_view/embedded.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>
-<body>
-This is the embedded MIME type handler.
-</body>
-<script src="embedded.js"></script>
-</html>
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/index.html b/chrome/test/data/extensions/api_test/mime_handler_view/index.html
new file mode 100644
index 0000000..ea5d99fa
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/index.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+This is the MIME type handler.
+</body>
+<script src="index.js"></script>
+</html>
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/embedded.js b/chrome/test/data/extensions/api_test/mime_handler_view/index.js
similarity index 74%
rename from chrome/test/data/extensions/api_test/mime_handler_view/embedded.js
rename to chrome/test/data/extensions/api_test/mime_handler_view/index.js
index 73415213..1fbe620 100644
--- a/chrome/test/data/extensions/api_test/mime_handler_view/embedded.js
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/index.js
@@ -38,15 +38,24 @@
   chrome.test.assertEq('content to read\n', response.data);
 }
 
+function expectSuccessfulReadLong(response) {
+  chrome.test.assertEq(200, response.status);
+  chrome.test.assertTrue(response.data.indexOf('content to read\n') === 0);
+}
+
 function checkStreamDetails(name, embedded) {
-  chrome.test.assertTrue(streamDetails.originalUrl.indexOf(name) != -1);
-  chrome.test.assertEq('text/csv', streamDetails.mimeType);
-  chrome.test.assertTrue(streamDetails.tabId != -1);
+  checkStreamDetailsNoFile();
   chrome.test.assertEq(embedded, streamDetails.embedded);
+  chrome.test.assertTrue(streamDetails.originalUrl.indexOf(name) != -1);
   chrome.test.assertEq('text/csv',
                        streamDetails.responseHeaders['Content-Type']);
 }
 
+function checkStreamDetailsNoFile() {
+  chrome.test.assertEq('text/csv', streamDetails.mimeType);
+  chrome.test.assertTrue(streamDetails.tabId != -1);
+}
+
 var tests = [
   function testBasic() {
     checkStreamDetails('testBasic.csv', false);
@@ -86,6 +95,15 @@
     });
   },
 
+  function testNonAsciiHeaders() {
+    checkStreamDetails('testNonAsciiHeaders.csv', false);
+    chrome.test.assertEq(undefined,
+                         streamDetails.responseHeaders['Content-Disposition']);
+    chrome.test.assertEq(undefined,
+                         streamDetails.responseHeaders['ü']);
+    chrome.test.succeed();
+  },
+
   function testPostMessage() {
     var expectedMessages = ['hey', 100, 25.0];
     var messagesReceived = 0;
@@ -107,6 +125,21 @@
       handleMessage(queuedMessages.shift());
     }
 
+  },
+
+  function testDataUrl() {
+    // TODO(raymes): have separate checks for embedded/unembedded data URLs.
+    checkStreamDetailsNoFile();
+    fetchUrl(streamDetails.streamUrl)
+        .then(expectSuccessfulRead)
+        .then(chrome.test.succeed);
+  },
+
+  function testDataUrlLong() {
+    checkStreamDetailsNoFile();
+    fetchUrl(streamDetails.streamUrl)
+        .then(expectSuccessfulReadLong)
+        .then(chrome.test.succeed);
   }
 ];
 
@@ -128,4 +161,14 @@
     window.removeEventListener('message', queueMessage);
     chrome.test.runTests([testsByName[test]]);
   }
+
+  // Run the test for data URLs.
+  if (streamInfo.originalUrl.indexOf("data:") === 0) {
+    window.removeEventListener('message', queueMessage);
+    // Long data URLs get truncated.
+    if (streamInfo.originalUrl == "data:")
+      chrome.test.runTests([testsByName['testDataUrlLong']]);
+    else
+      chrome.test.runTests([testsByName['testDataUrl']]);
+  }
 });
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/manifest.json b/chrome/test/data/extensions/api_test/mime_handler_view/manifest.json
index 3519fd4..bc5c1025 100644
--- a/chrome/test/data/extensions/api_test/mime_handler_view/manifest.json
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/manifest.json
@@ -6,5 +6,5 @@
   "mime_types": [
     "text/csv"
   ],
-  "mime_types_handler": "embedded.html"
+  "mime_types_handler": "index.html"
 }
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/testNonAsciiHeaders.csv b/chrome/test/data/extensions/api_test/mime_handler_view/testNonAsciiHeaders.csv
new file mode 100644
index 0000000..1e30f4ad
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/testNonAsciiHeaders.csv
@@ -0,0 +1 @@
+content to read
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/testNonAsciiHeaders.csv.mock-http-headers b/chrome/test/data/extensions/api_test/mime_handler_view/testNonAsciiHeaders.csv.mock-http-headers
new file mode 100644
index 0000000..e23b9e4
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/testNonAsciiHeaders.csv.mock-http-headers
@@ -0,0 +1,4 @@
+HTTP/1.0 200 OK
+Content-Type: text/csv
+Content-Disposition: inline; filename=ü
+ü: value
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_embed.html b/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_embed.html
new file mode 100644
index 0000000..046377e5
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_embed.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<embed id="plugin" width="200" height="200" src="data:text/csv;base64,Y29udGVudCB0byByZWFkCg==" type="text/csv"></object>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_long.html b/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_long.html
new file mode 100644
index 0000000..c2d88951
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_long.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<object id="plugin" width="200" height="200" data="data:text/csv;base64,Y29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCmNvbnRlbnQgdG8gcmVhZApjb250ZW50IHRvIHJlYWQKY29udGVudCB0byByZWFkCg==" type="text/csv"></object>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_object.html b/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_object.html
new file mode 100644
index 0000000..6d17d01b3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/test_embedded_data_url_object.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<object id="plugin" width="200" height="200" data="data:text/csv;base64,Y29udGVudCB0byByZWFkCg==" type="text/csv"></object>
+</body>
+</html>
diff --git a/chrome/test/data/nacl/nacl_test_data.gyp b/chrome/test/data/nacl/nacl_test_data.gyp
index 0372000..78d3aa6 100644
--- a/chrome/test/data/nacl/nacl_test_data.gyp
+++ b/chrome/test/data/nacl/nacl_test_data.gyp
@@ -126,9 +126,6 @@
 	  'simple_cc.js',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
     {
       'target_name': 'sysconf_nprocessors_onln_test',
@@ -166,9 +163,6 @@
           '../../../../ppapi/native_client/tests/ppapi_test_lib/testable_callback.cc',
         ]
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
     {
       'target_name': 'ppapi_progress_events',
@@ -193,7 +187,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -220,7 +213,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -245,7 +237,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -270,7 +261,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -295,7 +285,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -320,7 +309,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -345,7 +333,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -371,7 +358,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -399,7 +385,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -427,7 +412,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -455,7 +439,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -483,7 +466,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -525,7 +507,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/ppapi/ppapi_nacl.gyp:ppapi_cpp_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
         '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:aot',
@@ -586,7 +567,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:nacl_exception_lib',
@@ -641,7 +621,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
@@ -666,9 +645,6 @@
           'pnacl_debug_url/pnacl_no_debug.nmf',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ]
     },
     {
       'target_name': 'pnacl_error_handling_test',
@@ -686,9 +662,6 @@
           'pnacl_error_handling/pnacl_illformed_manifest.nmf',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ]
     },
     {
       'target_name': 'pnacl_mime_type_test',
@@ -721,9 +694,6 @@
           'pnacl_nmf_options/pnacl_o_large.nmf',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ]
     },
     {
       'target_name': 'pnacl_dyncode_syscall_disabled_test',
@@ -754,7 +724,6 @@
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:nacl_dyncode_private_lib',
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
         '<(DEPTH)/ppapi/ppapi_nacl.gyp:ppapi_cpp_lib',
         'ppapi_test_lib',
@@ -789,7 +758,6 @@
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:nacl_exception_private_lib',
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
         '<(DEPTH)/ppapi/ppapi_nacl.gyp:ppapi_cpp_lib',
         'ppapi_test_lib',
@@ -819,7 +787,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -850,7 +817,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -882,7 +848,6 @@
         ],
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform_lib',
         '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio_lib',
         '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib',
@@ -920,9 +885,6 @@
               }],
             ],
           },
-          'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-          ],
         },
       ],
     }],
diff --git a/chrome/test/data/navigation_interception/navigation_from_image_onload.html b/chrome/test/data/navigation_interception/navigation_from_image_onload.html
new file mode 100644
index 0000000..6d053f5
--- /dev/null
+++ b/chrome/test/data/navigation_interception/navigation_from_image_onload.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<!--
+
+Copyright 2015 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+-->
+<head>
+  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
+  <style>
+    #first {
+      position: absolute;
+      width: 100px;
+      height: 100px;
+      top: 0px;
+      left: 0px;
+      background-color: green;
+      -webkit-transform: translate3d(0, 0, 0);
+    }
+  </style>
+  <script>
+    function pingAndOpenHello(e) {
+      var img = new Image();
+      img.onload = function () {
+        window.location = 'hello.html';
+      }
+      img.src = '../image_search/valid.png';
+
+      e.preventDefault();
+    };
+
+    function setup() {
+      first.ontouchstart = pingAndOpenHello;
+    };
+  </script>
+</head>
+<body onload='setup();'>
+  <div id='first'></div>
+</body>
+</html>
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js
index 21c6bb9..149fe2f 100644
--- a/chrome/test/data/pdf/navigator_test.js
+++ b/chrome/test/data/pdf/navigator_test.js
@@ -32,7 +32,7 @@
     var mockSizer = new MockSizer();
     var mockCallback = new MockViewportChangedCallback();
     var viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
 
     var paramsParser = new OpenPDFParamsParser(function(name) {
       if (name == 'US')
diff --git a/chrome/test/data/pdf/viewport_test.js b/chrome/test/data/pdf/viewport_test.js
index fc232a93..a513de93 100644
--- a/chrome/test/data/pdf/viewport_test.js
+++ b/chrome/test/data/pdf/viewport_test.js
@@ -6,7 +6,7 @@
   function testDocumentNeedsScrollbars() {
     var viewport =
         new Viewport(new MockWindow(100, 100), new MockSizer(), function() {},
-                     function() {}, function() {}, 10, 0);
+                     function() {}, function() {}, 10, 1);
     var scrollbars;
 
     viewport.setDocumentDimensions(new MockDocumentDimensions(90, 90));
@@ -61,7 +61,7 @@
     var mockWindow = new MockWindow(100, 100, mockSizer);
     var mockCallback = new MockViewportChangedCallback();
     var viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
 
     // Test setting the zoom without the document dimensions set. The sizer
     // shouldn't change size.
@@ -136,7 +136,7 @@
   function testGetMostVisiblePage() {
     var mockWindow = new MockWindow(100, 100);
     var viewport = new Viewport(mockWindow, new MockSizer(), function() {},
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
 
     var documentDimensions = new MockDocumentDimensions(100, 100);
     documentDimensions.addPage(50, 100);
@@ -186,7 +186,7 @@
     var mockSizer = new MockSizer();
     var mockCallback = new MockViewportChangedCallback();
     var viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
     var documentDimensions = new MockDocumentDimensions();
 
     // Test with a document width which matches the window width.
@@ -245,7 +245,7 @@
     // fit to width, which will cause the page height to span outside of the
     // viewport, triggering 15px scrollbars to be shown.
     viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                            function() {}, function() {}, 15, 0);
+                            function() {}, function() {}, 15, 1);
     documentDimensions.reset();
     documentDimensions.addPage(50, 100);
     viewport.setDocumentDimensions(documentDimensions);
@@ -264,7 +264,7 @@
     var mockSizer = new MockSizer();
     var mockCallback = new MockViewportChangedCallback();
     var viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
     var documentDimensions = new MockDocumentDimensions();
 
     // Test with a page size which matches the window size.
@@ -373,7 +373,7 @@
     var mockSizer = new MockSizer();
     var mockCallback = new MockViewportChangedCallback();
     var viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
     var documentDimensions = new MockDocumentDimensions();
 
     documentDimensions.addPage(100, 100);
@@ -414,7 +414,7 @@
     var mockSizer = new MockSizer();
     var mockCallback = new MockViewportChangedCallback();
     var viewport = new Viewport(mockWindow, mockSizer, mockCallback.callback,
-                                function() {}, function() {}, 0, 0);
+                                function() {}, function() {}, 0, 1);
     var documentDimensions = new MockDocumentDimensions();
     documentDimensions.addPage(100, 100);
     documentDimensions.addPage(200, 200);
@@ -469,10 +469,28 @@
         chrome.test.assertEq(1, viewport.zoom);
     };
     viewport = new Viewport(mockWindow, mockSizer, function() {},
-                            beforeZoom, afterZoom, 0, 0);
+                            beforeZoom, afterZoom, 0, 1);
     viewport.setZoom(0.5);
     chrome.test.succeed();
-  }
+  },
+
+  function testInitialSetDocumentDimensionsZoomConstrained() {
+    var viewport =
+        new Viewport(new MockWindow(100, 100), new MockSizer(), function() {},
+                     function() {}, function() {}, 0, 1.2);
+    viewport.setDocumentDimensions(new MockDocumentDimensions(50, 50));
+    chrome.test.assertEq(1.2, viewport.zoom);
+    chrome.test.succeed();
+  },
+
+  function testInitialSetDocumentDimensionsZoomUnconstrained() {
+    var viewport = new Viewport(
+        new MockWindow(100, 100),
+        new MockSizer(), function() {}, function() {}, function() {}, 0, 3);
+    viewport.setDocumentDimensions(new MockDocumentDimensions(50, 50));
+    chrome.test.assertEq(2, viewport.zoom);
+    chrome.test.succeed();
+  },
 ];
 
 chrome.test.runTests(tests);
diff --git a/chrome/test/data/pdf/zoom_manager_test.js b/chrome/test/data/pdf/zoom_manager_test.js
index 6ce0a3b1b..f02010c6 100644
--- a/chrome/test/data/pdf/zoom_manager_test.js
+++ b/chrome/test/data/pdf/zoom_manager_test.js
@@ -54,7 +54,8 @@
       let viewport = new MockViewport();
       let browserZoomSetter = new MockBrowserZoomSetter();
       let zoomManager = new ZoomManager(
-          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter));
+          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter),
+          1);
       viewport.zoom = 2;
       zoomManager.onPdfZoomChange();
       chrome.test.assertEq(2, browserZoomSetter.zoom);
@@ -62,21 +63,9 @@
       chrome.test.succeed();
     },
 
-    function testZoomChangedBeforeConstruction() {
-      let viewport = new MockViewport();
-      viewport.zoom = 2;
-      let browserZoomSetter = new MockBrowserZoomSetter();
-      let zoomManager = new ZoomManager(
-          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter));
-      chrome.test.assertEq(2, browserZoomSetter.zoom);
-      chrome.test.assertTrue(browserZoomSetter.started);
-      chrome.test.succeed();
-    },
-
     function testBrowserZoomChange() {
       let viewport = new MockViewport();
-      let zoomManager = new ZoomManager(viewport, Promise.resolve.bind(Promise),
-                                        chrome.test.fail);
+      let zoomManager = new ZoomManager(viewport, chrome.test.fail, 1);
       zoomManager.onBrowserZoomChange(3);
       chrome.test.assertEq(1, viewport.zooms.length);
       chrome.test.assertEq(3, viewport.zooms[0]);
@@ -88,8 +77,9 @@
       let viewport = new MockViewport();
       let browserZoomSetter = new MockBrowserZoomSetter();
       let zoomManager = new ZoomManager(
-          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter));
-      viewport.zoom = 1.0001;
+          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter),
+          2);
+      viewport.zoom = 2.0001;
       zoomManager.onPdfZoomChange();
       chrome.test.assertEq(1, browserZoomSetter.zoom);
       chrome.test.assertFalse(browserZoomSetter.started);
@@ -98,8 +88,7 @@
 
     function testSmallBrowserZoomChange() {
       let viewport = new MockViewport();
-      let zoomManager = new ZoomManager(viewport, Promise.resolve.bind(Promise),
-                                        chrome.test.fail);
+      let zoomManager = new ZoomManager(viewport, chrome.test.fail, 1);
       zoomManager.onBrowserZoomChange(0.999);
       chrome.test.assertEq(0, viewport.zooms.length);
       chrome.test.assertEq(1, viewport.zoom);
@@ -110,7 +99,8 @@
       let viewport = new MockViewport();
       let browserZoomSetter = new MockBrowserZoomSetter();
       let zoomManager = new ZoomManager(
-          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter));
+          viewport, browserZoomSetter.setBrowserZoom.bind(browserZoomSetter),
+          1);
       viewport.zoom = 2;
       zoomManager.onPdfZoomChange();
       viewport.zoom = 3;
@@ -127,8 +117,7 @@
 
     function testMultipleBrowserZoomChanges() {
       let viewport = new MockViewport();
-      let zoomManager = new ZoomManager(viewport, Promise.resolve.bind(Promise),
-                                        chrome.test.fail);
+      let zoomManager = new ZoomManager(viewport, chrome.test.fail, 1);
       zoomManager.onBrowserZoomChange(2);
       zoomManager.onBrowserZoomChange(3);
       chrome.test.assertEq(2, viewport.zooms.length);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 7106453..cb38eb4 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2300,8 +2300,8 @@
     "official_only": true,
     "test_policy": { "DeviceMetricsReportingEnabled": true },
     "pref_mappings": [
-      { "pref": "spellcheck.use_spelling_service",
-        "indicator_test_setup_js": "Preferences.getInstance().addEventListener('alternate_error_pages.enabled', function(event) { Preferences.prefsChangedCallback(['cros.metrics.reportingEnabled', {value: event.value.value, controlledBy: event.value.controlledBy, disabled: event.value.disabled}]); });",
+      { "pref": "cros.metrics.reportingEnabled",
+        "indicator_test_setup_js": "var controllingPref = 'spellcheck.use_spelling_service'; var testedPref = 'cros.metrics.reportingEnabled'; Preferences.prefsChangedCallback([testedPref, Preferences.getInstance().registeredPreferences_[controllingPref].orig]); Preferences.getInstance().addEventListener(controllingPref, function(event) {Preferences.prefsChangedCallback([testedPref, {value: event.value.value, controlledBy: event.value.controlledBy, disabled: event.value.disabled}]);});",
         "indicator_tests": [
           { "policy": { "SpellCheckServiceEnabled": true } }
         ]
diff --git a/chrome/test/data/push_messaging/push_test.js b/chrome/test/data/push_messaging/push_test.js
index be99f62..19118ad 100644
--- a/chrome/test/data/push_messaging/push_test.js
+++ b/chrome/test/data/push_messaging/push_test.js
@@ -5,7 +5,7 @@
 'use strict';
 
 var resultQueue = new ResultQueue();
-var pushRegistration = null;
+var pushSubscription = null;
 
 // Sends data back to the test. This must be in response to an earlier
 // request, but it's ok to respond asynchronously. The request blocks until
@@ -57,7 +57,7 @@
 };
 
 // Notification permission has been coalesced with Push permission. After
-// this is granted, Push API registration can succeed.
+// this is granted, Push API subscription can succeed.
 function requestNotificationPermission() {
   Notification.requestPermission(function(permission) {
     sendResultToTest('permission status - ' + permission);
@@ -92,15 +92,13 @@
   }
 }
 
-function registerPush() {
+function subscribePush() {
   navigator.serviceWorker.ready.then(function(swRegistration) {
-    var registerMethodName =
-        swRegistration.pushManager.register ? 'register' : 'subscribe';
-    return swRegistration.pushManager[registerMethodName]()
-        .then(function(registration) {
-          pushRegistration = registration;
-          sendResultToTest(registration.endpoint + ' - ' +
-              (registration.registrationId || registration.subscriptionId));
+    return swRegistration.pushManager.subscribe()
+        .then(function(subscription) {
+          pushSubscription = subscription;
+          sendResultToTest(
+              subscription.endpoint + ' - ' + subscription.subscriptionId);
         });
   }).catch(sendErrorToTest);
 }
@@ -122,27 +120,25 @@
   }
 }
 
-function unregister() {
-  if (!pushRegistration) {
-    sendResultToTest('unregister error: no registration');
+function unsubscribePush() {
+  if (!pushSubscription) {
+    sendResultToTest('unsubscribe error: no subscription');
     return;
   }
 
-  var unregisterMethodName =
-      pushRegistration.unregister ? 'unregister' : 'unsubscribe';
-  pushRegistration[unregisterMethodName]().then(function(result) {
-    sendResultToTest('unregister result: ' + result);
+  pushSubscription.unsubscribe().then(function(result) {
+    sendResultToTest('unsubscribe result: ' + result);
   }, function(error) {
-    sendResultToTest('unregister error: ' + error.name + ': ' + error.message);
+    sendResultToTest('unsubscribe error: ' + error.name + ': ' + error.message);
   });
 }
 
-function hasRegistration() {
+function hasSubscription() {
   navigator.serviceWorker.ready.then(function(swRegistration) {
     return swRegistration.pushManager.getSubscription();
   }).then(function(subscription) {
-    sendResultToTest(subscription ? 'true - registered'
-                                  : 'false - not registered');
+    sendResultToTest(subscription ? 'true - subscribed'
+                                  : 'false - not subscribed');
   }).catch(sendErrorToTest);
 }
 
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index c469307..dbf408f 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -83,21 +83,15 @@
     }
   }
 
-  if (use_openssl) {
-    if (!is_win && !is_mac && !is_android) {
-      sources -= [ "importer/nss_decryptor.cc" ]
-    }
-  } else {  # !use_openssl
-    if (!is_win && !is_mac) {
-      sources += [
-        "importer/nss_decryptor_system_nss.cc",
-        "importer/nss_decryptor_system_nss.h",
-      ]
-      deps += [
-        "//crypto",
-        "//crypto:platform",
-      ]
-    }
+  if (use_nss_certs) {
+    sources += [
+      "importer/nss_decryptor_system_nss.cc",
+      "importer/nss_decryptor_system_nss.h",
+    ]
+    deps += [
+      "//crypto",
+      "//crypto:platform",
+    ]
   }
 
   if (!enable_print_preview) {
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc
index 1c79cdf4..111ac99c 100644
--- a/chrome/utility/chrome_content_utility_client.cc
+++ b/chrome/utility/chrome_content_utility_client.cc
@@ -207,9 +207,13 @@
 // static
 SkBitmap ChromeContentUtilityClient::DecodeImage(
     const std::vector<unsigned char>& encoded_data, bool shrink_to_fit) {
-  SkBitmap decoded_image = content::DecodeImage(&encoded_data[0],
-                                                gfx::Size(),
-                                                encoded_data.size());
+  SkBitmap decoded_image;
+  if (encoded_data.empty())
+    return decoded_image;
+
+  decoded_image = content::DecodeImage(&encoded_data[0],
+                                       gfx::Size(),
+                                       encoded_data.size());
 
   int64_t struct_size = sizeof(ChromeUtilityHostMsg_DecodeImage_Succeeded);
   int64_t image_size = decoded_image.computeSize64();
@@ -298,10 +302,9 @@
   Send(new ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl(
       supports_prctl));
 
-  bool supports_syscall = sandbox::SandboxBPF::SupportsSeccompSandbox(
-      sandbox::SandboxBPF::SeccompLevel::MULTI_THREADED);
-  Send(new ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall(
-      supports_syscall));
+  // Probing for the seccomp syscall can provoke kernel panics in certain LGE
+  // devices. For now, this data will not be collected. In the future, this
+  // should detect SeccompLevel::MULTI_THREADED. http://crbug.com/478478
 
   ReleaseProcessIfNeeded();
 }
diff --git a/chrome/utility/importer/ie_importer_win.cc b/chrome/utility/importer/ie_importer_win.cc
index 8da54a3..e1f5e4fb 100644
--- a/chrome/utility/importer/ie_importer_win.cc
+++ b/chrome/utility/importer/ie_importer_win.cc
@@ -634,7 +634,7 @@
     // import a password from IE whose scheme is https, we give it the benefit
     // of the doubt and DON'T auto-fill it unless the form appears under
     // valid TLS conditions.
-    form.ssl_valid = url.SchemeUsesTLS();
+    form.ssl_valid = url.SchemeIsCryptographic();
 
     // Goes through the list to find out the username field
     // of the web page.
diff --git a/chrome/utility/importer/nss_decryptor.cc b/chrome/utility/importer/nss_decryptor.cc
index 5c54638..01bdb0a 100644
--- a/chrome/utility/importer/nss_decryptor.cc
+++ b/chrome/utility/importer/nss_decryptor.cc
@@ -202,7 +202,7 @@
     form.signon_realm = form.origin.GetOrigin().spec();
     if (!realm.empty())
       form.signon_realm += realm;
-    form.ssl_valid = form.origin.SchemeUsesTLS();
+    form.ssl_valid = form.origin.SchemeIsCryptographic();
     ++begin;
 
     // There may be multiple username/password pairs for this site.
@@ -296,7 +296,7 @@
       // digest_auth entry, so let's assume basic_auth.
       form.scheme = autofill::PasswordForm::SCHEME_BASIC;
     }
-    form.ssl_valid = form.origin.SchemeUsesTLS();
+    form.ssl_valid = form.origin.SchemeIsCryptographic();
     // The user name, password and action.
     form.username_element = s2.ColumnString16(3);
     form.username_value = Decrypt(s2.ColumnString(5));
diff --git a/chrome/utility/importer/nss_decryptor.h b/chrome/utility/importer/nss_decryptor.h
index 5c36112..d53e640b 100644
--- a/chrome/utility/importer/nss_decryptor.h
+++ b/chrome/utility/importer/nss_decryptor.h
@@ -11,15 +11,10 @@
 #include "chrome/utility/importer/nss_decryptor_mac.h"
 #elif defined(OS_WIN)
 #include "chrome/utility/importer/nss_decryptor_win.h"
-#elif defined(USE_OPENSSL)
-// TODO(joth): It should be an error to include this file with USE_OPENSSL
-// defined. (Unless there is a way to do nss decrypt with OpenSSL). Ideally
-// we remove the importers that depend on NSS when doing USE_OPENSSL builds, but
-// that is going to take some non-trivial refactoring so in the meantime we're
-// just falling back to a no-op implementation.
-#include "chrome/utility/importer/nss_decryptor_null.h"
 #elif defined(USE_NSS_CERTS)
 #include "chrome/utility/importer/nss_decryptor_system_nss.h"
+#else
+#error NSSDecryptor not implemented.
 #endif
 
 #endif  // CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_H_
diff --git a/chrome/utility/importer/nss_decryptor_null.h b/chrome/utility/importer/nss_decryptor_null.h
deleted file mode 100644
index e99334ba..0000000
--- a/chrome/utility/importer/nss_decryptor_null.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_NULL_H_
-#define CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_NULL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-
-namespace autofill {
-struct PasswordForm;
-}
-
-namespace base {
-class FilePath;
-}
-
-// A NULL wrapper for Firefox NSS decrypt component, for use in builds where
-// we do not have the NSS library.
-class NSSDecryptor {
- public:
-  NSSDecryptor() {}
-  bool Init(const base::FilePath& dll_path, const base::FilePath& db_path) {
-    return false;
-  }
-  base::string16 Decrypt(const std::string& crypt) const {
-    return base::string16();
-  }
-  void ParseSignons(const std::string& content,
-                    std::vector<autofill::PasswordForm>* forms) {}
-  bool ReadAndParseSignons(const base::FilePath& sqlite_file,
-                           std::vector<autofill::PasswordForm>* forms) {
-    return false;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NSSDecryptor);
-};
-
-#endif  // CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_NULL_H_
diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc
index 31219cc9..6aef1cc 100644
--- a/chrome_elf/blacklist/blacklist.cc
+++ b/chrome_elf/blacklist/blacklist.cc
@@ -41,6 +41,7 @@
   L"crdli.dll",                         // Linkury Inc.
   L"crdli64.dll",                       // Linkury Inc.
   L"datamngr.dll",                      // Unknown (suspected adware).
+  L"explorerex.dll",                    // Unknown (suspected adware).
   L"hk.dll",                            // Unknown (keystroke logger).
   L"libapi2hook.dll",                   // V-Bates.
   L"libinject.dll",                     // V-Bates.
diff --git a/chrome_elf/chrome_elf_util_unittest.cc b/chrome_elf/chrome_elf_util_unittest.cc
index 90b04ed1..ad83801 100644
--- a/chrome_elf/chrome_elf_util_unittest.cc
+++ b/chrome_elf/chrome_elf_util_unittest.cc
@@ -57,7 +57,7 @@
                                              const char*,
                                              const char*> > {
  protected:
-  virtual void SetUp() override {
+  void SetUp() override {
     override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE);
     override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
     const char* app;
diff --git a/chrome_elf/create_file/chrome_create_file_unittest.cc b/chrome_elf/create_file/chrome_create_file_unittest.cc
index cd66d47..8b0331fe 100644
--- a/chrome_elf/create_file/chrome_create_file_unittest.cc
+++ b/chrome_elf/create_file/chrome_create_file_unittest.cc
@@ -76,7 +76,7 @@
         path);
   }
 
-  virtual void SetUp() override {
+  void SetUp() override {
     original_thread_ = base::PlatformThread::CurrentId();
     InitCache();
     PlatformTest::SetUp();
diff --git a/chrome_elf/ntdll_cache_unittest.cc b/chrome_elf/ntdll_cache_unittest.cc
index a96df615..d3f3555a 100644
--- a/chrome_elf/ntdll_cache_unittest.cc
+++ b/chrome_elf/ntdll_cache_unittest.cc
@@ -13,7 +13,7 @@
 
 class NTDLLCacheTest : public testing::Test {
  protected:
-  virtual void SetUp() override {
+  void SetUp() override {
     InitCache();
   }
 
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
new file mode 100644
index 0000000..6169cf8
--- /dev/null
+++ b/chromecast/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chromecast/chromecast.gni")
+
+config("config") {
+  defines = []
+
+  if (use_playready) {
+    defines += [ "PLAYREADY_CDM_AVAILABLE" ]
+  }
+}
+
+component("chromecast") {
+  deps = [
+    "//chromecast/base",
+    "//chromecast/base/metrics",
+    "//chromecast/media",
+  ]
+}
diff --git a/chromecast/DEPS b/chromecast/DEPS
index d278340..eae26b0 100644
--- a/chromecast/DEPS
+++ b/chromecast/DEPS
@@ -5,6 +5,7 @@
   # sub-directory within chromecast/.
   "-chromecast",
   "+chromecast/base",
+  "+chromecast/public",
 
   # Other Chromecast-wide dependencies.
   "+content/public/common",
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn
new file mode 100644
index 0000000..b105a71
--- /dev/null
+++ b/chromecast/base/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("base") {
+  sources = [
+    "cast_paths.cc",
+    "cast_paths.h",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/base/cast_sys_info_dummy.cc b/chromecast/base/cast_sys_info_dummy.cc
new file mode 100644
index 0000000..92c39a9
--- /dev/null
+++ b/chromecast/base/cast_sys_info_dummy.cc
@@ -0,0 +1,67 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/base/cast_sys_info_dummy.h"
+
+namespace chromecast {
+
+CastSysInfoDummy::CastSysInfoDummy() {
+}
+
+CastSysInfoDummy::~CastSysInfoDummy() {
+}
+
+CastSysInfo::BuildType CastSysInfoDummy::GetBuildType() {
+  return BUILD_ENG;
+}
+
+std::string CastSysInfoDummy::GetSystemReleaseChannel() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetSerialNumber() {
+  return "dummy.serial.number";
+}
+
+std::string CastSysInfoDummy::GetProductName() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetDeviceModel() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetBoardName() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetBoardRevision() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetManufacturer() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetSystemBuildNumber() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetFactoryCountry() {
+  return "US";
+}
+
+std::string CastSysInfoDummy::GetFactoryLocale(std::string* second_locale) {
+  return "en-US";
+}
+
+std::string CastSysInfoDummy::GetWifiInterface() {
+  return "";
+}
+
+std::string CastSysInfoDummy::GetApInterface() {
+  return "";
+}
+
+}  // namespace chromecast
diff --git a/chromecast/base/cast_sys_info_dummy.h b/chromecast/base/cast_sys_info_dummy.h
new file mode 100644
index 0000000..0b804a2
--- /dev/null
+++ b/chromecast/base/cast_sys_info_dummy.h
@@ -0,0 +1,39 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_BASE_CAST_SYS_INFO_DUMMY_H_
+#define CHROMECAST_BASE_CAST_SYS_INFO_DUMMY_H_
+
+#include "base/macros.h"
+#include "chromecast/public/cast_sys_info.h"
+
+namespace chromecast {
+
+class CastSysInfoDummy : public CastSysInfo {
+ public:
+  CastSysInfoDummy();
+  ~CastSysInfoDummy() override;
+
+  // CastSysInfo implementation:
+  BuildType GetBuildType() override;
+  std::string GetSystemReleaseChannel() override;
+  std::string GetSerialNumber() override;
+  std::string GetProductName() override;
+  std::string GetDeviceModel() override;
+  std::string GetBoardName() override;
+  std::string GetBoardRevision() override;
+  std::string GetManufacturer() override;
+  std::string GetSystemBuildNumber() override;
+  std::string GetFactoryCountry() override;
+  std::string GetFactoryLocale(std::string* second_locale) override;
+  std::string GetWifiInterface() override;
+  std::string GetApInterface() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CastSysInfoDummy);
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_BASE_CAST_SYS_INFO_DUMMY_H_
diff --git a/chromecast/base/cast_sys_info_util.h b/chromecast/base/cast_sys_info_util.h
new file mode 100644
index 0000000..05ca069
--- /dev/null
+++ b/chromecast/base/cast_sys_info_util.h
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_BASE_CAST_SYS_INFO_UTIL_H_
+#define CHROMECAST_BASE_CAST_SYS_INFO_UTIL_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+
+namespace chromecast {
+
+class CastSysInfo;
+
+scoped_ptr<CastSysInfo> CreateSysInfo();
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_BASE_CAST_SYS_INFO_UTIL_H_
diff --git a/chromecast/base/cast_sys_info_util_simple.cc b/chromecast/base/cast_sys_info_util_simple.cc
new file mode 100644
index 0000000..68ab9dff
--- /dev/null
+++ b/chromecast/base/cast_sys_info_util_simple.cc
@@ -0,0 +1,16 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/base/cast_sys_info_util.h"
+
+#include "chromecast/base/cast_sys_info_dummy.h"
+
+namespace chromecast {
+
+// static
+scoped_ptr<CastSysInfo> CreateSysInfo() {
+  return make_scoped_ptr(new CastSysInfoDummy());
+}
+
+}  // namespace chromecast
diff --git a/chromecast/base/metrics/BUILD.gn b/chromecast/base/metrics/BUILD.gn
new file mode 100644
index 0000000..7ed81a5
--- /dev/null
+++ b/chromecast/base/metrics/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("metrics") {
+  sources = [
+    "cast_histograms.h",
+    "cast_metrics_helper.cc",
+    "cast_metrics_helper.h",
+    "grouped_histogram.cc",
+    "grouped_histogram.h",
+  ]
+
+  deps = [
+    "//chromecast/base",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
+
+source_set("test_support") {
+  testonly = true
+
+  sources = [
+    "cast_metrics_test_helper.cc",
+    "cast_metrics_test_helper.h",
+  ]
+
+  deps = [
+    ":metrics",
+    "//chromecast/base",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/base/serializers.cc b/chromecast/base/serializers.cc
new file mode 100644
index 0000000..366a5d2
--- /dev/null
+++ b/chromecast/base/serializers.cc
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/base/serializers.h"
+
+#include "base/json/json_string_value_serializer.h"
+#include "base/logging.h"
+
+namespace chromecast {
+
+scoped_ptr<base::Value> DeserializeFromJson(const std::string& text) {
+  JSONStringValueDeserializer deserializer(text);
+
+  int error_code;
+  std::string error_msg;
+  scoped_ptr<base::Value> value(
+      deserializer.Deserialize(&error_code, &error_msg));
+  DLOG_IF(ERROR, !value) << "JSON error " << error_code << ":" << error_msg;
+
+  // Value will hold the nullptr in case of an error.
+  return value.Pass();
+}
+
+scoped_ptr<std::string> SerializeToJson(const base::Value& value) {
+  scoped_ptr<std::string> json_str(new std::string());
+  JSONStringValueSerializer serializer(json_str.get());
+  if (!serializer.Serialize(value))
+    json_str.reset(nullptr);
+  return json_str.Pass();
+}
+
+}  // namespace chromecast
diff --git a/chromecast/base/serializers.h b/chromecast/base/serializers.h
new file mode 100644
index 0000000..df278fdbc0
--- /dev/null
+++ b/chromecast/base/serializers.h
@@ -0,0 +1,29 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_BASE_SERIALIZERS_H_
+#define CHROMECAST_BASE_SERIALIZERS_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class Value;
+}
+
+namespace chromecast {
+
+// Helper function which deserializes JSON |text| into a base::Value. If |text|
+// is empty, is not valid JSON, or if some other deserialization error occurs,
+// the return value will hold the NULL pointer.
+scoped_ptr<base::Value> DeserializeFromJson(const std::string& text);
+
+// Helper function which serializes |value| into a JSON string. If a
+// serialization error occurs,the return value will hold the NULL pointer.
+scoped_ptr<std::string> SerializeToJson(const base::Value& value);
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_BASE_SERIALIZERS_H_
diff --git a/chromecast/base/serializers_unittest.cc b/chromecast/base/serializers_unittest.cc
new file mode 100644
index 0000000..e82d0dc
--- /dev/null
+++ b/chromecast/base/serializers_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/values.h"
+#include "chromecast/base/serializers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromecast {
+namespace {
+const char kEmptyJsonString[] = "{}";
+const char kProperJsonString[] =
+    "{\n"
+    "   \"compound\": {\n"
+    "      \"a\": 1,\n"
+    "      \"b\": 2\n"
+    "   },\n"
+    "   \"some_String\": \"1337\",\n"
+    "   \"some_int\": 42,\n"
+    "   \"the_list\": [ \"val1\", \"val2\" ]\n"
+    "}\n";
+const char kPoorlyFormedJsonString[] = "{\"key\":";
+const char kTestKey[] = "test_key";
+const char kTestValue[] = "test_value";
+
+}  // namespace
+
+TEST(DeserializeFromJson, EmptyString) {
+  std::string str;
+  scoped_ptr<base::Value> value = DeserializeFromJson(str);
+  EXPECT_EQ(nullptr, value.get());
+}
+
+TEST(DeserializeFromJson, EmptyJsonObject) {
+  std::string str = kEmptyJsonString;
+  scoped_ptr<base::Value> value = DeserializeFromJson(str);
+  EXPECT_NE(nullptr, value.get());
+}
+
+TEST(DeserializeFromJson, ProperJsonObject) {
+  std::string str = kProperJsonString;
+  scoped_ptr<base::Value> value = DeserializeFromJson(str);
+  EXPECT_NE(nullptr, value.get());
+}
+
+TEST(DeserializeFromJson, PoorlyFormedJsonObject) {
+  std::string str = kPoorlyFormedJsonString;
+  scoped_ptr<base::Value> value = DeserializeFromJson(str);
+  EXPECT_EQ(nullptr, value.get());
+}
+
+TEST(SerializeToJson, BadValue) {
+  base::BinaryValue value(scoped_ptr<char[]>(new char[12]), 12);
+  scoped_ptr<std::string> str = SerializeToJson(value);
+  EXPECT_EQ(nullptr, str.get());
+}
+
+TEST(SerializeToJson, EmptyValue) {
+  base::DictionaryValue value;
+  scoped_ptr<std::string> str = SerializeToJson(value);
+  ASSERT_NE(nullptr, str.get());
+  EXPECT_EQ(kEmptyJsonString, *str);
+}
+
+TEST(SerializeToJson, PopulatedValue) {
+  base::DictionaryValue orig_value;
+  orig_value.SetString(kTestKey, kTestValue);
+  scoped_ptr<std::string> str = SerializeToJson(orig_value);
+  ASSERT_NE(nullptr, str.get());
+
+  scoped_ptr<base::Value> new_value = DeserializeFromJson(*str);
+  ASSERT_NE(nullptr, new_value.get());
+  EXPECT_TRUE(new_value->Equals(&orig_value));
+}
+
+}  // namespace chromecast
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS
index e91498e..53066424 100644
--- a/chromecast/browser/DEPS
+++ b/chromecast/browser/DEPS
@@ -4,6 +4,7 @@
   "+cc/base/switches.h",
   "+chromecast",
   "+components/crash",
+  "+components/devtools_discovery",
   "+components/devtools_http_handler",
   "+components/network_hints/browser",
   "+content/public/browser",
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWindowAndroid.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWindowAndroid.java
index 9ad13c2..ed85dcf 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWindowAndroid.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWindowAndroid.java
@@ -127,7 +127,7 @@
     private void initFromNativeWebContents(WebContents webContents, int renderProcessId) {
         Context context = getContext();
         mContentViewCore = new ContentViewCore(context);
-        ContentView view = ContentView.newInstance(context, mContentViewCore);
+        ContentView view = new ContentView(context, mContentViewCore);
         mContentViewCore.initialize(view, view, webContents, mWindow);
         mWebContents = mContentViewCore.getWebContents();
         mNavigationController = mWebContents.getNavigationController();
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 3234a59..beae0d3 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -40,6 +40,7 @@
 #include "content/public/common/web_preferences.h"
 #include "gin/v8_initializer.h"
 #include "net/ssl/ssl_cert_request_info.h"
+#include "net/url_request/url_request_context_getter.h"
 #include "ui/gl/gl_switches.h"
 
 #if defined(OS_ANDROID)
@@ -74,22 +75,43 @@
 
 void CastContentBrowserClient::RenderProcessWillLaunch(
     content::RenderProcessHost* host) {
-  scoped_refptr<content::BrowserMessageFilter> network_hints_message_filter(
-      new network_hints::NetworkHintsMessageFilter(
-          url_request_context_factory_->host_resolver()));
-  host->AddFilter(network_hints_message_filter.get());
 #if !defined(OS_ANDROID)
   scoped_refptr<media::CmaMessageFilterHost> cma_message_filter(
       new media::CmaMessageFilterHost(host->GetID()));
   host->AddFilter(cma_message_filter.get());
 #endif  // !defined(OS_ANDROID)
 
+  // Forcibly trigger I/O-thread URLRequestContext initialization before
+  // getting HostResolver.
+  content::BrowserThread::PostTaskAndReplyWithResult(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&net::URLRequestContextGetter::GetURLRequestContext,
+                 base::Unretained(
+                    url_request_context_factory_->GetSystemGetter())),
+      base::Bind(&CastContentBrowserClient::AddNetworkHintsMessageFilter,
+                 base::Unretained(this), host->GetID()));
+
   auto extra_filters = PlatformGetBrowserMessageFilters();
   for (auto const& filter : extra_filters) {
     host->AddFilter(filter.get());
   }
 }
 
+void CastContentBrowserClient::AddNetworkHintsMessageFilter(
+    int render_process_id, net::URLRequestContext* context) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  content::RenderProcessHost* host =
+      content::RenderProcessHost::FromID(render_process_id);
+  if (!host)
+    return;
+
+  scoped_refptr<content::BrowserMessageFilter> network_hints_message_filter(
+      new network_hints::NetworkHintsMessageFilter(
+          url_request_context_factory_->host_resolver()));
+  host->AddFilter(network_hints_message_filter.get());
+}
+
 net::URLRequestContextGetter* CastContentBrowserClient::CreateRequestContext(
     content::BrowserContext* browser_context,
     content::ProtocolHandlerMap* protocol_handlers,
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index c35bc2ec..193a090f 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -19,6 +19,10 @@
 class BrowserMessageFilter;
 }
 
+namespace net {
+class HostResolver;
+}
+
 namespace chromecast {
 namespace shell {
 
@@ -99,6 +103,9 @@
 #endif  // defined(OS_ANDROID) && defined(VIDEO_HOLE)
 
  private:
+  void AddNetworkHintsMessageFilter(int render_process_id,
+                                    net::URLRequestContext* context);
+
   net::X509Certificate* SelectClientCertificateOnIOThread(
       GURL requesting_url,
       int render_process_id);
diff --git a/chromecast/browser/devtools/cast_dev_tools_delegate.cc b/chromecast/browser/devtools/cast_dev_tools_delegate.cc
index d5bbf17..41447275 100644
--- a/chromecast/browser/devtools/cast_dev_tools_delegate.cc
+++ b/chromecast/browser/devtools/cast_dev_tools_delegate.cc
@@ -7,6 +7,7 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_target.h"
 #include "content/public/browser/favicon_status.h"
@@ -20,67 +21,6 @@
 namespace chromecast {
 namespace shell {
 
-namespace {
-
-const char kTargetTypePage[] = "page";
-const char kTargetTypeServiceWorker[] = "service_worker";
-const char kTargetTypeSharedWorker[] = "worker";
-const char kTargetTypeOther[] = "other";
-
-class Target : public content::DevToolsTarget {
- public:
-  explicit Target(scoped_refptr<content::DevToolsAgentHost> agent_host);
-
-  std::string GetId() const override { return agent_host_->GetId(); }
-  std::string GetParentId() const override { return std::string(); }
-  std::string GetType() const override {
-    switch (agent_host_->GetType()) {
-      case content::DevToolsAgentHost::TYPE_WEB_CONTENTS:
-        return kTargetTypePage;
-      case content::DevToolsAgentHost::TYPE_SERVICE_WORKER:
-        return kTargetTypeServiceWorker;
-      case content::DevToolsAgentHost::TYPE_SHARED_WORKER:
-        return kTargetTypeSharedWorker;
-      default:
-        break;
-    }
-    return kTargetTypeOther;
-  }
-  std::string GetTitle() const override { return agent_host_->GetTitle(); }
-  std::string GetDescription() const override { return std::string(); }
-  GURL GetURL() const override { return agent_host_->GetURL(); }
-  GURL GetFaviconURL() const override { return favicon_url_; }
-  base::TimeTicks GetLastActivityTime() const override {
-    return last_activity_time_;
-  }
-  bool IsAttached() const override { return agent_host_->IsAttached(); }
-  scoped_refptr<content::DevToolsAgentHost> GetAgentHost() const override {
-    return agent_host_;
-  }
-  bool Activate() const override { return agent_host_->Activate(); }
-  bool Close() const override { return agent_host_->Close(); }
-
- private:
-  scoped_refptr<content::DevToolsAgentHost> agent_host_;
-  GURL favicon_url_;
-  base::TimeTicks last_activity_time_;
-
-  DISALLOW_COPY_AND_ASSIGN(Target);
-};
-
-Target::Target(scoped_refptr<content::DevToolsAgentHost> agent_host)
-    : agent_host_(agent_host) {
-  if (content::WebContents* web_contents = agent_host_->GetWebContents()) {
-    content::NavigationController& controller = web_contents->GetController();
-    content::NavigationEntry* entry = controller.GetActiveEntry();
-    if (entry != NULL && entry->GetURL().is_valid())
-      favicon_url_ = entry->GetFavicon().url;
-    last_activity_time_ = web_contents->GetLastActiveTime();
-  }
-}
-
-}  // namespace
-
 // CastDevToolsDelegate -----------------------------------------------------
 
 CastDevToolsDelegate::CastDevToolsDelegate() {
@@ -129,12 +69,10 @@
 
 void CastDevToolsManagerDelegate::EnumerateTargets(TargetCallback callback) {
   TargetList targets;
-  content::DevToolsAgentHost::List agents =
-      content::DevToolsAgentHost::GetOrCreateAll();
-  for (content::DevToolsAgentHost::List::iterator it = agents.begin();
-       it != agents.end(); ++it) {
-    targets.push_back(new Target(*it));
-  }
+  devtools_discovery::DevToolsDiscoveryManager* discovery_manager =
+      devtools_discovery::DevToolsDiscoveryManager::GetInstance();
+  for (const auto& descriptor : discovery_manager->GetDescriptors())
+    targets.push_back(descriptor);
   callback.Run(targets);
 }
 
diff --git a/chromecast/browser/media/cma_message_filter_host.cc b/chromecast/browser/media/cma_message_filter_host.cc
index 899b9ef..d3664c91 100644
--- a/chromecast/browser/media/cma_message_filter_host.cc
+++ b/chromecast/browser/media/cma_message_filter_host.cc
@@ -442,7 +442,7 @@
 }
 
 void CmaMessageFilterHost::SetPlaybackRate(
-    int media_id, float playback_rate) {
+    int media_id, double playback_rate) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   MediaPipelineHost* media_pipeline = LookupById(media_id);
   if (!media_pipeline)
diff --git a/chromecast/browser/media/cma_message_filter_host.h b/chromecast/browser/media/cma_message_filter_host.h
index 763727c..e000574 100644
--- a/chromecast/browser/media/cma_message_filter_host.h
+++ b/chromecast/browser/media/cma_message_filter_host.h
@@ -77,7 +77,7 @@
   void StartPlayingFrom(int media_id, base::TimeDelta time);
   void Flush(int media_id);
   void Stop(int media_id);
-  void SetPlaybackRate(int media_id, float playback_rate);
+  void SetPlaybackRate(int media_id, double playback_rate);
   void SetVolume(int media_id, TrackId track_id, float volume);
   void NotifyPipeWrite(int media_id, TrackId track_id);
   void NotifyExternalSurface(int surface_id,
diff --git a/chromecast/browser/media/media_pipeline_host.cc b/chromecast/browser/media/media_pipeline_host.cc
index ff97612..ff3eb69 100644
--- a/chromecast/browser/media/media_pipeline_host.cc
+++ b/chromecast/browser/media/media_pipeline_host.cc
@@ -142,7 +142,7 @@
   media_pipeline_->Stop();
 }
 
-void MediaPipelineHost::SetPlaybackRate(float playback_rate) {
+void MediaPipelineHost::SetPlaybackRate(double playback_rate) {
   DCHECK(thread_checker_.CalledOnValidThread());
   media_pipeline_->SetPlaybackRate(playback_rate);
 }
diff --git a/chromecast/browser/media/media_pipeline_host.h b/chromecast/browser/media/media_pipeline_host.h
index 1dea01e..dc15db9 100644
--- a/chromecast/browser/media/media_pipeline_host.h
+++ b/chromecast/browser/media/media_pipeline_host.h
@@ -59,7 +59,7 @@
   void Flush(const ::media::PipelineStatusCB& status_cb);
   void Stop();
 
-  void SetPlaybackRate(float playback_rate);
+  void SetPlaybackRate(double playback_rate);
   void SetVolume(TrackId track_id, float playback_rate);
   void SetCdm(BrowserCdmCast* cdm);
 
diff --git a/chromecast/build/args.gn b/chromecast/build/args.gn
new file mode 100644
index 0000000..1624b0a
--- /dev/null
+++ b/chromecast/build/args.gn
@@ -0,0 +1,14 @@
+# Build arguments for Chromecast.
+# Copy the contents of this file to gn args.
+
+root_extra_deps = [ "//chromecast" ]
+
+# Flags set from build/common.gypi
+enable_mpeg2ts_stream_parser = true
+ffmpeg_branding = "ChromeOS"
+proprietary_codecs = true
+enable_browser_cdms = true
+# TODO(halliwell): look into supporting Cast Ozone with GN.
+# ozone_platform_cast = 1
+# TODO(gyp): Add support for blink_logging_always_on and enable it.
+# blink_logging_always_on = 1
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni
new file mode 100644
index 0000000..b6f7307b
--- /dev/null
+++ b/chromecast/chromecast.gni
@@ -0,0 +1,10 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+declare_args() {
+  # is_chromecast_chrome_branded is set to true for an official build
+  is_chromecast_chrome_branded = false
+
+  use_playready = false
+}
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp
index 15b31b40..5c2e49c 100644
--- a/chromecast/chromecast.gyp
+++ b/chromecast/chromecast.gyp
@@ -38,6 +38,7 @@
       'sources': [
         'public/cast_egl_platform.h',
         'public/cast_egl_platform_shlib.h',
+        'public/cast_sys_info.h',
         'public/chromecast_export.h',
         'public/graphics_properties_shlib.h'
       ],
@@ -59,7 +60,9 @@
         'base/metrics/cast_metrics_helper.cc',
         'base/metrics/cast_metrics_helper.h',
         'base/metrics/grouped_histogram.cc',
-        'base/metrics/grouped_histogram.h'
+        'base/metrics/grouped_histogram.h',
+        'base/serializers.cc',
+        'base/serializers.h'
       ],
     },  # end of target 'cast_base'
     {
@@ -177,6 +180,7 @@
         'cast_net',
         'cast_shell_pak',
         'cast_shell_resources',
+        'cast_sys_info',
         'cast_version_header',
         'chromecast_locales.gyp:chromecast_locales_pak',
         'chromecast_locales.gyp:chromecast_settings',
@@ -186,6 +190,7 @@
         '../components/components.gyp:cdm_renderer',
         '../components/components.gyp:component_metrics_proto',
         '../components/components.gyp:crash_component',
+        '../components/components.gyp:devtools_discovery',
         '../components/components.gyp:devtools_http_handler',
         '../components/components.gyp:network_hints_browser',
         '../components/components.gyp:network_hints_renderer',
@@ -313,6 +318,26 @@
       ],
     },
     {
+      'target_name': 'cast_sys_info',
+      'type': '<(component)',
+      'dependencies': [
+        'cast_public_api',
+        '../base/base.gyp:base',
+      ],
+      'sources': [
+        'base/cast_sys_info_util.h',
+        'base/cast_sys_info_dummy.cc',
+        'base/cast_sys_info_dummy.h',
+      ],
+      'conditions': [
+        ['chromecast_branding!="Chrome"', {
+          'sources': [
+            'base/cast_sys_info_util_simple.cc',
+          ],
+        }],
+      ],
+    },  # end of target 'cast_sys_info'
+    {
       'target_name': 'cast_version_header',
       'type': 'none',
       'direct_dependent_settings': {
@@ -573,9 +598,14 @@
           'sources': [
             'app/cast_main.cc',
           ],
-          # TODO(dougsteed): remove when Chromecast moves to boringssl.
-          # Allow the cast shell to find the NSS module in the same directory.
           'ldflags': [
+            # Allow  OEMs to override default libraries that are shipped with
+            # cast receiver package by installed OEM-specific libraries in
+            # /oem_cast_shlib.
+            '-Wl,-rpath=/oem_cast_shlib',
+            # TODO(dougsteed): remove when Chromecast moves to boringssl.
+            # Allow the cast shell to find the NSS module in the same
+            # directory.
             '-Wl,-rpath=\$$ORIGIN'
           ],
         },
diff --git a/chromecast/chromecast_tests.gypi b/chromecast/chromecast_tests.gypi
index 09bcb52..26c5762 100644
--- a/chromecast/chromecast_tests.gypi
+++ b/chromecast/chromecast_tests.gypi
@@ -3,8 +3,23 @@
 # found in the LICENSE file.
 
 {
+  'variables': {
+    'chromium_code': 1
+  },
   'targets': [
     {
+      'target_name': 'cast_base_unittests',
+      'type': '<(gtest_target_type)',
+      'dependencies': [
+        'chromecast.gyp:cast_base',
+        '../testing/gtest.gyp:gtest',
+        '../testing/gtest.gyp:gtest_main',
+      ],
+      'sources': [
+        'base/serializers_unittest.cc',
+      ],
+    },
+    {
       'target_name': 'cast_tests',
       'type': 'none',
       'dependencies': [
@@ -23,8 +38,8 @@
       'target_name': 'cast_test_generator',
       'type': 'none',
       'dependencies': [
+        'cast_base_unittests',
         '../base/base.gyp:base_unittests',
-        '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
         '../content/content_shell_and_tests.gyp:content_unittests',
         '../crypto/crypto.gyp:crypto_unittests',
         '../ipc/ipc.gyp:ipc_tests',
@@ -34,6 +49,7 @@
         '../sandbox/sandbox.gyp:sandbox_linux_unittests',
         '../sql/sql.gyp:sql_unittests',
         '../sync/sync.gyp:sync_unit_tests',
+        '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
         '../ui/base/ui_base_tests.gyp:ui_base_unittests',
         '../url/url.gyp:url_unittests',
       ],
diff --git a/chromecast/common/cast_content_client.cc b/chromecast/common/cast_content_client.cc
index e93b7d2a..4772fdd5 100644
--- a/chromecast/common/cast_content_client.cc
+++ b/chromecast/common/cast_content_client.cc
@@ -4,6 +4,8 @@
 
 #include "chromecast/common/cast_content_client.h"
 
+#include "base/strings/stringprintf.h"
+#include "base/sys_info.h"
 #include "chromecast/common/version.h"
 #include "content/public/common/user_agent.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -12,9 +14,56 @@
 namespace chromecast {
 namespace shell {
 
+namespace {
+
+#if defined(OS_ANDROID)
+std::string BuildAndroidOsInfo() {
+  int32 os_major_version = 0;
+  int32 os_minor_version = 0;
+  int32 os_bugfix_version = 0;
+  base::SysInfo::OperatingSystemVersionNumbers(&os_major_version,
+                                               &os_minor_version,
+                                               &os_bugfix_version);
+
+  std::string android_version_str;
+  base::StringAppendF(
+      &android_version_str, "%d.%d", os_major_version, os_minor_version);
+  if (os_bugfix_version != 0)
+    base::StringAppendF(&android_version_str, ".%d", os_bugfix_version);
+
+  std::string android_info_str;
+  // Append the build ID.
+  std::string android_build_id = base::SysInfo::GetAndroidBuildID();
+  if (android_build_id.size() > 0)
+    android_info_str += "; Build/" + android_build_id;
+
+  std::string os_info;
+  base::StringAppendF(
+      &os_info,
+      "Android %s%s",
+      android_version_str.c_str(),
+      android_info_str.c_str());
+  return os_info;
+}
+#endif
+
+}  // namespace
+
 std::string GetUserAgent() {
   std::string product = "Chrome/" PRODUCT_VERSION;
-  return content::BuildUserAgentFromProduct(product) +
+  std::string os_info;
+  base::StringAppendF(
+      &os_info,
+      "%s%s",
+#if defined(OS_ANDROID)
+      "Linux; ",
+      BuildAndroidOsInfo().c_str()
+#else
+      "X11; ",
+      content::BuildOSCpuInfo().c_str()
+#endif
+      );
+  return content::BuildUserAgentFromOSAndProduct(os_info, product) +
       " CrKey/" CAST_BUILD_REVISION;
 }
 
diff --git a/chromecast/common/media/cma_messages.h b/chromecast/common/media/cma_messages.h
index 414913b2..3fbed3db 100644
--- a/chromecast/common/media/cma_messages.h
+++ b/chromecast/common/media/cma_messages.h
@@ -41,7 +41,7 @@
                      int /* Media pipeline ID */)
 IPC_MESSAGE_CONTROL2(CmaHostMsg_SetPlaybackRate,
                      int /* Media pipeline ID */,
-                     float /* Playback rate */)
+                     double /* Playback rate */)
 
 IPC_MESSAGE_CONTROL3(CmaHostMsg_CreateAvPipe,
                      int /* Media pipeline ID */,
diff --git a/chromecast/crash/android/crash_handler.cc b/chromecast/crash/android/crash_handler.cc
index 3b195464..1c42dfa 100644
--- a/chromecast/crash/android/crash_handler.cc
+++ b/chromecast/crash/android/crash_handler.cc
@@ -26,15 +26,13 @@
 
 chromecast::CrashHandler* g_crash_handler = NULL;
 
-// ExceptionHandler requires a HandlerCallback as a function pointer. This
-// function exists to proxy into the global CrashHandler instance.
-bool HandleCrash(const void* /* crash_context */,
-                 size_t /* crash_context_size */,
-                 void* /* context */) {
+bool HandleCrash(void* /* crash_context */) {
   DCHECK(g_crash_handler);
   g_crash_handler->UploadCrashDumps();
 
-  // Let the exception continue to propagate up to the system.
+  // TODO(gunsch): clean up the ATV crash handling code.
+  // Don't write another minidump. Chrome's default ExceptionHandler has already
+  // written a minidump by this point in the crash handling sequence.
   return false;
 }
 
@@ -100,8 +98,7 @@
     // Dummy MinidumpDescriptor just to start up another ExceptionHandler.
     google_breakpad::MinidumpDescriptor dummy(crash_dump_path_.value());
     crash_uploader_.reset(new google_breakpad::ExceptionHandler(
-        dummy, NULL, NULL, NULL, true, -1));
-    crash_uploader_->set_crash_handler(&::HandleCrash);
+        dummy, &HandleCrash, NULL, NULL, true, -1));
 
     breakpad::InitCrashReporter(process_type);
 
diff --git a/chromecast/media/BUILD.gn b/chromecast/media/BUILD.gn
new file mode 100644
index 0000000..6a8c6a6
--- /dev/null
+++ b/chromecast/media/BUILD.gn
@@ -0,0 +1,53 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//testing/test.gni")
+
+group("media") {
+  deps = [
+    "//chromecast/media/base",
+    "//chromecast/media/cdm",
+    "//chromecast/media/cma",
+  ]
+}
+
+test("unittests") {
+  sources = [
+    "//media/base",
+    "cma/backend/audio_video_pipeline_device_unittest.cc",
+    "cma/base/balanced_media_task_runner_unittest.cc",
+    "cma/base/buffering_controller_unittest.cc",
+    "cma/base/buffering_frame_provider_unittest.cc",
+    "cma/filters/demuxer_stream_adapter_unittest.cc",
+    "cma/ipc/media_message_fifo_unittest.cc",
+    "cma/ipc/media_message_unittest.cc",
+    "cma/ipc_streamer/av_streamer_unittest.cc",
+    "cma/pipeline/audio_video_pipeline_impl_unittest.cc",
+    "cma/test/frame_generator_for_test.cc",
+    "cma/test/frame_generator_for_test.h",
+    "cma/test/frame_segmenter_for_test.cc",
+    "cma/test/frame_segmenter_for_test.h",
+    "cma/test/media_component_device_feeder_for_test.cc",
+    "cma/test/media_component_device_feeder_for_test.h",
+    "cma/test/mock_frame_consumer.cc",
+    "cma/test/mock_frame_consumer.h",
+    "cma/test/mock_frame_provider.cc",
+    "cma/test/mock_frame_provider.h",
+    "cma/test/run_all_unittests.cc",
+  ]
+
+  deps = [
+    ":media",
+    "//base",
+    "//base:i18n",
+    "//base/test:test_support",
+    "//chromecast/base/metrics:test_support",
+    "//media",
+    "//media/base:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/base/BUILD.gn b/chromecast/media/base/BUILD.gn
new file mode 100644
index 0000000..64992f33
--- /dev/null
+++ b/chromecast/media/base/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/crypto.gni")
+import("//chromecast/chromecast.gni")
+
+source_set("base") {
+  sources = [
+    "decrypt_context.cc",
+    "decrypt_context.h",
+    "decrypt_context_clearkey.cc",
+    "decrypt_context_clearkey.h",
+    "key_systems_common.cc",
+    "key_systems_common.h",
+    "media_caps.cc",
+    "media_caps.h",
+    "switching_media_renderer.cc",
+    "switching_media_renderer.h",
+  ]
+
+  deps = [
+    "//base",
+    "//crypto",
+    "//crypto:platform",
+    "//third_party/widevine/cdm:version_h",
+  ]
+
+  configs += [ "//chromecast:config" ]
+
+  if (is_chromecast_chrome_branded) {
+    deps += [
+      # TODO(gyp): add dependency on internal/chromecast_internal:media_base_internal
+    ]
+  } else {
+    sources += [ "key_systems_common_simple.cc" ]
+  }
+}
diff --git a/chromecast/media/base/switching_media_renderer.cc b/chromecast/media/base/switching_media_renderer.cc
index 79b7d1ef..b0a12c3 100644
--- a/chromecast/media/base/switching_media_renderer.cc
+++ b/chromecast/media/base/switching_media_renderer.cc
@@ -78,7 +78,7 @@
   GetRenderer()->StartPlayingFrom(time);
 }
 
-void SwitchingMediaRenderer::SetPlaybackRate(float playback_rate)  {
+void SwitchingMediaRenderer::SetPlaybackRate(double playback_rate)  {
   GetRenderer()->SetPlaybackRate(playback_rate);
 }
 
diff --git a/chromecast/media/base/switching_media_renderer.h b/chromecast/media/base/switching_media_renderer.h
index 2739f400..c32b1d4 100644
--- a/chromecast/media/base/switching_media_renderer.h
+++ b/chromecast/media/base/switching_media_renderer.h
@@ -43,7 +43,7 @@
               const ::media::CdmAttachedCB& cdm_attached_cb) override;
   void Flush(const base::Closure& flush_cb) override;
   void StartPlayingFrom(base::TimeDelta time) override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
   void SetVolume(float volume) override;
   base::TimeDelta GetMediaTime() override;
   bool HasAudio() override;
diff --git a/chromecast/media/cdm/BUILD.gn b/chromecast/media/cdm/BUILD.gn
new file mode 100644
index 0000000..1a929d0
--- /dev/null
+++ b/chromecast/media/cdm/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("cdm") {
+  sources = [
+    "browser_cdm_cast.cc",
+    "browser_cdm_cast.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromecast/media/base",
+    "//media",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/BUILD.gn b/chromecast/media/cma/BUILD.gn
new file mode 100644
index 0000000..c9da6296f
--- /dev/null
+++ b/chromecast/media/cma/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+group("cma") {
+  deps = [
+    "//chromecast/media/cma/backend",
+    "//chromecast/media/cma/base",
+    "//chromecast/media/cma/filters",
+    "//chromecast/media/cma/ipc",
+    "//chromecast/media/cma/ipc_streamer",
+    "//chromecast/media/cma/pipeline",
+  ]
+}
diff --git a/chromecast/media/cma/backend/BUILD.gn b/chromecast/media/cma/backend/BUILD.gn
new file mode 100644
index 0000000..6526a1f7
--- /dev/null
+++ b/chromecast/media/cma/backend/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("backend") {
+  sources = [
+    "audio_pipeline_device.cc",
+    "audio_pipeline_device.h",
+    "media_clock_device.cc",
+    "media_clock_device.h",
+    "media_component_device.cc",
+    "media_component_device.h",
+    "media_pipeline_device.cc",
+    "media_pipeline_device.h",
+    "media_pipeline_device_fake.cc",
+    "media_pipeline_device_fake.h",
+    "media_pipeline_device_fake_factory.cc",
+    "media_pipeline_device_params.cc",
+    "media_pipeline_device_params.h",
+    "video_pipeline_device.cc",
+    "video_pipeline_device.h",
+    "video_plane.cc",
+    "video_plane.h",
+    "video_plane_fake.cc",
+    "video_plane_fake.h",
+    "video_plane_fake_factory.cc",
+  ]
+
+  deps = [
+    "//base",
+    "//chromecast/media/base",
+    "//chromecast/media/cma/base",
+    "//media",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/base/BUILD.gn b/chromecast/media/cma/base/BUILD.gn
new file mode 100644
index 0000000..b919439
--- /dev/null
+++ b/chromecast/media/cma/base/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("base") {
+  sources = [
+    "balanced_media_task_runner_factory.cc",
+    "balanced_media_task_runner_factory.h",
+    "buffering_controller.cc",
+    "buffering_controller.h",
+    "buffering_defs.cc",
+    "buffering_defs.h",
+    "buffering_frame_provider.cc",
+    "buffering_frame_provider.h",
+    "buffering_state.cc",
+    "buffering_state.h",
+    "cma_logging.h",
+    "coded_frame_provider.cc",
+    "coded_frame_provider.h",
+    "decoder_buffer_adapter.cc",
+    "decoder_buffer_adapter.h",
+    "decoder_buffer_base.cc",
+    "decoder_buffer_base.h",
+    "media_task_runner.cc",
+    "media_task_runner.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromecast/base",
+    "//media",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/filters/BUILD.gn b/chromecast/media/cma/filters/BUILD.gn
new file mode 100644
index 0000000..6050755
--- /dev/null
+++ b/chromecast/media/cma/filters/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("filters") {
+  sources = [
+    "cma_renderer.cc",
+    "cma_renderer.h",
+    "demuxer_stream_adapter.cc",
+    "demuxer_stream_adapter.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromecast/media/cma/base",
+    "//media",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/filters/cma_renderer.cc b/chromecast/media/cma/filters/cma_renderer.cc
index bc29b4f..0de06343 100644
--- a/chromecast/media/cma/filters/cma_renderer.cc
+++ b/chromecast/media/cma/filters/cma_renderer.cc
@@ -55,7 +55,7 @@
       initial_video_hole_created_(false),
       time_interpolator_(
           new ::media::TimeDeltaInterpolator(&default_tick_clock_)),
-      playback_rate_(1.0f),
+      playback_rate_(1.0),
       weak_factory_(this) {
   weak_this_ = weak_factory_.GetWeakPtr();
   thread_checker_.DetachFromThread();
@@ -185,7 +185,7 @@
   CompleteStateTransition(kPlaying);
 }
 
-void CmaRenderer::SetPlaybackRate(float playback_rate) {
+void CmaRenderer::SetPlaybackRate(double playback_rate) {
   CMALOG(kLogControl) << __FUNCTION__ << ": " << playback_rate;
   DCHECK(thread_checker_.CalledOnValidThread());
   media_pipeline_->SetPlaybackRate(playback_rate);
diff --git a/chromecast/media/cma/filters/cma_renderer.h b/chromecast/media/cma/filters/cma_renderer.h
index 25fec41..d33699e 100644
--- a/chromecast/media/cma/filters/cma_renderer.h
+++ b/chromecast/media/cma/filters/cma_renderer.h
@@ -50,7 +50,7 @@
       const base::Closure& waiting_for_decryption_key_cb) override;
   void Flush(const base::Closure& flush_cb) override;
   void StartPlayingFrom(base::TimeDelta time) override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
   void SetVolume(float volume) override;
   base::TimeDelta GetMediaTime() override;
   bool HasAudio() override;
@@ -137,7 +137,7 @@
   // as playback progresses.
   scoped_ptr< ::media::TimeDeltaInterpolator> time_interpolator_;
 
-  float playback_rate_;
+  double playback_rate_;
 
   base::WeakPtr<CmaRenderer> weak_this_;
   base::WeakPtrFactory<CmaRenderer> weak_factory_;
diff --git a/chromecast/media/cma/ipc/BUILD.gn b/chromecast/media/cma/ipc/BUILD.gn
new file mode 100644
index 0000000..037b3bd
--- /dev/null
+++ b/chromecast/media/cma/ipc/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("ipc") {
+  sources = [
+    "media_memory_chunk.cc",
+    "media_memory_chunk.h",
+    "media_message.cc",
+    "media_message.h",
+    "media_message_fifo.cc",
+    "media_message_fifo.h",
+    "media_message_type.h",
+  ]
+
+  deps = [
+    "//base",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/ipc_streamer/BUILD.gn b/chromecast/media/cma/ipc_streamer/BUILD.gn
new file mode 100644
index 0000000..aa87709
--- /dev/null
+++ b/chromecast/media/cma/ipc_streamer/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("ipc_streamer") {
+  sources = [
+    "audio_decoder_config_marshaller.cc",
+    "audio_decoder_config_marshaller.h",
+    "av_streamer_proxy.cc",
+    "av_streamer_proxy.h",
+    "coded_frame_provider_host.cc",
+    "coded_frame_provider_host.h",
+    "decoder_buffer_base_marshaller.cc",
+    "decoder_buffer_base_marshaller.h",
+    "decrypt_config_marshaller.cc",
+    "decrypt_config_marshaller.h",
+    "video_decoder_config_marshaller.cc",
+    "video_decoder_config_marshaller.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromecast/media/cma/base",
+    "//media",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/pipeline/BUILD.gn b/chromecast/media/cma/pipeline/BUILD.gn
new file mode 100644
index 0000000..f82a8d9a
--- /dev/null
+++ b/chromecast/media/cma/pipeline/BUILD.gn
@@ -0,0 +1,44 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("pipeline") {
+  sources = [
+    "audio_pipeline.cc",
+    "audio_pipeline.h",
+    "audio_pipeline_impl.cc",
+    "audio_pipeline_impl.h",
+    "av_pipeline_client.cc",
+    "av_pipeline_client.h",
+    "av_pipeline_impl.cc",
+    "av_pipeline_impl.h",
+    "decrypt_util.cc",
+    "decrypt_util.h",
+    "load_type.h",
+    "media_pipeline.h",
+    "media_pipeline_client.cc",
+    "media_pipeline_client.h",
+    "media_pipeline_impl.cc",
+    "media_pipeline_impl.h",
+    "video_pipeline.cc",
+    "video_pipeline.h",
+    "video_pipeline_client.cc",
+    "video_pipeline_client.h",
+    "video_pipeline_impl.cc",
+    "video_pipeline_impl.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromecast/media/cma/backend",
+    "//chromecast/media/cma/base",
+    "//chromecast/media/base",
+    "//chromecast/media/cdm",
+    "//crypto",
+    "//crypto:platform",
+    "//media",
+    "//third_party/boringssl",
+  ]
+
+  configs += [ "//chromecast:config" ]
+}
diff --git a/chromecast/media/cma/pipeline/media_pipeline.h b/chromecast/media/cma/pipeline/media_pipeline.h
index 2b82c4f1..6b127cb2 100644
--- a/chromecast/media/cma/pipeline/media_pipeline.h
+++ b/chromecast/media/cma/pipeline/media_pipeline.h
@@ -57,7 +57,7 @@
   virtual void Stop() = 0;
 
   // Set the playback rate.
-  virtual void SetPlaybackRate(float playback_rate) = 0;
+  virtual void SetPlaybackRate(double playback_rate) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MediaPipeline);
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
index c713f9a..ced7df14 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
@@ -263,7 +263,7 @@
     video_pipeline_->Stop();
 }
 
-void MediaPipelineImpl::SetPlaybackRate(float rate) {
+void MediaPipelineImpl::SetPlaybackRate(double rate) {
   CMALOG(kLogControl) << __FUNCTION__ << " rate=" << rate;
   DCHECK(thread_checker_.CalledOnValidThread());
   target_playback_rate_ = rate;
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.h b/chromecast/media/cma/pipeline/media_pipeline_impl.h
index 166b8f9..eb14a555b 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.h
@@ -51,7 +51,7 @@
   void StartPlayingFrom(base::TimeDelta time) override;
   void Flush(const ::media::PipelineStatusCB& status_cb) override;
   void Stop() override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
 
   AudioPipelineImpl* GetAudioPipelineImpl() const;
   VideoPipelineImpl* GetVideoPipelineImpl() const;
diff --git a/chromecast/public/DEPS b/chromecast/public/DEPS
new file mode 100644
index 0000000..30d9ea2d
--- /dev/null
+++ b/chromecast/public/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+   # chromecast/public should not depend on anything Chromium specific
+   "-chromecast",
+   "-base",
+   "-content",
+   "-net",
+   "-ui",
+]
diff --git a/chromecast/public/cast_sys_info.h b/chromecast/public/cast_sys_info.h
new file mode 100644
index 0000000..95d1da6
--- /dev/null
+++ b/chromecast/public/cast_sys_info.h
@@ -0,0 +1,62 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_PUBLIC_CAST_SYS_INFO_H_
+#define CHROMECAST_PUBLIC_CAST_SYS_INFO_H_
+
+#include <string>
+#include <vector>
+
+namespace chromecast {
+
+// Pure abstract interface for system information which is accessed by other
+// processes as well as cast_shell browser process. All information should be
+// immutable.
+// It should be possible to instantiate multiple instances of CastSysInfo and
+// should be able to be instantiated at any point in the startup process. Other
+// processes must be able to create an instance of CastSysInfo.
+class CastSysInfo {
+ public:
+  enum BuildType {
+    BUILD_ENG,
+    BUILD_BETA,
+    BUILD_PRODUCTION,
+  };
+
+  virtual ~CastSysInfo() {}
+
+  // Returns the system build type.
+  virtual BuildType GetBuildType() = 0;
+  // Returns release channel of system.
+  virtual std::string GetSystemReleaseChannel() = 0;
+  // Returns serial number of the device.
+  virtual std::string GetSerialNumber() = 0;
+  // Returns product code name of the device.
+  virtual std::string GetProductName() = 0;
+  // Returns model name of device (eg: Chromecast, Nexus Player, ...).
+  virtual std::string GetDeviceModel() = 0;
+  // Returns the board's name.
+  virtual std::string GetBoardName() = 0;
+  // Returns the revision of board (eg: 514, ...).
+  virtual std::string GetBoardRevision() = 0;
+  // Returns device manufacturer (eg: Google, ...).
+  virtual std::string GetManufacturer() = 0;
+  // Returns the system's build number (eg: 100, 20000 ...).
+  // This describes system version which may be different with
+  // CAST_BUILD_NUMBER.
+  virtual std::string GetSystemBuildNumber() = 0;
+
+  // Returns default country and locale baked from the factory.
+  virtual std::string GetFactoryCountry() = 0;
+  virtual std::string GetFactoryLocale(std::string* second_locale) = 0;
+
+  // Returns the name of the wifi interface used to connect to the internet.
+  virtual std::string GetWifiInterface() = 0;
+  // Returns the name of the software AP interface.
+  virtual std::string GetApInterface() = 0;
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_PUBLIC_CAST_SYS_INFO_H_
diff --git a/chromecast/renderer/key_systems_cast.cc b/chromecast/renderer/key_systems_cast.cc
index 5d3ad1c..c9cae76 100644
--- a/chromecast/renderer/key_systems_cast.cc
+++ b/chromecast/renderer/key_systems_cast.cc
@@ -27,11 +27,13 @@
       ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1;
   info.max_audio_robustness = ::media::EmeRobustness::EMPTY;
   info.max_video_robustness = ::media::EmeRobustness::EMPTY;
-  info.persistent_license_support = ::media::EME_SESSION_TYPE_NOT_SUPPORTED;
+  info.persistent_license_support =
+      ::media::EmeSessionTypeSupport::NOT_SUPPORTED;
   info.persistent_release_message_support =
-      ::media::EME_SESSION_TYPE_NOT_SUPPORTED;
-  info.persistent_state_support = ::media::EME_FEATURE_ALWAYS_ENABLED;
-  info.distinctive_identifier_support = ::media::EME_FEATURE_ALWAYS_ENABLED;
+      ::media::EmeSessionTypeSupport::NOT_SUPPORTED;
+  info.persistent_state_support = ::media::EmeFeatureSupport::ALWAYS_ENABLED;
+  info.distinctive_identifier_support =
+      ::media::EmeFeatureSupport::ALWAYS_ENABLED;
   key_systems_info->push_back(info);
 }
 
@@ -39,15 +41,16 @@
     std::vector<::media::KeySystemInfo>* key_systems_info) {
 #if defined(WIDEVINE_CDM_AVAILABLE)
   AddWidevineWithCodecs(
-      cdm::WIDEVINE,
-      ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1,
-      ::media::EmeRobustness::HW_SECURE_ALL,    // Max audio robustness.
-      ::media::EmeRobustness::HW_SECURE_ALL,    // Max video robustness.
-      ::media::EME_SESSION_TYPE_NOT_SUPPORTED,  // persistent-license.
-      ::media::EME_SESSION_TYPE_NOT_SUPPORTED,  // persistent-release-message.
+      cdm::WIDEVINE, ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1,
+      ::media::EmeRobustness::HW_SECURE_ALL,          // Max audio robustness.
+      ::media::EmeRobustness::HW_SECURE_ALL,          // Max video robustness.
+      ::media::EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
+      ::media::EmeSessionTypeSupport::
+          NOT_SUPPORTED,  // persistent-release-message.
       // Note: On Chromecast, all CDMs may have persistent state.
-      ::media::EME_FEATURE_ALWAYS_ENABLED,      // Persistent state.
-      ::media::EME_FEATURE_ALWAYS_ENABLED,      // Distinctive identifier.
+      ::media::EmeFeatureSupport::ALWAYS_ENABLED,  // Persistent state.
+      ::media::EmeFeatureSupport::ALWAYS_ENABLED,  // Distinctive
+                                                   // identifier.
       key_systems_info);
 #endif
 
diff --git a/chromecast/renderer/media/media_pipeline_proxy.cc b/chromecast/renderer/media/media_pipeline_proxy.cc
index 7a454b166..830ac0f 100644
--- a/chromecast/renderer/media/media_pipeline_proxy.cc
+++ b/chromecast/renderer/media/media_pipeline_proxy.cc
@@ -34,7 +34,7 @@
   void StartPlayingFrom(const base::TimeDelta& time);
   void Flush(const ::media::PipelineStatusCB& status_cb);
   void Stop();
-  void SetPlaybackRate(float playback_rate);
+  void SetPlaybackRate(double playback_rate);
 
  private:
   void Shutdown();
@@ -135,7 +135,7 @@
     client_.error_cb.Run(::media::PIPELINE_ERROR_ABORT);
 }
 
-void MediaPipelineProxyInternal::SetPlaybackRate(float playback_rate) {
+void MediaPipelineProxyInternal::SetPlaybackRate(double playback_rate) {
   DCHECK(thread_checker_.CalledOnValidThread());
   media_channel_proxy_->Send(scoped_ptr<IPC::Message>(
       new CmaHostMsg_SetPlaybackRate(
@@ -274,7 +274,7 @@
   FORWARD_ON_IO_THREAD(Stop);
 }
 
-void MediaPipelineProxy::SetPlaybackRate(float playback_rate) {
+void MediaPipelineProxy::SetPlaybackRate(double playback_rate) {
   DCHECK(thread_checker_.CalledOnValidThread());
   FORWARD_ON_IO_THREAD(SetPlaybackRate, playback_rate);
 }
diff --git a/chromecast/renderer/media/media_pipeline_proxy.h b/chromecast/renderer/media/media_pipeline_proxy.h
index 0d22795..decec65 100644
--- a/chromecast/renderer/media/media_pipeline_proxy.h
+++ b/chromecast/renderer/media/media_pipeline_proxy.h
@@ -50,7 +50,7 @@
   void StartPlayingFrom(base::TimeDelta time) override;
   void Flush(const ::media::PipelineStatusCB& status_cb) override;
   void Stop() override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
 
  private:
   void OnProxyFlushDone(const ::media::PipelineStatusCB& status_cb,
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 5f67f60..de5659fe 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-6993.0.0
\ No newline at end of file
+6996.0.0
\ No newline at end of file
diff --git a/chromeos/dbus/bluetooth_le_advertising_manager_client.cc b/chromeos/dbus/bluetooth_le_advertising_manager_client.cc
index 00f4f67..35bb36e 100644
--- a/chromeos/dbus/bluetooth_le_advertising_manager_client.cc
+++ b/chromeos/dbus/bluetooth_le_advertising_manager_client.cc
@@ -27,8 +27,12 @@
       : object_manager_(NULL), weak_ptr_factory_(this) {}
 
   ~BluetoothAdvertisementManagerClientImpl() override {
-    object_manager_->UnregisterInterface(
-        bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface);
+    // TODO(rkc): object_manager_ should not be NULL, just a hot fix till
+    // http://crbug.com/479430 is properly fixed.
+    if (object_manager_) {
+      object_manager_->UnregisterInterface(
+          bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface);
+    }
   }
 
   // BluetoothAdapterClient override.
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index ef79717f..e6f97cb5 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -775,6 +775,9 @@
     devices->SetDeviceProperty("/device/cellular1",
                                shill::kSupportedCarriersProperty,
                                carrier_list);
+    devices->SetDeviceProperty("/device/cellular1",
+                               shill::kSupportNetworkScanProperty,
+                               base::FundamentalValue(true));
     if (roaming_state_ == kRoamingRequired) {
       devices->SetDeviceProperty("/device/cellular1",
                                  shill::kProviderRequiresRoamingProperty,
@@ -1049,8 +1052,7 @@
     base::DictionaryValue* simlock_dict = new base::DictionaryValue;
     simlock_dict->Set(shill::kSIMLockEnabledProperty,
                       new base::FundamentalValue(locked));
-    // TODO(stevenjb): Investigate why non-empty value breaks UI.
-    std::string lock_type = "";  // shill::kSIMLockPin
+    std::string lock_type = shill::kSIMLockPin;
     simlock_dict->SetString(shill::kSIMLockTypeProperty, lock_type);
     simlock_dict->SetInteger(shill::kSIMLockRetriesLeftProperty, 5);
 
diff --git a/chromeos/dbus/nfc_client_unittest.cc b/chromeos/dbus/nfc_client_unittest.cc
index 7870e48..736853b 100644
--- a/chromeos/dbus/nfc_client_unittest.cc
+++ b/chromeos/dbus/nfc_client_unittest.cc
@@ -88,9 +88,9 @@
 class NfcClientTest : public testing::Test {
  public:
   NfcClientTest() : response_(NULL) {}
-  virtual ~NfcClientTest() {}
+  ~NfcClientTest() override {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     // Create the mock bus.
     dbus::Bus::Options options;
     options.bus_type = dbus::Bus::SYSTEM;
@@ -222,7 +222,7 @@
     message_loop_.RunUntilIdle();
   }
 
-  virtual void TearDown() override {
+  void TearDown() override {
     tag_client_->RemoveObserver(&mock_tag_observer_);
     device_client_->RemoveObserver(&mock_device_observer_);
     adapter_client_->RemoveObserver(&mock_adapter_observer_);
diff --git a/chromeos/dbus/shill_client_unittest_base.h b/chromeos/dbus/shill_client_unittest_base.h
index d7b8cde..9b32490 100644
--- a/chromeos/dbus/shill_client_unittest_base.h
+++ b/chromeos/dbus/shill_client_unittest_base.h
@@ -45,10 +45,10 @@
   explicit ValueMatcher(const base::Value& value);
 
   // MatcherInterface overrides.
-  virtual bool MatchAndExplain(const base::Value& value,
-                               MatchResultListener* listener) const override;
-  virtual void DescribeTo(::std::ostream* os) const override;
-  virtual void DescribeNegationTo(::std::ostream* os) const override;
+  bool MatchAndExplain(const base::Value& value,
+                       MatchResultListener* listener) const override;
+  void DescribeTo(::std::ostream* os) const override;
+  void DescribeNegationTo(::std::ostream* os) const override;
 
  private:
   scoped_ptr<base::Value> expected_value_;
diff --git a/components/BUILD.gn b/components/BUILD.gn
index c0f6ad8b..01503dc 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -36,6 +36,7 @@
     "//components/data_reduction_proxy/core/browser",
     "//components/data_reduction_proxy/core/common",
     "//components/device_event_log",
+    "//components/devtools_discovery",
     "//components/devtools_http_handler",
     "//components/dom_distiller/core",
     "//components/domain_reliability",
@@ -224,6 +225,7 @@
     deps += [
       "//components/app_modal",
       "//components/browsing_data",
+      "//components/scheduler",
     ]
   }
 
@@ -306,6 +308,10 @@
   if (is_ios) {
     deps -= [ "//components/devtools_http_handler:unit_tests" ]
   }
+
+  if (!is_ios) {
+    deps += [ "//components/scheduler:unit_tests" ]
+  }
 }
 
 repack("components_tests_pak") {
@@ -328,6 +334,17 @@
   ]
 }
 
+if (is_android) {
+  import("//build/config/android/rules.gni")
+
+  generate_jni("components_browsertests_jni_headers") {
+    jni_package = "components_browsertests/shell"
+    sources = [
+      "test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java",
+    ]
+  }
+}
+
 test("components_browsertests") {
   sources = [
     "autofill/content/browser/risk/fingerprint_browsertest.cc",
@@ -363,7 +380,18 @@
   data_deps = [ ":components_tests_pak" ]
 
   if (is_android) {
+    sources += [
+      "test/android/browsertests_apk/components_browser_tests_android.cc",
+      "test/android/browsertests_apk/components_browser_tests_android.h",
+      "test/android/browsertests_apk/components_browser_tests_jni_onload.cc",
+    ]
     sources -= [ "autofill/content/browser/risk/fingerprint_browsertest.cc" ]
+    deps += [
+      ":components_browsertests_jni_headers",
+      "//testing/android/native_test:native_test_util",
+    ]
+
+    use_launcher = false
   }
 
   if (is_linux) {
@@ -379,6 +407,7 @@
 
 test("components_perftests") {
   sources = [
+    "scheduler/child/task_queue_manager_perftest.cc",
     "visitedlink/test/visitedlink_perftest.cc",
   ]
 
@@ -389,6 +418,7 @@
     "//base",
     "//base/test:test_support_perf",
     "//testing/gtest",
+    "//testing/perf",
     "//content/test:test_support",
     "//components/visitedlink/browser",
   ]
diff --git a/components/OWNERS b/components/OWNERS
index 05b239f..296d144 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -58,6 +58,9 @@
 per-file devtools_bridge.gyp=mnaganov@chromium.org
 per-file devtools_bridge.gyp=serya@chromium.org
 
+per-file devtools_discovery.gyp*=dgozman@chromium.org
+per-file devtools_discovery.gyp*=pfeldman@chromium.org
+
 per-file devtools_http_handler.gyp*=dgozman@chromium.org
 per-file devtools_http_handler.gyp*=pfeldman@chromium.org
 
diff --git a/components/autofill.gypi b/components/autofill.gypi
index f3d2f6a..25f6909a 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -203,12 +203,10 @@
         'autofill/core/browser/webdata/autofill_webdata_service_observer.h',
       ],
       'conditions': [
-        ['desktop_linux==1', {
+        ['desktop_linux != 1', {
           # Controls whether Wallet cards can be saved to the local instance of
           # chrome.
-          'defines': [ 'ENABLE_SAVE_WALLET_CARDS_LOCALLY=0' ],
-        }, {
-          'defines': [ 'ENABLE_SAVE_WALLET_CARDS_LOCALLY=1' ],
+          'defines': [ 'ENABLE_SAVE_WALLET_CARDS_LOCALLY' ],
         }],
       ],
 
diff --git a/components/autofill/content/browser/wallet/wallet_signin_helper.cc b/components/autofill/content/browser/wallet/wallet_signin_helper.cc
index fc9b66f..92a228d 100644
--- a/components/autofill/content/browser/wallet/wallet_signin_helper.cc
+++ b/components/autofill/content/browser/wallet/wallet_signin_helper.cc
@@ -38,7 +38,7 @@
 void GetGoogleCookiesCallback(
     const base::Callback<void(const std::string&)>& callback,
     const net::CookieList& cookies) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   // Cookies for parent domains will also be returned; we only want cookies with
   // exact host matches. TODO(estade): really?
@@ -62,7 +62,7 @@
 void GetGoogleCookies(
     scoped_refptr<net::URLRequestContextGetter> request_context_getter,
     const base::Callback<void(const std::string&)>& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   net::URLRequestContext* url_request_context =
       request_context_getter->GetURLRequestContext();
@@ -166,7 +166,7 @@
 
 void WalletSigninHelper::ReturnWalletCookieValue(
     const std::string& cookie_value) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   delegate_->OnDidFetchWalletCookieValue(cookie_value);
 }
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
index d4b3f45..6971997 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -105,10 +105,19 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordFormBuilder);
 };
 
-class PasswordFormConversionUtilsTest : public content::RenderViewTest {
+// RenderVIewTest-based tests crash on Android
+// http://crbug.com/187500
+#if defined(OS_ANDROID)
+#define MAYBE_PasswordFormConversionUtilsTest \
+  DISABLED_PasswordFormConversionUtilsTest
+#else
+#define MAYBE_PasswordFormConversionUtilsTest PasswordFormConversionUtilsTest
+#endif  // defined(OS_ANDROID)
+
+class MAYBE_PasswordFormConversionUtilsTest : public content::RenderViewTest {
  public:
-  PasswordFormConversionUtilsTest() : content::RenderViewTest() {}
-  ~PasswordFormConversionUtilsTest() override {}
+  MAYBE_PasswordFormConversionUtilsTest() : content::RenderViewTest() {}
+  ~MAYBE_PasswordFormConversionUtilsTest() override {}
 
  protected:
   // Loads the given |html|, retrieves the sole WebFormElement from it, and then
@@ -138,12 +147,12 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest);
+  DISALLOW_COPY_AND_ASSIGN(MAYBE_PasswordFormConversionUtilsTest);
 };
 
 }  // namespace
 
-TEST_F(PasswordFormConversionUtilsTest, BasicFormAttributes) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, BasicFormAttributes) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username", "johnsmith", NULL);
   builder.AddSubmitButton("inactive_submit", false);
@@ -170,7 +179,7 @@
   EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, DisabledFieldsAreIgnored) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, DisabledFieldsAreIgnored) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username", "johnsmith", NULL);
   builder.AddDisabledUsernameField();
@@ -188,7 +197,7 @@
   EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, IdentifyingUsernameFields) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingUsernameFields) {
   // Each test case consists of a set of parameters to be plugged into the
   // PasswordFormBuilder below, plus the corresponding expectations.
   struct TestCase {
@@ -273,7 +282,7 @@
   }
 }
 
-TEST_F(PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) {
   // Each test case consists of a set of parameters to be plugged into the
   // PasswordFormBuilder below, plus the corresponding expectations.
   struct TestCase {
@@ -328,7 +337,7 @@
   }
 }
 
-TEST_F(PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) {
   // Each test case consists of a set of parameters to be plugged into the
   // PasswordFormBuilder below, plus the corresponding expectations.
   struct TestCase {
@@ -389,7 +398,7 @@
   }
 }
 
-TEST_F(PasswordFormConversionUtilsTest,
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
        IdentifyingPasswordFieldsWithAutocompleteAttributes) {
   // Each test case consists of a set of parameters to be plugged into the
   // PasswordFormBuilder below, plus the corresponding expectations.
@@ -527,7 +536,7 @@
   }
 }
 
-TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToBadActionURL) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, InvalidFormDueToBadActionURL) {
   PasswordFormBuilder builder("invalid_target");
   builder.AddUsernameField("username", "JohnSmith", NULL);
   builder.AddSubmitButton("submit", true);
@@ -539,7 +548,8 @@
   EXPECT_FALSE(password_form);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToNoPasswordFields) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
+       InvalidFormDueToNoPasswordFields) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username1", "John", NULL);
   builder.AddUsernameField("username2", "Smith", NULL);
@@ -551,7 +561,7 @@
   EXPECT_FALSE(password_form);
 }
 
-TEST_F(PasswordFormConversionUtilsTest,
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
        InvalidFormsDueToConfusingPasswordFields) {
   // Each test case consists of a set of parameters to be plugged into the
   // PasswordFormBuilder below.
@@ -582,7 +592,7 @@
   }
 }
 
-TEST_F(PasswordFormConversionUtilsTest,
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
        InvalidFormDueToTooManyPasswordFieldsWithoutAutocompleteAttributes) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username1", "John", NULL);
@@ -598,7 +608,7 @@
   EXPECT_FALSE(password_form);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, LayoutClassificationLogin) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, LayoutClassificationLogin) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddHiddenField();
   builder.AddUsernameField("username", "", nullptr);
@@ -612,7 +622,7 @@
   EXPECT_EQ(PasswordForm::Layout::LAYOUT_OTHER, login_form->layout);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, LayoutClassificationSignup) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, LayoutClassificationSignup) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("someotherfield", "", nullptr);
   builder.AddUsernameField("username", "", nullptr);
@@ -628,7 +638,7 @@
   EXPECT_EQ(PasswordForm::Layout::LAYOUT_OTHER, signup_form->layout);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, LayoutClassificationChange) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, LayoutClassificationChange) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username", "", nullptr);
   builder.AddPasswordField("old_password", "", nullptr);
@@ -644,7 +654,8 @@
   EXPECT_EQ(PasswordForm::Layout::LAYOUT_OTHER, change_form->layout);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, LayoutClassificationLoginPlusSignup_A) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
+       LayoutClassificationLoginPlusSignup_A) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username", "", nullptr);
   builder.AddHiddenField();
@@ -665,7 +676,8 @@
             login_plus_signup_form->layout);
 }
 
-TEST_F(PasswordFormConversionUtilsTest, LayoutClassificationLoginPlusSignup_B) {
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
+       LayoutClassificationLoginPlusSignup_B) {
   PasswordFormBuilder builder(kTestFormActionURL);
   builder.AddUsernameField("username", "", nullptr);
   builder.AddHiddenField();
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 17ca7fd..6c2d3d1 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -120,10 +120,8 @@
   ]
 
   # Controls whether Wallet cards can be saved to the local instance of chrome.
-  if (is_desktop_linux) {
-    defines = [ "ENABLE_SAVE_WALLET_CARDS_LOCALLY=0" ]
-  } else {
-    defines = [ "ENABLE_SAVE_WALLET_CARDS_LOCALLY=1" ]
+  if (!is_desktop_linux) {
+    defines = [ "ENABLE_SAVE_WALLET_CARDS_LOCALLY" ]
   }
 
   deps = [
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 8d26935..beb4281 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -397,6 +397,8 @@
   if (submitted_form->IsAutofillable())
     ImportFormData(*submitted_form);
 
+  recently_unmasked_cards_.clear();
+
   return true;
 }
 
@@ -765,7 +767,8 @@
 void AutofillManager::OnLoadedServerPredictions(
     const std::string& response_xml) {
   // Parse and store the server predictions.
-  FormStructure::ParseQueryResponse(response_xml, form_structures_.get());
+  FormStructure::ParseQueryResponse(response_xml, form_structures_.get(),
+                                    client_->GetRapporService());
 
   // Forward form structures to the password generation manager to detect
   // account creation forms.
@@ -799,6 +802,7 @@
   if (!real_pan.empty()) {
     DCHECK_EQ(AutofillClient::SUCCESS, result);
     credit_card_form_event_logger_->OnDidFillSuggestion(unmasking_card_);
+    recently_unmasked_cards_.push_back(unmasking_card_);
     unmasking_card_.set_record_type(CreditCard::FULL_SERVER_CARD);
     unmasking_card_.SetNumber(base::UTF8ToUTF16(real_pan));
     if (unmask_response_.should_store_pan)
@@ -824,6 +828,17 @@
   if (!personal_data_->ImportFormData(submitted_form, &imported_credit_card))
     return;
 
+  // Don't offer to save any cards that were recently unmasked.
+  if (recently_unmasked_cards_.end() !=
+      std::find_if(recently_unmasked_cards_.begin(),
+                   recently_unmasked_cards_.end(),
+                   [&imported_credit_card](const CreditCard& unmasked) -> bool {
+                     return unmasked.TypeAndLastFourDigits() ==
+                            imported_credit_card->TypeAndLastFourDigits();
+                   })) {
+    return;
+  }
+
   // If credit card information was submitted, we need to confirm whether to
   // save it.
   if (imported_credit_card) {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 542e8b8e..f69634a 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -419,6 +419,10 @@
   // Time when we requested the last real pan
   base::Time real_pan_request_timestamp_;
 
+  // Masked copies of recently unmasked cards, to help avoid double-asking to
+  // save the card (in the prompt and in the infobar after submit).
+  std::vector<CreditCard> recently_unmasked_cards_;
+
   // SuggestionBackendID to ID mapping. We keep two maps to convert back and
   // forth. These should be used only by BackendIDToInt and IntToBackendID.
   // Note that the integers are not frontend IDs.
@@ -470,6 +474,7 @@
                            FormSubmittedAutocompleteEnabled);
   FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
                            AutocompleteOffRespectedForAutocomplete);
+  FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, DontOfferToSaveWalletCard);
   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 238b205d..d2255cb5 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -35,6 +35,7 @@
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "grit/components_strings.h"
+#include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -51,6 +52,19 @@
 
 const int kDefaultPageID = 137;
 
+class MockAutofillClient : public TestAutofillClient {
+ public:
+  MockAutofillClient() {}
+
+  ~MockAutofillClient() override {}
+
+  MOCK_METHOD1(ConfirmSaveCreditCard,
+               void(const base::Closure& save_card_callback));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockAutofillClient);
+};
+
 class TestPersonalDataManager : public PersonalDataManager {
  public:
   TestPersonalDataManager()
@@ -627,6 +641,9 @@
     personal_data_.set_database(autofill_client_.GetDatabase());
     personal_data_.SetPrefService(autofill_client_.GetPrefs());
     autofill_driver_.reset(new MockAutofillDriver());
+    request_context_ =
+        new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
+    autofill_driver_->SetURLRequestContext(request_context_.get());
     autofill_manager_.reset(new TestAutofillManager(
         autofill_driver_.get(), &autofill_client_, &personal_data_));
 
@@ -646,6 +663,8 @@
     // need to care about removing self as an observer in destruction.
     personal_data_.set_database(scoped_refptr<AutofillWebDataService>(NULL));
     personal_data_.SetPrefService(NULL);
+
+    request_context_ = nullptr;
   }
 
   void GetAutofillSuggestions(int query_id,
@@ -714,10 +733,11 @@
 
  protected:
   base::MessageLoop message_loop_;
-  TestAutofillClient autofill_client_;
+  MockAutofillClient autofill_client_;
   scoped_ptr<MockAutofillDriver> autofill_driver_;
   scoped_ptr<TestAutofillManager> autofill_manager_;
   scoped_ptr<TestAutofillExternalDelegate> external_delegate_;
+  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
   TestPersonalDataManager personal_data_;
 };
 
@@ -3036,35 +3056,6 @@
 }
 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
 
-namespace {
-
-class MockAutofillClient : public TestAutofillClient {
- public:
-  MockAutofillClient() {}
-
-  ~MockAutofillClient() override {}
-
-  void ShowRequestAutocompleteDialog(const FormData& form,
-                                     content::RenderFrameHost* rfh,
-                                     const ResultCallback& callback) override {
-    callback.Run(user_supplied_data_ ? AutocompleteResultSuccess :
-                                       AutocompleteResultErrorDisabled,
-                 base::string16(),
-                 user_supplied_data_.get());
-  }
-
-  void SetUserSuppliedData(scoped_ptr<FormStructure> user_supplied_data) {
-    user_supplied_data_.reset(user_supplied_data.release());
-  }
-
- private:
-  scoped_ptr<FormStructure> user_supplied_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockAutofillClient);
-};
-
-}  // namespace
-
 // Test our external delegate is called at the right time.
 TEST_F(AutofillManagerTest, TestExternalDelegate) {
   FormData form;
@@ -3139,4 +3130,48 @@
           "04/12", kVisaCard, autofill_manager_->GetPackedCreditCardID(4)));
 }
 
+TEST_F(AutofillManagerTest, DontOfferToSaveWalletCard) {
+  // This line silences the warning from RealPanWalletClient about matching
+  // sync and wallet server types.
+  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      "sync-url", "https://google.com");
+
+  // Set up our form data.
+  FormData form;
+  CreateTestCreditCardFormData(&form, true, false);
+  std::vector<FormData> forms(1, form);
+  FormsSeen(forms);
+
+  CreditCard card(CreditCard::MASKED_SERVER_CARD, "a123");
+  test::SetCreditCardInfo(&card, "John Dillinger", "1881" /* Visa */, "01",
+                          "2017");
+  card.SetTypeForMaskedCard(kVisaCard);
+
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCard(_)).Times(0);
+  EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _));
+  autofill_manager_->FillOrPreviewCreditCardForm(
+      AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form,
+      form.fields[0], card, 0);
+
+  // Manually fill out |form| so we can use it in OnFormSubmitted.
+  for (size_t i = 0; i < form.fields.size(); ++i) {
+    if (form.fields[i].name == ASCIIToUTF16("cardnumber"))
+      form.fields[i].value = ASCIIToUTF16("4012888888881881");
+    else if (form.fields[i].name == ASCIIToUTF16("nameoncard"))
+      form.fields[i].value = ASCIIToUTF16("John H Dillinger");
+    else if (form.fields[i].name == ASCIIToUTF16("ccmonth"))
+      form.fields[i].value = ASCIIToUTF16("01");
+    else if (form.fields[i].name == ASCIIToUTF16("ccyear"))
+      form.fields[i].value = ASCIIToUTF16("2017");
+  }
+
+  AutofillManager::UnmaskResponse response;
+  response.should_store_pan = false;
+  response.cvc = ASCIIToUTF16("123");
+  autofill_manager_->OnUnmaskResponse(response);
+  autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS,
+                                     "4012888888881881");
+  autofill_manager_->OnFormSubmitted(form);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index a582b0a..5c76c62 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -550,9 +550,9 @@
 }
 
 // static
-void FormStructure::ParseQueryResponse(
-    const std::string& response_xml,
-    const std::vector<FormStructure*>& forms) {
+void FormStructure::ParseQueryResponse(const std::string& response_xml,
+                                       const std::vector<FormStructure*>& forms,
+                                       rappor::RapporService* rappor_service) {
   AutofillMetrics::LogServerQueryMetric(
       AutofillMetrics::QUERY_RESPONSE_RECEIVED);
 
@@ -579,6 +579,7 @@
     FormStructure* form = *iter;
     form->upload_required_ = upload_required;
 
+    bool query_response_has_no_server_data = true;
     for (std::vector<AutofillField*>::iterator field = form->fields_.begin();
          field != form->fields_.end(); ++field) {
       if (form->ShouldSkipField(**field))
@@ -589,6 +590,9 @@
       if (current_info == field_infos.end())
         break;
 
+      query_response_has_no_server_data &=
+          current_info->field_type == NO_SERVER_DATA;
+
       // If |form->has_author_specified_types| only password fields should be
       // updated.
       if (!form->has_author_specified_types_ ||
@@ -612,6 +616,12 @@
       ++current_info;
     }
 
+    if (query_response_has_no_server_data && form->source_url().is_valid()) {
+      rappor::SampleDomainAndRegistryFromGURL(
+          rappor_service, "Autofill.QueryResponseHasNoServerDataForForm",
+          form->source_url());
+    }
+
     form->UpdateAutofillCount();
     form->IdentifySections(false);
   }
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 8e2e7a1..5a3f5065 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -77,8 +77,10 @@
 
   // Parses the field types from the server query response. |forms| must be the
   // same as the one passed to EncodeQueryRequest when constructing the query.
+  // |rappor_service| may be null.
   static void ParseQueryResponse(const std::string& response_xml,
-                                 const std::vector<FormStructure*>& forms);
+                                 const std::vector<FormStructure*>& forms,
+                                 rappor::RapporService* rappor_service);
 
   // Returns predictions using the details from the given |form_structures| and
   // their fields' predicted types.
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index a437aa4..7d05b72 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -11,10 +11,12 @@
 #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/rappor/test_rappor_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 using base::ASCIIToUTF16;
+using rappor::TestRapporService;
 
 namespace autofill {
 
@@ -2379,7 +2381,9 @@
 }
 
 TEST(FormStructureTest, ParseQueryResponse) {
+  TestRapporService rappor_service;
   FormData form;
+  form.origin = GURL("http://foo.com");
   FormFieldData field;
   field.form_control_type = "text";
 
@@ -2420,7 +2424,7 @@
       "<field autofilltype=\"0\" />"
       "</autofillqueryresponse>";
 
-  FormStructure::ParseQueryResponse(response, forms.get());
+  FormStructure::ParseQueryResponse(response, forms.get(), &rappor_service);
 
   ASSERT_GE(forms[0]->field_count(), 2U);
   ASSERT_GE(forms[1]->field_count(), 2U);
@@ -2428,11 +2432,17 @@
   EXPECT_EQ(30, forms[0]->field(1)->server_type());
   EXPECT_EQ(9, forms[1]->field(0)->server_type());
   EXPECT_EQ(0, forms[1]->field(1)->server_type());
+
+  // No RAPPOR metrics are logged in the case there is server data available for
+  // all forms.
+  EXPECT_EQ(0, rappor_service.GetReportsCount());
 }
 
 // If user defined types are present, only parse password fields.
 TEST(FormStructureTest, ParseQueryResponseAuthorDefinedTypes) {
+  TestRapporService rappor_service;
   FormData form;
+  form.origin = GURL("http://foo.com");
   FormFieldData field;
 
   field.label = ASCIIToUTF16("email");
@@ -2457,11 +2467,159 @@
       "<field autofilltype=\"76\" />"
       "</autofillqueryresponse>";
 
-  FormStructure::ParseQueryResponse(response, forms.get());
+  FormStructure::ParseQueryResponse(response, forms.get(), &rappor_service);
 
   ASSERT_GE(forms[0]->field_count(), 2U);
   EXPECT_EQ(NO_SERVER_DATA, forms[0]->field(0)->server_type());
   EXPECT_EQ(76, forms[0]->field(1)->server_type());
 }
 
+// If the server returns NO_SERVER_DATA for one of the forms, expect RAPPOR
+// logging.
+TEST(FormStructureTest, ParseQueryResponse_RapporLogging_OneFormNoServerData) {
+  TestRapporService rappor_service;
+  FormData form;
+  form.origin = GURL("http://foo.com");
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("fullname");
+  field.name = ASCIIToUTF16("fullname");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("address");
+  field.name = ASCIIToUTF16("address");
+  form.fields.push_back(field);
+
+  ScopedVector<FormStructure> forms;
+  forms.push_back(new FormStructure(form));
+
+  field.label = ASCIIToUTF16("email");
+  field.name = ASCIIToUTF16("email");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("password");
+  field.name = ASCIIToUTF16("password");
+  field.form_control_type = "password";
+  form.fields.push_back(field);
+
+  forms.push_back(new FormStructure(form));
+
+  std::string response =
+      "<autofillqueryresponse>"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"9\" />"
+      "<field autofilltype=\"0\" />"
+      "</autofillqueryresponse>";
+
+  FormStructure::ParseQueryResponse(response, forms.get(), &rappor_service);
+
+  EXPECT_EQ(1, rappor_service.GetReportsCount());
+  std::string sample;
+  rappor::RapporType type;
+  EXPECT_TRUE(rappor_service.GetRecordedSampleForMetric(
+      "Autofill.QueryResponseHasNoServerDataForForm", &sample, &type));
+  EXPECT_EQ("foo.com", sample);
+  EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
+}
+
+// If the server returns NO_SERVER_DATA for both of the forms, expect RAPPOR
+// logging.
+TEST(FormStructureTest, ParseQueryResponse_RapporLogging_AllFormsNoServerData) {
+  TestRapporService rappor_service;
+  FormData form;
+  form.origin = GURL("http://foo.com");
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("fullname");
+  field.name = ASCIIToUTF16("fullname");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("address");
+  field.name = ASCIIToUTF16("address");
+  form.fields.push_back(field);
+
+  ScopedVector<FormStructure> forms;
+  forms.push_back(new FormStructure(form));
+
+  field.label = ASCIIToUTF16("email");
+  field.name = ASCIIToUTF16("email");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("password");
+  field.name = ASCIIToUTF16("password");
+  field.form_control_type = "password";
+  form.fields.push_back(field);
+
+  forms.push_back(new FormStructure(form));
+
+  std::string response =
+      "<autofillqueryresponse>"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"0\" />"
+      "</autofillqueryresponse>";
+
+  FormStructure::ParseQueryResponse(response, forms.get(), &rappor_service);
+
+  // Even though both forms are logging to RAPPOR, there is only one sample for
+  // a given eTLD+1.
+  EXPECT_EQ(1, rappor_service.GetReportsCount());
+  std::string sample;
+  rappor::RapporType type;
+  EXPECT_TRUE(rappor_service.GetRecordedSampleForMetric(
+      "Autofill.QueryResponseHasNoServerDataForForm", &sample, &type));
+  EXPECT_EQ("foo.com", sample);
+  EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
+}
+
+// If the server returns NO_SERVER_DATA for only some of the fields, expect no
+// RAPPOR logging.
+TEST(FormStructureTest, ParseQueryResponse_RapporLogging_PartialNoServerData) {
+  TestRapporService rappor_service;
+  FormData form;
+  form.origin = GURL("http://foo.com");
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("fullname");
+  field.name = ASCIIToUTF16("fullname");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("address");
+  field.name = ASCIIToUTF16("address");
+  form.fields.push_back(field);
+
+  ScopedVector<FormStructure> forms;
+  forms.push_back(new FormStructure(form));
+
+  field.label = ASCIIToUTF16("email");
+  field.name = ASCIIToUTF16("email");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("password");
+  field.name = ASCIIToUTF16("password");
+  field.form_control_type = "password";
+  form.fields.push_back(field);
+
+  forms.push_back(new FormStructure(form));
+
+  std::string response =
+      "<autofillqueryresponse>"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"10\" />"
+      "<field autofilltype=\"0\" />"
+      "<field autofilltype=\"11\" />"
+      "</autofillqueryresponse>";
+
+  FormStructure::ParseQueryResponse(response, forms.get(), &rappor_service);
+
+  // No RAPPOR metrics are logged in the case there is at least some server data
+  // available for all forms.
+  EXPECT_EQ(0, rappor_service.GetReportsCount());
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 15edaac..9af96ab 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -490,8 +490,9 @@
   }
 
   // Also don't offer to save if we already have this stored as a full wallet
-  // card. (In particular this comes up just after filling and submitting a
-  // Wallet card.)
+  // card. Note that we will offer to save masked server cards, as long as
+  // the user re-typed the info by hand. See AutofillManager's
+  // |recently_unmasked_cards_|.
   if (local_imported_credit_card) {
     for (CreditCard* card : server_credit_cards_) {
       if (card->record_type() == CreditCard::FULL_SERVER_CARD &&
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 90828085..5780908 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
+#include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/form_structure.h"
@@ -494,6 +495,16 @@
   base::MessageLoop::current()->Run();
 
   ASSERT_EQ(3U, personal_data_->GetCreditCards().size());
+
+  if (!OfferStoreUnmaskedCards()) {
+    for (CreditCard* card : personal_data_->GetCreditCards()) {
+      EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, card->record_type());
+    }
+    // The rest of this test doesn't work if we're force-masking all unmasked
+    // cards.
+    return;
+  }
+
   // The GUIDs will be different, so just compare the data.
   for (size_t i = 0; i < 3; ++i)
     EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i]));
@@ -917,8 +928,8 @@
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
   scoped_ptr<CreditCard> imported_credit_card;
-  EXPECT_TRUE(personal_data_->ImportFormData(form_structure,
-                                              &imported_credit_card));
+  EXPECT_TRUE(
+      personal_data_->ImportFormData(form_structure, &imported_credit_card));
   const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
   ASSERT_EQ(1U, profiles.size());
 }
@@ -3143,6 +3154,16 @@
   base::MessageLoop::current()->Run();
 
   ASSERT_EQ(3U, personal_data_->GetCreditCards().size());
+
+  if (!OfferStoreUnmaskedCards()) {
+    for (CreditCard* card : personal_data_->GetCreditCards()) {
+      EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, card->record_type());
+    }
+    // The rest of this test doesn't work if we're force-masking all unmasked
+    // cards.
+    return;
+  }
+
   // The GUIDs will be different, so just compare the data.
   for (size_t i = 0; i < 3; ++i)
     EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i]));
@@ -3253,4 +3274,67 @@
   EXPECT_TRUE(personal_data_->GetProfiles().empty());
 }
 
+TEST_F(PersonalDataManagerTest, DontDuplicateServerCard) {
+  EnableWalletCardImport();
+
+  std::vector<CreditCard> server_cards;
+  server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
+  test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
+                          "1881" /* Visa */, "01", "2017");
+  server_cards.back().SetTypeForMaskedCard(kVisaCard);
+
+  server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
+  test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
+                          "347666888555" /* American Express */, "04", "2015");
+
+  test::SetServerCreditCards(autofill_table_, server_cards);
+  personal_data_->Refresh();
+  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+      .WillOnce(QuitMainMessageLoop());
+  base::MessageLoop::current()->Run();
+
+  // A valid credit card form. A user re-types one of their masked cards.
+  // We should offer to save.
+  FormData form1;
+  FormFieldData field;
+  test::CreateTestFormField("Name on card:", "name_on_card", "John Dillinger",
+                            "text", &field);
+  form1.fields.push_back(field);
+  test::CreateTestFormField("Card Number:", "card_number", "4012888888881881",
+                            "text", &field);
+  form1.fields.push_back(field);
+  test::CreateTestFormField("Exp Month:", "exp_month", "01", "text", &field);
+  form1.fields.push_back(field);
+  test::CreateTestFormField("Exp Year:", "exp_year", "2017", "text", &field);
+  form1.fields.push_back(field);
+
+  FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
+  scoped_ptr<CreditCard> imported_credit_card;
+  EXPECT_TRUE(
+      personal_data_->ImportFormData(form_structure1, &imported_credit_card));
+  EXPECT_TRUE(imported_credit_card);
+  imported_credit_card.reset();
+
+  // A user re-types (or fills with) an unmasked card. Don't offer to save
+  // again.
+  FormData form2;
+  test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
+                            "text", &field);
+  form2.fields.push_back(field);
+  test::CreateTestFormField("Card Number:", "card_number", "347666888555",
+                            "text", &field);
+  form2.fields.push_back(field);
+  test::CreateTestFormField("Exp Month:", "exp_month", "04", "text", &field);
+  form2.fields.push_back(field);
+  test::CreateTestFormField("Exp Year:", "exp_year", "2015", "text", &field);
+  form2.fields.push_back(field);
+
+  FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
+  EXPECT_FALSE(
+      personal_data_->ImportFormData(form_structure2, &imported_credit_card));
+  EXPECT_FALSE(imported_credit_card);
+}
+
 }  // namespace autofill
diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc
index 8076a2a..28b45eb 100644
--- a/components/cdm/renderer/android_key_systems.cc
+++ b/components/cdm/renderer/android_key_systems.cc
@@ -62,18 +62,18 @@
 
   // We are using MediaDrm API on Android and we cannot guarantee that API
   // doesn't use persistent storage on the device. Therefore always set
-  // persistent state to EME_FEATURE_ALWAYS_ENABLED to err on the safe side.
+  // persistent state to EmeFeatureSupport::ALWAYS_ENABLED to err on the
+  // safe side.
 
   if (codecs != media::EME_CODEC_NONE) {
     AddWidevineWithCodecs(
-        WIDEVINE,
-        codecs,
-        max_audio_robustness,
-        max_video_robustness,
-        media::EME_SESSION_TYPE_NOT_SUPPORTED,  // persistent-license.
-        media::EME_SESSION_TYPE_NOT_SUPPORTED,  // persistent-release-message.
-        media::EME_FEATURE_ALWAYS_ENABLED,      // Persistent state.
-        media::EME_FEATURE_ALWAYS_ENABLED,      // Distinctive identifier.
+        WIDEVINE, codecs, max_audio_robustness, max_video_robustness,
+        media::EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
+        media::EmeSessionTypeSupport::
+            NOT_SUPPORTED,  // persistent-release-message.
+        media::EmeFeatureSupport::ALWAYS_ENABLED,  // Persistent state.
+        media::EmeFeatureSupport::ALWAYS_ENABLED,  // Distinctive
+                                                   // identifier.
         concrete_key_systems);
   }
 
@@ -84,14 +84,15 @@
   // TODO(ddorwin): Remove with unprefixed. http://crbug.com/249976
   if (response.non_compositing_codecs != media::EME_CODEC_NONE) {
     AddWidevineWithCodecs(
-        WIDEVINE_HR_NON_COMPOSITING,
-        response.non_compositing_codecs,
-        EmeRobustness::HW_SECURE_CRYPTO,        // Max audio robustness.
-        EmeRobustness::HW_SECURE_ALL,           // Max video robustness.
-        media::EME_SESSION_TYPE_NOT_SUPPORTED,  // persistent-license.
-        media::EME_SESSION_TYPE_NOT_SUPPORTED,  // persistent-release-message.
-        media::EME_FEATURE_ALWAYS_ENABLED,      // Persistent state.
-        media::EME_FEATURE_ALWAYS_ENABLED,      // Distinctive identifier.
+        WIDEVINE_HR_NON_COMPOSITING, response.non_compositing_codecs,
+        EmeRobustness::HW_SECURE_CRYPTO,              // Max audio robustness.
+        EmeRobustness::HW_SECURE_ALL,                 // Max video robustness.
+        media::EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
+        media::EmeSessionTypeSupport::
+            NOT_SUPPORTED,  // persistent-release-message.
+        media::EmeFeatureSupport::ALWAYS_ENABLED,  // Persistent state.
+        media::EmeFeatureSupport::ALWAYS_ENABLED,  // Distinctive
+                                                   // identifier.
         concrete_key_systems);
   }
 }
@@ -121,11 +122,13 @@
       info.max_audio_robustness = EmeRobustness::EMPTY;
       info.max_video_robustness = EmeRobustness::EMPTY;
       // Assume the worst case (from a user point of view).
-      info.persistent_license_support = media::EME_SESSION_TYPE_NOT_SUPPORTED;
+      info.persistent_license_support =
+          media::EmeSessionTypeSupport::NOT_SUPPORTED;
       info.persistent_release_message_support =
-          media::EME_SESSION_TYPE_NOT_SUPPORTED;
-      info.persistent_state_support = media::EME_FEATURE_ALWAYS_ENABLED;
-      info.distinctive_identifier_support = media::EME_FEATURE_ALWAYS_ENABLED;
+          media::EmeSessionTypeSupport::NOT_SUPPORTED;
+      info.persistent_state_support = media::EmeFeatureSupport::ALWAYS_ENABLED;
+      info.distinctive_identifier_support =
+          media::EmeFeatureSupport::ALWAYS_ENABLED;
       concrete_key_systems->push_back(info);
     }
   }
diff --git a/components/components.gyp b/components/components.gyp
index 9327c97..3f6eb49 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -88,6 +88,7 @@
         'app_modal.gypi',
         'browsing_data.gypi',
         'cdm.gypi',
+        'devtools_discovery.gypi',
         'devtools_http_handler.gypi',
         'navigation_interception.gypi',
         'power.gypi',
diff --git a/components/components_browsertests.isolate b/components/components_browsertests.isolate
index 2dff53ae..e60cea1 100644
--- a/components/components_browsertests.isolate
+++ b/components/components_browsertests.isolate
@@ -34,18 +34,32 @@
         ],
       },
     }],
+    ['OS=="android"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/components_browsertests_apk_shell/assets/components_tests_resources.pak',
+          '<(PRODUCT_DIR)/components_browsertests_apk_shell/assets/content_shell.pak',
+        ],
+      },
+    }],
     ['OS=="linux" or OS=="mac" or OS=="win"', {
       'variables': {
         'files': [
-          'test/data/',
           '../testing/test_env.py',
-          '../third_party/dom_distiller_js/dist/test/data/',
           '<(PRODUCT_DIR)/components_browsertests<(EXECUTABLE_SUFFIX)',
           '<(PRODUCT_DIR)/components_tests_resources.pak',
           '<(PRODUCT_DIR)/content_shell.pak',
         ],
       },
     }],
+    ['OS=="android" or OS=="linux" or OS=="mac" or OS=="win"', {
+      'variables': {
+        'files': [
+          'test/data/',
+          '../third_party/dom_distiller_js/dist/test/data/',
+        ],
+      },
+    }],
     ['OS=="linux"', {
       'variables': {
         'files': [
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 14710fa..f48690f 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -430,6 +430,18 @@
       'rappor/rappor_service_unittest.cc',
       'rappor/rappor_utils_unittest.cc',
     ],
+    'scheduler_unittest_sources': [
+      'scheduler/child/nestable_task_runner_for_test.cc',
+      'scheduler/child/nestable_task_runner_for_test.h',
+      'scheduler/child/prioritizing_task_queue_selector_unittest.cc',
+      'scheduler/child/scheduler_helper_unittest.cc',
+      'scheduler/child/task_queue_manager_unittest.cc',
+      'scheduler/child/test_time_source.cc',
+      'scheduler/child/test_time_source.h',
+      'scheduler/child/worker_scheduler_impl_unittest.cc',
+      'scheduler/renderer/deadline_task_runner_unittest.cc',
+      'scheduler/renderer/renderer_scheduler_impl_unittest.cc',
+    ],
     'search_unittest_sources': [
       'search/search_android_unittest.cc',
       'search/search_unittest.cc',
@@ -815,6 +827,7 @@
             '<@(navigation_interception_unittest_sources)',
             '<@(network_hints_unittest_sources)',
             '<@(power_unittest_sources)',
+            '<@(scheduler_unittest_sources)',
             '<@(storage_monitor_unittest_sources)',
             '<@(ui_unittest_sources)',
             '<@(visitedlink_unittest_sources)',
@@ -849,6 +862,7 @@
             'components.gyp:web_cache_browser',
             'components.gyp:web_modal',
             'components.gyp:web_modal_test_support',
+            'scheduler/scheduler.gyp:scheduler',
             'webcrypto/webcrypto.gyp:webcrypto',
             '../third_party/re2/re2.gyp:re2',
           ],
@@ -1109,6 +1123,87 @@
     },
   ],
   'conditions': [
+    ['OS == "android"', {
+      'variables': {
+        'components_browsertests_pak_input_resources': [
+          '<(PRODUCT_DIR)/components_tests_resources.pak',
+          '<(PRODUCT_DIR)/content_shell/assets/content_shell.pak',
+        ],
+        'conditions': [
+          ['icu_use_data_file_flag==1', {
+            'components_browsertests_pak_input_resources': [
+              '<(PRODUCT_DIR)/icudtl.dat',
+            ],
+          }],
+          ['v8_use_external_startup_data==1', {
+            'components_browsertests_pak_input_resources': [
+              '<(PRODUCT_DIR)/natives_blob.bin',
+              '<(PRODUCT_DIR)/snapshot_blob.bin',
+            ],
+          }],
+        ],
+      },
+      'targets': [
+        {
+          'target_name': 'components_browsertests_paks_copy',
+          'type': 'none',
+          'dependencies': [
+            'components_browsertests',
+          ],
+          'copies': [
+            {
+              'destination': '<(PRODUCT_DIR)/components_browsertests_apk_shell/assets',
+              'files': [
+                '<@(components_browsertests_pak_input_resources)',
+              ],
+            }
+          ],
+        },
+        {
+          'target_name': 'components_browsertests_manifest',
+          'type': 'none',
+          'variables': {
+            'jinja_inputs': ['test/android/browsertests_apk/AndroidManifest.xml.jinja2'],
+            'jinja_output': '<(SHARED_INTERMEDIATE_DIR)/components_browsertests_manifest/AndroidManifest.xml',
+          },
+          'includes': [ '../build/android/jinja_template.gypi' ],
+        },
+        {
+          'target_name': 'components_browsertests_jni_headers',
+          'type': 'none',
+          'sources': [
+            'test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java',
+          ],
+          'variables': {
+            'jni_gen_package': 'content/shell',
+          },
+          'includes': [ '../build/jni_generator.gypi' ],
+        },
+        {
+          # TODO(GN)
+          'target_name': 'components_browsertests_apk',
+          'type': 'none',
+          'dependencies': [
+            '../content/content.gyp:content_icudata',
+            '../content/content.gyp:content_java',
+            '../content/content.gyp:content_v8_external_data',
+            '../content/content_shell_and_tests.gyp:content_java_test_support',
+            '../content/content_shell_and_tests.gyp:content_shell_java',
+            'components_browsertests_paks_copy',
+            'components_browsertests',
+          ],
+          'variables': {
+            'apk_name': 'components_browsertests',
+            'java_in_dir': 'test/android/browsertests_apk',
+            'android_manifest_path': '<(SHARED_INTERMEDIATE_DIR)/components_browsertests_manifest/AndroidManifest.xml',
+            'resource_dir': 'test/android/browsertests_apk/res',
+            'native_lib_target': 'libcomponents_browsertests',
+            'asset_location': '<(PRODUCT_DIR)/components_browsertests_apk_shell/assets',
+          },
+          'includes': [ '../build/java_apk.gypi' ],
+        },
+      ],
+    }],
     ['OS != "ios"', {
       'targets': [
         {
@@ -1120,12 +1215,15 @@
             '../base/base.gyp:test_support_perf',
             '../content/content_shell_and_tests.gyp:test_support_content',
             '../testing/gtest.gyp:gtest',
+            '../testing/perf/perf_test.gyp:perf_test',
             'components.gyp:visitedlink_browser',
+            'scheduler/scheduler.gyp:scheduler',
           ],
          'include_dirs': [
            '..',
          ],
          'sources': [
+           'scheduler/child/task_queue_manager_perftest.cc',
            'visitedlink/test/visitedlink_perftest.cc',
          ],
          'conditions': [
@@ -1187,9 +1285,18 @@
           ],
           'conditions': [
             ['OS == "android"', {
+              'sources' : [
+                'test/android/browsertests_apk/components_browser_tests_android.cc',
+                'test/android/browsertests_apk/components_browser_tests_android.h',
+                'test/android/browsertests_apk/components_browser_tests_jni_onload.cc',
+              ],
               'sources!': [
                 'autofill/content/browser/risk/fingerprint_browsertest.cc',
               ],
+              'dependencies': [
+                '../testing/android/native_test.gyp:native_test_util',
+                'components_browsertests_jni_headers',
+              ],
             }],
             ['OS == "linux"', {
               'sources': [
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc
index 74076c5..39f70ee 100644
--- a/components/content_settings/core/browser/host_content_settings_map.cc
+++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -493,6 +493,14 @@
     return false;
   }
 #endif
+
+  // Don't support ALLOW for the default media settings.
+  if ((content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
+       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
+      setting == CONTENT_SETTING_ALLOW) {
+    return false;
+  }
+
   return IsSettingAllowedForType(prefs, setting, content_type);
 }
 
diff --git a/components/crash/browser/crash_dump_manager_android.cc b/components/crash/browser/crash_dump_manager_android.cc
index 4814afdc..a6df1d92 100644
--- a/components/crash/browser/crash_dump_manager_android.cc
+++ b/components/crash/browser/crash_dump_manager_android.cc
@@ -57,7 +57,7 @@
 }
 
 base::File CrashDumpManager::CreateMinidumpFile(int child_process_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER));
+  DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
   base::FilePath minidump_path;
   if (!base::CreateTemporaryFile(&minidump_path))
     return base::File();
diff --git a/components/cronet/android/cronet_url_request_adapter.cc b/components/cronet/android/cronet_url_request_adapter.cc
index 64713bf..cec7756 100644
--- a/components/cronet/android/cronet_url_request_adapter.cc
+++ b/components/cronet/android/cronet_url_request_adapter.cc
@@ -52,9 +52,11 @@
   return reinterpret_cast<jlong>(adapter);
 }
 
-// IOBuffer subclass for a buffer owned by a Java ByteBuffer. Keeps the
-// ByteBuffer alive until destroyed.
-class CronetURLRequestAdapter::IOBufferWithByteBuffer : public net::IOBuffer {
+// net::WrappedIOBuffer subclass for a buffer owned by a Java ByteBuffer. Keeps
+// the ByteBuffer alive until destroyed. Uses WrappedIOBuffer because data() is
+// owned by the embedder.
+class CronetURLRequestAdapter::IOBufferWithByteBuffer
+    : public net::WrappedIOBuffer {
  public:
   // Creates a buffer wrapping the Java ByteBuffer |jbyte_buffer|. |data| points
   // to the memory backed by the ByteBuffer, and position is the location to
@@ -64,7 +66,7 @@
       jobject jbyte_buffer,
       void* data,
       int position)
-      : net::IOBuffer(static_cast<char*>(data) + position),
+      : net::WrappedIOBuffer(static_cast<char*>(data) + position),
         initial_position_(position) {
     DCHECK(data);
     DCHECK_EQ(env->GetDirectBufferAddress(jbyte_buffer), data);
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
index f0207ec..03246f4 100644
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
@@ -77,8 +77,8 @@
     }
 
     /**
-     * Starts NetLog logging to a file. The NetLog log level used is
-     * LOG_ALL_BUT_BYTES.
+     * Starts NetLog logging to a file. The NetLog capture mode is
+     * NetLogCaptureMode::Default().
      * @param fileName The complete file path. It must not be empty. If file
      *            exists, it is truncated before starting. If actively logging,
      *            this method is ignored.
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java
index 54eee3f..cddd64d 100644
--- a/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java
@@ -56,8 +56,8 @@
     public abstract void shutdown();
 
     /**
-     * Starts NetLog logging to a file. The NetLog log level used is
-     * LOG_ALL_BUT_BYTES.
+     * Starts NetLog logging to a file. The NetLog capture mode used is
+     * NetLogCaptureMode::Default().
      * @param fileName The complete file path. It must not be empty. If file
      *            exists, it is truncated before starting. If actively logging,
      *            this method is ignored.
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetFixedModeOutputStream.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetFixedModeOutputStream.java
index 3e4bb25..8b9519e 100644
--- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetFixedModeOutputStream.java
+++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetFixedModeOutputStream.java
@@ -151,7 +151,7 @@
             // Reuse this buffer.
             mBuffer.clear();
             // Quit message loop so embedder can write more data.
-            mMessageLoop.postQuitTask();
+            mMessageLoop.quit();
         }
         uploadDataSink.onReadSucceeded(false);
     }
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java
index bed68b04..c1123d6d 100644
--- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java
+++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java
@@ -426,14 +426,14 @@
         public void onResponseStarted(UrlRequest request, ResponseInfo info) {
             mResponseInfo = info;
             // Quits the message loop since we have the headers now.
-            mMessageLoop.postQuitTask();
+            mMessageLoop.quit();
         }
 
         @Override
         public void onReadCompleted(UrlRequest request, ResponseInfo info,
                 ByteBuffer byteBuffer) {
             mResponseInfo = info;
-            mMessageLoop.postQuitTask();
+            mMessageLoop.quit();
         }
 
         @Override
@@ -480,7 +480,7 @@
             if (mInputStream != null) {
                 mInputStream.setResponseDataCompleted();
             }
-            mMessageLoop.postQuitTask();
+            mMessageLoop.quit();
         }
     }
 
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java
index 9bad57b..f3d376c 100644
--- a/components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java
+++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java
@@ -16,9 +16,6 @@
 class MessageLoop implements Executor {
     private final BlockingQueue<Runnable> mQueue;
 
-    // A reusable runnable to quit the message loop.
-    private final Runnable mQuitTask;
-
     // Indicates whether this message loop is currently running.
     private boolean mLoopRunning = false;
 
@@ -28,23 +25,30 @@
     // task enqueued.
     private boolean mLoopFailed = false;
 
+    // Used when assertions are enabled to enforce single-threaded use.
+    private static final long INVALID_THREAD_ID = -1;
+    private long mThreadId = INVALID_THREAD_ID;
+
     MessageLoop() {
         mQueue = new LinkedBlockingQueue<Runnable>();
-        mQuitTask = new Runnable() {
-            @Override
-            public void run() {
-                mLoopRunning = false;
-            }
-        };
+    }
+
+    private boolean calledOnValidThread() {
+        if (mThreadId == INVALID_THREAD_ID) {
+            mThreadId = Thread.currentThread().getId();
+            return true;
+        }
+        return mThreadId == Thread.currentThread().getId();
     }
 
     /**
-     * Runs the message loop. Be sure to call {@link MessageLoop#postQuitTask()}
+     * Runs the message loop. Be sure to call {@link MessageLoop#quit()}
      * to end the loop. If an interruptedException occurs, the loop cannot be
      * started again (see {@link #mLoopFailed}).
      * @throws IOException
      */
     public void loop() throws IOException {
+        assert calledOnValidThread();
         if (mLoopFailed) {
             throw new IllegalStateException(
                     "Cannot run loop as an exception has occurred previously.");
@@ -71,12 +75,13 @@
     }
 
     /**
-     * Posts a reusable runnable, {@link #mQuitTask} to quit the loop. This
-     * causes the {@link #loop()} to stop after processing all currently
-     * enqueued messages.
+     * This causes {@link #loop()} to stop executing messages after the current
+     * message being executed.  Should only be called from the currently
+     * executing message.
      */
-    public void postQuitTask() {
-        execute(mQuitTask);
+    public void quit() {
+        assert calledOnValidThread();
+        mLoopRunning = false;
     }
 
     /**
diff --git a/components/cronet/android/test/assets/test/content_length_mismatch.html b/components/cronet/android/test/assets/test/content_length_mismatch.html
new file mode 100644
index 0000000..f883f8f
--- /dev/null
+++ b/components/cronet/android/test/assets/test/content_length_mismatch.html
@@ -0,0 +1 @@
+Response that lies about content length.
\ No newline at end of file
diff --git a/components/cronet/android/test/assets/test/content_length_mismatch.html.mock-http-headers b/components/cronet/android/test/assets/test/content_length_mismatch.html.mock-http-headers
new file mode 100644
index 0000000..b10b621
--- /dev/null
+++ b/components/cronet/android/test/assets/test/content_length_mismatch.html.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: text/html
+Content-Length: 1000000
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
index 83a3b0f..7bd5982 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
@@ -8,7 +8,6 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.test.ActivityInstrumentationTestCase2;
-import android.text.TextUtils;
 
 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
 
@@ -77,7 +76,7 @@
         // Make sure the activity was created as expected.
         assertNotNull(getActivity());
         try {
-            waitForActiveShellToBeDoneLoading();
+            waitForActivityToBeDoneLoading();
         } catch (Throwable e) {
             fail("Test activity has failed to load.");
         }
@@ -94,41 +93,26 @@
     }
 
     /**
-     * Waits for the Active shell to finish loading. This times out after
-     * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be
-     * used for long loading pages. Instead it should be used more for test
-     * initialization. The proper way to wait is to use a
-     * TestCallbackHelperContainer after the initial load is completed.
+     * Waits for the Activity to finish loading. This times out after
+     * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds.
      *
      * @return Whether or not the Shell was actually finished loading.
      * @throws InterruptedException
      */
-    private boolean waitForActiveShellToBeDoneLoading()
+    private boolean waitForActivityToBeDoneLoading()
             throws InterruptedException {
         final CronetTestActivity activity = getActivity();
 
-        // Wait for the Content Shell to be initialized.
+        // Wait for the Activity to load.
         return CriteriaHelper.pollForCriteria(new Criteria() {
-                @Override
+            @Override
             public boolean isSatisfied() {
                 try {
                     final AtomicBoolean isLoaded = new AtomicBoolean(false);
                     runTestOnUiThread(new Runnable() {
-                            @Override
+                        @Override
                         public void run() {
-                            if (activity != null) {
-                                // There are two cases here that need to be
-                                // accounted for.
-                                // The first is that we've just created a Shell
-                                // and it isn't
-                                // loading because it has no URL set yet. The
-                                // second is that
-                                // we've set a URL and it actually is loading.
-                                isLoaded.set(!activity.isLoading() && !TextUtils
-                                        .isEmpty(activity.getUrl()));
-                            } else {
-                                isLoaded.set(false);
-                            }
+                            isLoaded.set(activity != null && !activity.isLoading());
                         }
                     });
 
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
index 87c6499..e9aa7219 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -191,6 +191,32 @@
         assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED);
     }
 
+    // Checks that UrlRequestListener.onFailed is only called once in the case
+    // of ERR_CONTENT_LENGTH_MISMATCH, which has an unusual failure path.
+    // See http://crbug.com/468803.
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testContentLengthMismatchFailsOnce() throws Exception {
+        String url = NativeTestServer.getFileURL(
+                "/content_length_mismatch.html");
+        TestUrlRequestListener listener = startAndWaitForComplete(url);
+        assertEquals(200, listener.mResponseInfo.getHttpStatusCode());
+        // The entire response body will be read before the error is returned.
+        // This is because the network stack returns data as it's read from the
+        // socket, and the socket close message which tiggers the error will
+        // only be passed along after all data has been read.
+        assertEquals("Response that lies about content length.",
+                listener.mResponseAsString);
+        assertNotNull(listener.mError);
+        assertEquals(
+                "Exception in CronetUrlRequest: net::ERR_CONTENT_LENGTH_MISMATCH",
+                listener.mError.getMessage());
+        // Wait for a couple round trips to make sure there are no pending
+        // onFailed messages. This test relies on checks in
+        // TestUrlRequestListener catching a second onFailed call.
+        testSimpleGet();
+    }
+
     @SmallTest
     @Feature({"Cronet"})
     public void testSetHttpMethod() throws Exception {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestListener.java b/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestListener.java
index cd4363e..db9583f3 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestListener.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestListener.java
@@ -7,6 +7,7 @@
 import android.os.ConditionVariable;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
@@ -172,7 +173,7 @@
         assertEquals(mExecutorThread, Thread.currentThread());
         assertTrue(mResponseStep == ResponseStep.ON_RESPONSE_STARTED
                    || mResponseStep == ResponseStep.ON_READ_COMPLETED);
-        assertTrue(mError == null);
+        assertNull(mError);
 
         mResponseStep = ResponseStep.ON_SUCCEEDED;
         mExtendedResponseInfo = info;
@@ -187,6 +188,9 @@
         assertEquals(mExecutorThread, Thread.currentThread());
         // Shouldn't happen after success.
         assertTrue(mResponseStep != ResponseStep.ON_SUCCEEDED);
+        // Should happen at most once for a single request.
+        assertFalse(mOnErrorCalled);
+        assertNull(mError);
 
         mOnErrorCalled = true;
         mError = error;
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetBufferedOutputStreamTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetBufferedOutputStreamTest.java
index d0d1a8c..698be48 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetBufferedOutputStreamTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetBufferedOutputStreamTest.java
@@ -353,6 +353,8 @@
         try {
             // Write remaining bytes.
             out.write(UPLOAD_DATA, 3, UPLOAD_DATA.length - 3);
+            // On Lollipop, default implementation only triggers the error when reading response.
+            connection.getInputStream();
             fail();
         } catch (ProtocolException e) {
             assertEquals("exceeded content-length limit of "
@@ -381,6 +383,8 @@
             for (int i = 0; i < UPLOAD_DATA.length; i++) {
                 out.write(UPLOAD_DATA[i]);
             }
+            // On Lollipop, default implementation only triggers the error when reading response.
+            connection.getInputStream();
             fail();
         } catch (java.net.ProtocolException e) {
             assertEquals("exceeded content-length limit of "
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetFixedModeOutputStreamTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetFixedModeOutputStreamTest.java
index c2b7e45..be00a662 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetFixedModeOutputStreamTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetFixedModeOutputStreamTest.java
@@ -133,6 +133,8 @@
         OutputStream out = connection.getOutputStream();
         try {
             out.write(UPLOAD_DATA);
+            // On Lollipop, default implementation only triggers the error when reading response.
+            connection.getInputStream();
             fail();
         } catch (ProtocolException e) {
             // Expected.
@@ -162,10 +164,16 @@
         try {
             // Try upload an extra byte.
             out.write(UPLOAD_DATA[UPLOAD_DATA.length - 1]);
+            // On Lollipop, default implementation only triggers the error when reading response.
+            connection.getInputStream();
             fail();
         } catch (ProtocolException e) {
             // Expected.
-            assertEquals("expected 0 bytes but received 1", e.getMessage());
+            String expectedVariant = "expected 0 bytes but received 1";
+            String expectedVariantOnLollipop = "expected " + (UPLOAD_DATA.length - 1)
+                    + " bytes but received " + UPLOAD_DATA.length;
+            assertTrue(expectedVariant.equals(e.getMessage())
+                    || expectedVariantOnLollipop.equals(e.getMessage()));
         }
         connection.disconnect();
     }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/MessageLoopTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/MessageLoopTest.java
index b2e5fd9..b480967 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/MessageLoopTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/MessageLoopTest.java
@@ -10,18 +10,32 @@
 import org.chromium.net.CronetTestBase;
 
 import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
 
 /**
  * Tests the MessageLoop implementation.
  */
 public class MessageLoopTest extends CronetTestBase {
+    private Thread mTestThread;
+    private final ExecutorService mExecutorService =
+            Executors.newSingleThreadExecutor(new ExecutorThreadFactory());
+    private class ExecutorThreadFactory implements ThreadFactory {
+        public Thread newThread(Runnable r) {
+            mTestThread = new Thread(r);
+            return mTestThread;
+        }
+    }
+    private boolean mFailed = false;
 
     @SmallTest
     @Feature({"Cronet"})
     public void testInterrupt() throws Exception {
         final MessageLoop loop = new MessageLoop();
         assertFalse(loop.isRunning());
-        TestThread thread = new TestThread() {
+        Future future = mExecutorService.submit(new Runnable() {
             @Override
             public void run() {
                 try {
@@ -31,23 +45,29 @@
                     // Expected interrupt.
                 }
             }
-        };
-        thread.start();
+        });
         Thread.sleep(1000);
         assertTrue(loop.isRunning());
         assertFalse(loop.hasLoopFailed());
-        thread.interrupt();
-        Thread.sleep(1000);
+        mTestThread.interrupt();
+        future.get();
         assertFalse(loop.isRunning());
         assertTrue(loop.hasLoopFailed());
-        assertFalse(thread.mFailed);
+        assertFalse(mFailed);
         // Re-spinning the message loop is not allowed after interrupt.
-        try {
-            loop.loop();
-            fail();
-        } catch (IllegalStateException e) {
-            // Expected.
-        }
+        mExecutorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    loop.loop();
+                    fail();
+                } catch (Exception e) {
+                    if (!(e instanceof IllegalStateException)) {
+                        fail();
+                    }
+                }
+            }
+        }).get();
     }
 
     @SmallTest
@@ -55,7 +75,7 @@
     public void testTaskFailed() throws Exception {
         final MessageLoop loop = new MessageLoop();
         assertFalse(loop.isRunning());
-        TestThread thread = new TestThread() {
+        Future future = mExecutorService.submit(new Runnable() {
             @Override
             public void run() {
                 try {
@@ -67,44 +87,34 @@
                     }
                 }
             }
-        };
+        });
         Runnable failedTask = new Runnable() {
             @Override
             public void run() {
                 throw new NullPointerException();
             }
         };
-        thread.start();
         Thread.sleep(1000);
         assertTrue(loop.isRunning());
         assertFalse(loop.hasLoopFailed());
         loop.execute(failedTask);
-        Thread.sleep(1000);
+        future.get();
         assertFalse(loop.isRunning());
         assertTrue(loop.hasLoopFailed());
-        assertFalse(thread.mFailed);
+        assertFalse(mFailed);
         // Re-spinning the message loop is not allowed after exception.
-        try {
-            loop.loop();
-            fail();
-        } catch (IllegalStateException e) {
-            // Expected.
-        }
-    }
-
-    /**
-     * A Thread class to move assertion to the main thread, so findbug
-     * won't complain.
-     */
-    private class TestThread extends Thread {
-        boolean mFailed = false;
-
-        public TestThread() {
-        }
-
-        @Override
-        public void run() {
-            throw new IllegalStateException();
-        }
+        mExecutorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    loop.loop();
+                    fail();
+                } catch (Exception e) {
+                    if (!(e instanceof IllegalStateException)) {
+                        fail();
+                    }
+                }
+            }
+        }).get();
     }
 }
diff --git a/components/cronet/android/test/quic_test_server.cc b/components/cronet/android/test/quic_test_server.cc
index ff0b859e..f4b14f96 100644
--- a/components/cronet/android/test/quic_test_server.cc
+++ b/components/cronet/android/test/quic_test_server.cc
@@ -26,8 +26,7 @@
 net::tools::QuicSimpleServer* g_quic_server = nullptr;
 
 void ServeFilesFromDirectory(
-    const base::FilePath& directory,
-    base::android::ScopedJavaGlobalRef<jobject>* callback) {
+    const base::FilePath& directory) {
   DCHECK(g_quic_server_thread->task_runner()->BelongsToCurrentThread());
   DCHECK(!g_quic_server);
   base::FilePath file_dir = directory.Append("quic_data");
@@ -41,7 +40,7 @@
   int rv = g_quic_server->Listen(net::IPEndPoint(ip, kServerPort));
   CHECK_GE(rv, 0) << "Quic server fails to start";
   JNIEnv* env = base::android::AttachCurrentThread();
-  Java_QuicTestServer_onServerStarted(env, callback->obj());
+  Java_QuicTestServer_onServerStarted(env);
 }
 
 void ShutdownOnServerThread() {
@@ -55,7 +54,7 @@
 // Quic server is currently hardcoded to run on port 6121 of the localhost on
 // the device.
 void StartQuicTestServer(JNIEnv* env,
-                         jclass jcaller,
+                         jclass /*jcaller*/,
                          jstring jtest_files_root) {
   DCHECK(!g_quic_server_thread);
   g_quic_server_thread = new base::Thread("quic server thread");
@@ -65,26 +64,22 @@
   DCHECK(started);
   base::FilePath test_files_root(
       base::android::ConvertJavaStringToUTF8(env, jtest_files_root));
-  base::android::ScopedJavaGlobalRef<jobject>* callback =
-      new base::android::ScopedJavaGlobalRef<jobject>();
-  callback->Reset(env, jcaller);
   g_quic_server_thread->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&ServeFilesFromDirectory, test_files_root,
-                            base::Owned(callback)));
+      FROM_HERE, base::Bind(&ServeFilesFromDirectory, test_files_root));
 }
 
-void ShutdownQuicTestServer(JNIEnv* env, jclass jcaller) {
+void ShutdownQuicTestServer(JNIEnv* env, jclass /*jcaller*/) {
   DCHECK(!g_quic_server_thread->task_runner()->BelongsToCurrentThread());
   g_quic_server_thread->task_runner()->PostTask(
       FROM_HERE, base::Bind(&ShutdownOnServerThread));
   delete g_quic_server_thread;
 }
 
-jstring GetServerHost(JNIEnv* env, jclass jcaller) {
+jstring GetServerHost(JNIEnv* env, jclass /*jcaller*/) {
   return base::android::ConvertUTF8ToJavaString(env, kServerHost).Release();
 }
 
-int GetServerPort(JNIEnv* env, jclass jcaller) {
+int GetServerPort(JNIEnv* env, jclass /*jcaller*/) {
   return kServerPort;
 }
 
diff --git a/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java b/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
index 78fbfde7..8d3102c5 100644
--- a/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
+++ b/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
@@ -40,7 +40,7 @@
     }
 
     @CalledByNative
-    private void onServerStarted() {
+    private static void onServerStarted() {
         sBlock.open();
     }
 
diff --git a/components/cronet/android/url_request_context_adapter.cc b/components/cronet/android/url_request_context_adapter.cc
index 45ed5fb8..8fc3e02 100644
--- a/components/cronet/android/url_request_context_adapter.cc
+++ b/components/cronet/android/url_request_context_adapter.cc
@@ -199,8 +199,9 @@
 
   if (VLOG_IS_ON(2)) {
     net_log_observer_.reset(new NetLogObserver());
-    context_->net_log()->DeprecatedAddObserver(net_log_observer_.get(),
-                                               net::NetLog::LOG_ALL_BUT_BYTES);
+    context_->net_log()->DeprecatedAddObserver(
+        net_log_observer_.get(),
+        net::NetLogCaptureMode::IncludeCookiesAndCredentials());
   }
 
   is_context_initialized_ = true;
diff --git a/components/data_reduction_proxy.gypi b/components/data_reduction_proxy.gypi
index 8f5c4a0..1a8bf6d 100644
--- a/components/data_reduction_proxy.gypi
+++ b/components/data_reduction_proxy.gypi
@@ -147,6 +147,9 @@
         'data_reduction_proxy/core/common/data_reduction_proxy_client_config_parser.cc',
         'data_reduction_proxy/core/common/data_reduction_proxy_client_config_parser.h',
         'data_reduction_proxy/core/common/data_reduction_proxy_config_values.h',
+        'data_reduction_proxy/core/common/data_reduction_proxy_event_creator.cc',
+        'data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h',
+        'data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h',
         'data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc',
         'data_reduction_proxy/core/common/data_reduction_proxy_event_store.h',
         'data_reduction_proxy/core/common/data_reduction_proxy_headers.cc',
@@ -186,6 +189,8 @@
         'data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h',
         'data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc',
         'data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h',
+        'data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.cc',
+        'data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h',
         'data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.cc',
         'data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h',
         'data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc',
diff --git a/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_resource_throttle.cc b/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_resource_throttle.cc
index cc340ca1e..1b00b19 100644
--- a/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_resource_throttle.cc
+++ b/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_resource_throttle.cc
@@ -45,7 +45,7 @@
 void DataReductionProxyDebugResourceThrottle::StartDisplayingBlockingPage(
     scoped_refptr<DataReductionProxyDebugUIManager> ui_manager,
     const DataReductionProxyDebugUIManager::BypassResource& resource) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   ui_manager->DisplayBlockingPage(resource);
 }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
index cd9c1c3..cdb3e30 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
@@ -8,7 +8,7 @@
 #include "base/time/time.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "net/base/load_flags.h"
@@ -70,10 +70,10 @@
 
 DataReductionProxyBypassProtocol::DataReductionProxyBypassProtocol(
     DataReductionProxyConfig* config,
-    DataReductionProxyEventStore* event_store)
-    : config_(config), event_store_(event_store) {
+    DataReductionProxyEventCreator* event_creator)
+    : config_(config), event_creator_(event_creator) {
   DCHECK(config_);
-  DCHECK(event_store_);
+  DCHECK(event_creator_);
   net::NetworkChangeNotifier::AddIPAddressObserver(this);
 }
 
@@ -128,10 +128,9 @@
   // command was sent via the data reduction proxy headers
   bool event_logged = false;
   DataReductionProxyInfo data_reduction_proxy_info;
-  DataReductionProxyBypassType bypass_type =
-      GetDataReductionProxyBypassType(
-          response_headers, request->url(), request->net_log(),
-          &data_reduction_proxy_info, event_store_, &event_logged);
+  DataReductionProxyBypassType bypass_type = GetDataReductionProxyBypassType(
+      response_headers, request->url(), request->net_log(),
+      &data_reduction_proxy_info, event_creator_, &event_logged);
 
   if (bypass_type == BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER) {
     if (DataReductionProxyParams::
@@ -155,7 +154,7 @@
     return false;
 
   if (!event_logged) {
-    event_store_->AddBypassTypeEvent(
+    event_creator_->AddBypassTypeEvent(
         request->net_log(), bypass_type, request->url(),
         data_reduction_proxy_info.bypass_duration);
   }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h
index 44ffbc7..49111c8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h
@@ -18,7 +18,7 @@
 namespace data_reduction_proxy {
 
 class DataReductionProxyConfig;
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 
 // Class responsible for determining when a response should or should not cause
 // the data reduction proxy to be bypassed, and to what degree. Owned by the
@@ -27,9 +27,10 @@
     : public net::NetworkChangeNotifier::IPAddressObserver {
  public:
   // Constructs a DataReductionProxyBypassProtocol object. |config| and
-  // |event_store| must be non-NULL and outlive |this|.
-  DataReductionProxyBypassProtocol(DataReductionProxyConfig* config,
-                                   DataReductionProxyEventStore* event_store);
+  // |event_creator| must be non-NULL and outlive |this|.
+  DataReductionProxyBypassProtocol(
+      DataReductionProxyConfig* config,
+      DataReductionProxyEventCreator* event_creator);
 
   ~DataReductionProxyBypassProtocol() override;
 
@@ -54,7 +55,7 @@
   DataReductionProxyConfig* config_;
 
   // Must outlive |this|.
-  DataReductionProxyEventStore* event_store_;
+  DataReductionProxyEventCreator* event_creator_;
 
   // The set of data reduction proxies through which a response has come back
   // with the data reduction proxy via header since the last network change.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
index c638bdd8..0934c3e6 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
@@ -116,7 +116,7 @@
     DataReductionProxyInterceptor* interceptor =
         new DataReductionProxyInterceptor(test_context_->config(),
                                           bypass_stats_.get(),
-                                          test_context_->event_store());
+                                          test_context_->event_creator());
     scoped_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
         new net::URLRequestJobFactoryImpl());
     job_factory_.reset(new net::URLRequestInterceptingJobFactory(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index 6e9f2a5..9b9ba22 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -6,16 +6,17 @@
 
 #include <string>
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_util.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "net/base/load_flags.h"
-#include "net/http/http_network_layer.h"
 #include "net/proxy/proxy_server.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
@@ -53,42 +54,21 @@
 // Checks if the secure proxy is allowed by the carrier by sending a probe.
 class SecureProxyChecker : public net::URLFetcherDelegate {
  public:
-  SecureProxyChecker(net::URLRequestContext* url_request_context,
-                     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
-      : io_task_runner_(io_task_runner) {
-    DCHECK(io_task_runner_->BelongsToCurrentThread());
-
-    url_request_context_.reset(new net::URLRequestContext());
-    url_request_context_->CopyFrom(url_request_context);
-
-    net::HttpNetworkSession::Params params_modified =
-        *(url_request_context_->GetNetworkSessionParams());
-    params_modified.enable_quic = false;
-    params_modified.next_protos = net::NextProtosWithSpdyAndQuic(false, false);
-
-    http_network_layer_.reset(new net::HttpNetworkLayer(
-        new net::HttpNetworkSession(params_modified)));
-    url_request_context_->set_http_transaction_factory(
-        http_network_layer_.get());
-
-    url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
-        url_request_context_.get(), io_task_runner_);
-  }
+  SecureProxyChecker(net::URLRequestContextGetter* url_request_context_getter)
+      : url_request_context_getter_(url_request_context_getter) {}
 
   void OnURLFetchComplete(const net::URLFetcher* source) override {
-    DCHECK(io_task_runner_->BelongsToCurrentThread());
     DCHECK_EQ(source, fetcher_.get());
     net::URLRequestStatus status = source->GetStatus();
 
     std::string response;
     source->GetResponseAsString(&response);
 
-    fetcher_callback_.Run(response, status);
+    fetcher_callback_.Run(response, status, source->GetResponseCode());
   }
 
   void CheckIfSecureProxyIsAllowed(const GURL& secure_proxy_check_url,
                                    FetcherResponseCallback fetcher_callback) {
-    DCHECK(io_task_runner_->BelongsToCurrentThread());
     fetcher_.reset(net::URLFetcher::Create(secure_proxy_check_url,
                                            net::URLFetcher::GET, this));
     fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY);
@@ -111,11 +91,7 @@
   ~SecureProxyChecker() override {}
 
  private:
-  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-  scoped_ptr<net::URLRequestContext> url_request_context_;
-  scoped_ptr<net::HttpNetworkLayer> http_network_layer_;
 
   // The URLFetcher being used for the secure proxy check.
   scoped_ptr<net::URLFetcher> fetcher_;
@@ -129,7 +105,7 @@
     net::NetLog* net_log,
     scoped_ptr<DataReductionProxyConfigValues> config_values,
     DataReductionProxyConfigurator* configurator,
-    DataReductionProxyEventStore* event_store)
+    DataReductionProxyEventCreator* event_creator)
     : restricted_by_carrier_(false),
       disabled_on_vpn_(false),
       unreachable_(false),
@@ -139,11 +115,11 @@
       io_task_runner_(io_task_runner),
       net_log_(net_log),
       configurator_(configurator),
-      event_store_(event_store),
+      event_creator_(event_creator),
       url_request_context_getter_(nullptr) {
   DCHECK(io_task_runner);
   DCHECK(configurator);
-  DCHECK(event_store);
+  DCHECK(event_creator);
 }
 
 DataReductionProxyConfig::~DataReductionProxyConfig() {
@@ -396,11 +372,14 @@
 }
 
 void DataReductionProxyConfig::HandleSecureProxyCheckResponse(
-    const std::string& response, const net::URLRequestStatus& status) {
+    const std::string& response,
+    const net::URLRequestStatus& status,
+    int http_response_code) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
-  if (event_store_) {
-    event_store_->EndSecureProxyCheck(bound_net_log_, status.error());
-  }
+  bool success_response = ("OK" == response.substr(0, 2));
+  if (event_creator_)
+    event_creator_->EndSecureProxyCheck(bound_net_log_, status.error(),
+                                        http_response_code, success_response);
 
   if (status.status() == net::URLRequestStatus::FAILED) {
     if (status.error() == net::ERR_INTERNET_DISCONNECTED) {
@@ -414,7 +393,7 @@
                                 std::abs(status.error()));
   }
 
-  if ("OK" == response.substr(0, 2)) {
+  if (success_response) {
     DVLOG(1) << "The data reduction proxy is unrestricted.";
 
     if (enabled_by_user_) {
@@ -508,16 +487,14 @@
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   bound_net_log_ = net::BoundNetLog::Make(
       net_log_, net::NetLog::SOURCE_DATA_REDUCTION_PROXY);
-
-  if (event_store_) {
-    event_store_->BeginSecureProxyCheck(
+  if (event_creator_) {
+    event_creator_->BeginSecureProxyCheck(
         bound_net_log_, config_values_->secure_proxy_check_url());
   }
 
   if (!secure_proxy_checker_) {
-    DCHECK(url_request_context_getter_->GetURLRequestContext());
-    secure_proxy_checker_.reset(new SecureProxyChecker(
-        url_request_context_getter_->GetURLRequestContext(), io_task_runner_));
+    secure_proxy_checker_.reset(
+        new SecureProxyChecker(url_request_context_getter_));
   }
   secure_proxy_checker_->CheckIfSecureProxyIsAllowed(secure_proxy_check_url,
                                                      fetcher_callback);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
index 9acf691a..4499ee42 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -38,12 +38,13 @@
 
 namespace data_reduction_proxy {
 
-typedef base::Callback<void(const std::string&, const net::URLRequestStatus&)>
-    FetcherResponseCallback;
+typedef base::Callback<void(const std::string&,
+                            const net::URLRequestStatus&,
+                            int)> FetcherResponseCallback;
 
 class DataReductionProxyConfigValues;
 class DataReductionProxyConfigurator;
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 class DataReductionProxyService;
 class SecureProxyChecker;
 struct DataReductionProxyTypeInfo;
@@ -81,14 +82,19 @@
     : public net::NetworkChangeNotifier::IPAddressObserver {
  public:
   // The caller must ensure that all parameters remain alive for the lifetime
-  // of the |DataReductionProxyConfig| instance, with the exception of |params|
-  // which this instance will own.
+  // of the |DataReductionProxyConfig| instance, with the exception of
+  // |config_values| which is owned by |this|. |io_task_runner| is used to
+  // validate calls on the correct thread. |event_creator| is used for logging
+  // the start and end of a secure proxy check; |net_log| is used to create a
+  // net::BoundNetLog for correlating the start and end of the check.
+  // |config_values| contains the Data Reduction Proxy configuration values.
+  // |configurator| is the target for a configuration update.
   DataReductionProxyConfig(
       scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
       net::NetLog* net_log,
       scoped_ptr<DataReductionProxyConfigValues> config_values,
       DataReductionProxyConfigurator* configurator,
-      DataReductionProxyEventStore* event_store);
+      DataReductionProxyEventCreator* event_creator);
   ~DataReductionProxyConfig() override;
 
   // Performs initialization on the IO thread.
@@ -229,8 +235,9 @@
 
   // Parses the secure proxy check responses and appropriately configures the
   // Data Reduction Proxy rules.
-  virtual void HandleSecureProxyCheckResponse(
-      const std::string& response, const net::URLRequestStatus& status);
+  void HandleSecureProxyCheckResponse(const std::string& response,
+                                      const net::URLRequestStatus& status,
+                                      int http_response_code);
 
   // Adds the default proxy bypass rules for the Data Reduction Proxy.
   void AddDefaultProxyBypassRules();
@@ -278,8 +285,8 @@
   // The caller must ensure that the |configurator_| outlives this instance.
   DataReductionProxyConfigurator* configurator_;
 
-  // The caller must ensure that the |event_store_| outlives this instance.
-  DataReductionProxyEventStore* event_store_;
+  // The caller must ensure that the |event_creator_| outlives this instance.
+  DataReductionProxyEventCreator* event_creator_;
 
   // Used for performing the secure proxy check.
   net::URLRequestContextGetter* url_request_context_getter_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
index af4c571..67728a9 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
@@ -9,6 +9,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/command_line.h"
 #include "base/json/json_writer.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -19,14 +20,22 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_client_config_parser.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/data_reduction_proxy/proto/client_config.pb.h"
 #include "net/base/host_port_pair.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_status_code.h"
 #include "net/proxy/proxy_server.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request_status.h"
 
 namespace data_reduction_proxy {
 
 namespace {
 
+// Default URL for retrieving the Data Reduction Proxy configuration.
+const char kClientConfigURL[] = "";
+
 // This is the default backoff policy used to communicate with the Data
 // Reduction Proxy configuration service.
 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
@@ -80,6 +89,23 @@
   return kDefaultBackoffPolicy;
 }
 
+// static
+GURL DataReductionProxyConfigServiceClient::GetConfigServiceURL(
+    const base::CommandLine& command_line) {
+  if (!command_line.HasSwitch(switches::kDataReductionProxyConfigURL))
+    return GURL(kClientConfigURL);
+
+  std::string value(
+      command_line.GetSwitchValueASCII(switches::kDataReductionProxyConfigURL));
+  GURL result(value);
+  if (result.is_valid())
+    return result;
+
+  LOG(WARNING) << "The following client config URL specified at the "
+               << "command-line is invalid: " << value;
+  return GURL(kClientConfigURL);
+}
+
 DataReductionProxyConfigServiceClient::DataReductionProxyConfigServiceClient(
     scoped_ptr<DataReductionProxyParams> params,
     const net::BackoffEntry::Policy& backoff_policy,
@@ -90,7 +116,11 @@
       request_options_(request_options),
       config_values_(config_values),
       config_(config),
-      backoff_entry_(&backoff_policy) {
+      backoff_entry_(&backoff_policy),
+      config_service_url_(
+          GetConfigServiceURL(*base::CommandLine::ForCurrentProcess())),
+      use_local_config_(!config_service_url_.is_valid()),
+      url_request_context_getter_(nullptr) {
   DCHECK(request_options);
   DCHECK(config_values);
   DCHECK(config);
@@ -100,47 +130,24 @@
 
 DataReductionProxyConfigServiceClient::
     ~DataReductionProxyConfigServiceClient() {
+  net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
+}
+
+void DataReductionProxyConfigServiceClient::InitializeOnIOThread(
+    net::URLRequestContextGetter* url_request_context_getter) {
+  DCHECK(url_request_context_getter);
+  net::NetworkChangeNotifier::AddIPAddressObserver(this);
+  url_request_context_getter_ = url_request_context_getter;
 }
 
 void DataReductionProxyConfigServiceClient::RetrieveConfig() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  std::string static_response = ConstructStaticResponse();
-  ClientConfig config;
-  bool succeeded = false;
-  if (config_parser::ParseClientConfig(static_response, &config)) {
-    if (config.has_proxy_config()) {
-      net::ProxyServer origin;
-      net::ProxyServer fallback_origin;
-      std::vector<net::ProxyServer> proxies =
-          GetProxiesForHTTP(config.proxy_config());
-      if (proxies.size() > 0) {
-        origin = proxies[0];
-        if (proxies.size() > 1)
-          fallback_origin = proxies[1];
-
-        std::string session;
-        std::string credentials;
-        if (DataReductionProxyRequestOptions::ParseLocalSessionKey(
-                config.session_key(), &session, &credentials)) {
-          request_options_->SetCredentials(session, credentials);
-          config_values_->UpdateValues(origin, fallback_origin);
-          config_->ReloadConfig();
-          succeeded = true;
-        }
-      }
-    }
+  if (use_local_config_) {
+    ReadAndApplyStaticConfig();
+    return;
   }
 
-  base::Time expiration_time;
-  if (succeeded) {
-    expiration_time = config_parser::TimestampToTime(config.expire_time());
-  }
-
-  GetBackoffEntry()->InformOfRequest(succeeded);
-  base::TimeDelta next_config_refresh_time =
-      CalculateNextConfigRefreshTime(succeeded, expiration_time, Now(),
-                                     GetBackoffEntry()->GetTimeUntilRelease());
-  SetConfigRefreshTimer(next_config_refresh_time);
+  RetrieveRemoteConfig();
 }
 
 net::BackoffEntry* DataReductionProxyConfigServiceClient::GetBackoffEntry() {
@@ -171,4 +178,114 @@
   return response;
 }
 
+void DataReductionProxyConfigServiceClient::OnIPAddressChanged() {
+  GetBackoffEntry()->Reset();
+  RetrieveConfig();
+}
+
+void DataReductionProxyConfigServiceClient::OnURLFetchComplete(
+    const net::URLFetcher* source) {
+  DCHECK(source == fetcher_.get());
+  net::URLRequestStatus status = source->GetStatus();
+  std::string response;
+  source->GetResponseAsString(&response);
+  HandleResponse(response, status, source->GetResponseCode());
+}
+
+void DataReductionProxyConfigServiceClient::ReadAndApplyStaticConfig() {
+  std::string static_response = ConstructStaticResponse();
+  HandleResponse(static_response, net::URLRequestStatus(), net::HTTP_OK);
+}
+
+void DataReductionProxyConfigServiceClient::RetrieveRemoteConfig() {
+  scoped_ptr<net::URLFetcher> fetcher =
+      GetURLFetcherForConfig(config_service_url_, std::string());
+  if (!fetcher.get()) {
+    HandleResponse(std::string(),
+                   net::URLRequestStatus(net::URLRequestStatus::CANCELED, 0),
+                   net::URLFetcher::RESPONSE_CODE_INVALID);
+    return;
+  }
+
+  fetcher_ = fetcher.Pass();
+  fetcher_->Start();
+}
+
+scoped_ptr<net::URLFetcher>
+DataReductionProxyConfigServiceClient::GetURLFetcherForConfig(
+    const GURL& secure_proxy_check_url,
+    const std::string& request_body) {
+  scoped_ptr<net::URLFetcher> fetcher(net::URLFetcher::Create(
+      secure_proxy_check_url, net::URLFetcher::POST, this));
+  fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY);
+  fetcher->SetUploadData("application/json", request_body);
+  DCHECK(url_request_context_getter_);
+  fetcher->SetRequestContext(url_request_context_getter_);
+  // Configure max retries to be at most kMaxRetries times for 5xx errors.
+  static const int kMaxRetries = 5;
+  fetcher->SetMaxRetriesOn5xx(kMaxRetries);
+  fetcher->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries);
+  return fetcher.Pass();
+}
+
+void DataReductionProxyConfigServiceClient::HandleResponse(
+    const std::string& config_data,
+    const net::URLRequestStatus& status,
+    int response_code) {
+  ClientConfig config;
+  bool succeeded = false;
+
+  if (status.status() == net::URLRequestStatus::SUCCESS &&
+      response_code == net::HTTP_OK &&
+      config_parser::ParseClientConfig(config_data, &config)) {
+    succeeded = ParseAndApplyProxyConfig(config);
+  }
+
+  base::Time expiration_time;
+  if (succeeded) {
+    expiration_time = config_parser::TimestampToTime(config.expire_time());
+  }
+
+  GetBackoffEntry()->InformOfRequest(succeeded);
+  base::TimeDelta next_config_refresh_time =
+      CalculateNextConfigRefreshTime(succeeded, expiration_time, Now(),
+                                     GetBackoffEntry()->GetTimeUntilRelease());
+  SetConfigRefreshTimer(next_config_refresh_time);
+}
+
+bool DataReductionProxyConfigServiceClient::ParseAndApplyProxyConfig(
+    const ClientConfig& config) {
+  if (!config.has_proxy_config())
+    return false;
+
+  std::vector<net::ProxyServer> proxies =
+      GetProxiesForHTTP(config.proxy_config());
+  if (proxies.empty())
+    return false;
+
+  net::ProxyServer origin = proxies[0];
+  net::ProxyServer fallback_origin;
+  if (proxies.size() > 1)
+    fallback_origin = proxies[1];
+
+  if (!use_local_config_) {
+    request_options_->SetSecureSession(config.session_key());
+    config_values_->UpdateValues(origin, fallback_origin);
+    config_->ReloadConfig();
+    return true;
+  }
+
+  std::string session;
+  std::string credentials;
+  if (!DataReductionProxyRequestOptions::ParseLocalSessionKey(
+          config.session_key(), &session, &credentials)) {
+    return false;
+  }
+
+  request_options_->SetCredentials(session, credentials);
+  config_values_->UpdateValues(origin, fallback_origin);
+  config_->ReloadConfig();
+  return true;
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
index 84878295..41b0424 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
@@ -13,18 +13,30 @@
 #include "base/threading/thread_checker.h"
 #include "base/timer/timer.h"
 #include "net/base/backoff_entry.h"
+#include "net/base/network_change_notifier.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace base {
+class CommandLine;
 class Time;
 class TimeDelta;
 }
 
+namespace net {
+class URLFetcher;
+class URLRequestContextGetter;
+class URLRequestStatus;
+}
+
 namespace data_reduction_proxy {
 
+class ClientConfig;
 class DataReductionProxyConfig;
 class DataReductionProxyMutableConfigValues;
 class DataReductionProxyParams;
 class DataReductionProxyRequestOptions;
+class DataReductionProxyService;
 
 // Retrieves the default net::BackoffEntry::Policy for the Data Reduction Proxy
 // configuration service client.
@@ -32,11 +44,19 @@
 
 // Retrieves the Data Reduction Proxy configuration from a remote service. This
 // object lives on the IO thread.
-class DataReductionProxyConfigServiceClient {
+// TODO(jeremyim): Rename the class to DataReductionProxyConfigGetter(?).
+class DataReductionProxyConfigServiceClient
+    : public net::NetworkChangeNotifier::IPAddressObserver,
+      public net::URLFetcherDelegate {
  public:
+  // Returns the URL from which the Data Reduction Proxy configuration should
+  // be retrieved.
+  static GURL GetConfigServiceURL(const base::CommandLine& command_line);
+
   // The caller must ensure that all parameters remain alive for the lifetime of
   // the |DataReductionProxyConfigClient|, with the exception of |params|
-  // which this instance will own.
+  // which this instance will own. The |io_task_runner| is used to enforce that
+  // configurations are applied on the IO thread.
   DataReductionProxyConfigServiceClient(
       scoped_ptr<DataReductionProxyParams> params,
       const net::BackoffEntry::Policy& backoff_policy,
@@ -44,9 +64,14 @@
       DataReductionProxyMutableConfigValues* config_values,
       DataReductionProxyConfig* config);
 
-  virtual ~DataReductionProxyConfigServiceClient();
+  ~DataReductionProxyConfigServiceClient() override;
 
-  // Request the retrieval of the Data Reduction Proxy configuration.
+  // Performs initialization on the IO thread.
+  void InitializeOnIOThread(
+      net::URLRequestContextGetter* url_request_context_getter);
+
+  // Request the retrieval of the Data Reduction Proxy configuration. This
+  // operation takes place asynchronously.
   void RetrieveConfig();
 
  protected:
@@ -54,24 +79,55 @@
   // Virtual for testing.
   virtual net::BackoffEntry* GetBackoffEntry();
 
-  // Sets a timer to determine when to next refresh the Data Reduction Proxy
-  // configuration.
-  // Virtual for testing.
-  virtual void SetConfigRefreshTimer(const base::TimeDelta& delay);
-
   // Returns the current time.
   // Virtual for testing.
   virtual base::Time Now();
 
+  // Sets a timer to determine when to next refresh the Data Reduction Proxy
+  // configuration.
+  void SetConfigRefreshTimer(const base::TimeDelta& delay);
+
   // Constructs a synthetic response based on |params_|.
-  // Virtual for testing.
-  virtual std::string ConstructStaticResponse() const;
+  std::string ConstructStaticResponse() const;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceClientTest,
                            TestConstructStaticResponse);
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceClientTest,
+                           OnIPAddressChange);
   friend class TestDataReductionProxyConfigServiceClient;
 
+  // Override of net::NetworkChangeNotifier::IPAddressObserver.
+  void OnIPAddressChanged() override;
+
+  // Override of net::URLFetcherDelegate.
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+  // Retrieves the Data Reduction Proxy configuration from |params_|.
+  void ReadAndApplyStaticConfig();
+
+  // Retrieves the Data Reduction Proxy configuration from a remote service.
+  void RetrieveRemoteConfig();
+
+  // Returns a fetcher to retrieve the Data Reduction Proxy configuration.
+  // |secure_proxy_check_url| is the url from which to retrieve the config.
+  // |request_body| is the request body sent to the configuration service.
+  scoped_ptr<net::URLFetcher> GetURLFetcherForConfig(
+      const GURL& secure_proxy_check_url,
+      const std::string& request_body);
+
+  // Handles the response from the remote Data Reduction Proxy configuration
+  // service. |response| is the response body, |status| is the
+  // |net::URLRequestStatus| of the response, and response_code is the HTTP
+  // response code (if available).
+  void HandleResponse(const std::string& response,
+                      const net::URLRequestStatus& status,
+                      int response_code);
+
+  // Parses out the proxy configuration portion of |config| and applies it to
+  // |config_| and |request_options_|.
+  bool ParseAndApplyProxyConfig(const ClientConfig& config);
+
   // Contains the static configuration data to use.
   scoped_ptr<DataReductionProxyParams> params_;
 
@@ -87,11 +143,25 @@
   // Used to calculate the backoff time on request failures.
   net::BackoffEntry backoff_entry_;
 
+  // The URL for retrieving the Data Reduction Proxy configuration.
+  GURL config_service_url_;
+
+  // Whether to use |params_| to obtain the Data Reduction Proxy configuration
+  // or the remote server specified by |config_service_url_|.
+  // TODO(jeremyim): Remove this as part of bug 479282.
+  bool use_local_config_;
+
+  // Used for setting up |fetcher_|.
+  net::URLRequestContextGetter* url_request_context_getter_;
+
   // An event that fires when it is time to refresh the Data Reduction Proxy
   // configuration.
   base::OneShotTimer<DataReductionProxyConfigServiceClient>
       config_refresh_timer_;
 
+  // A |net::URLFetcher| to retrieve the Data Reduction Proxy configuration.
+  scoped_ptr<net::URLFetcher> fetcher_;
+
   // Enforce usage on the IO thread.
   base::ThreadChecker thread_checker_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
index b72ee5746..19ec5f4 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/tick_clock.h"
 #include "base/values.h"
@@ -15,9 +16,28 @@
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_client_config_parser.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/data_reduction_proxy/proto/client_config.pb.h"
+#include "net/socket/socket_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+const char kSuccessResponse[] =
+    "{ \"sessionKey\": \"SecretSessionKey\", "
+    "\"expireTime\": \"1970-01-01T00:01:00.000Z\", "
+    "\"proxyConfig\": { \"httpProxyServers\": ["
+    "{ \"scheme\": \"HTTPS\", \"host\": \"origin.net\", \"port\": 443 },"
+    "{ \"scheme\": \"HTTP\", \"host\": \"fallback.net\", \"port\": 80 }"
+    "] } }";
+// The following values should match the ones in the response above.
+const char kSuccessOrigin[] = "https://origin.net:443";
+const char kSuccessFallback[] = "fallback.net:80";
+const char kSuccessSessionKey[] = "SecretSessionKey";
+
+}  // namespace
 
 namespace data_reduction_proxy {
 
@@ -50,6 +70,8 @@
 
 class DataReductionProxyConfigServiceClientTest : public testing::Test {
  protected:
+  DataReductionProxyConfigServiceClientTest() : context_(true) {}
+
   void SetUp() override {
     test_context_ =
         DataReductionProxyTestContext::Builder()
@@ -57,12 +79,15 @@
                              DataReductionProxyParams::kFallbackAllowed |
                              DataReductionProxyParams::kPromoAllowed)
             .WithParamsDefinitions(TestDataReductionProxyParams::HAS_EVERYTHING)
+            .WithURLRequestContext(&context_)
+            .WithMockClientSocketFactory(&mock_socket_factory_)
             .WithTestConfigurator()
             .WithMockRequestOptions()
             .WithTestConfigClient()
             .Build();
-    test_context_->test_config_client()->SetCustomReleaseTime(
-        base::TimeTicks::UnixEpoch());
+    context_.set_client_socket_factory(&mock_socket_factory_);
+    context_.Init();
+    ResetBackoffEntryReleaseTime();
     test_context_->test_config_client()->SetNow(base::Time::UnixEpoch());
   }
 
@@ -84,6 +109,18 @@
             test_context_->io_data()->config()));
   }
 
+  void ResetBackoffEntryReleaseTime() {
+    config_client()->SetCustomReleaseTime(base::TimeTicks::UnixEpoch());
+  }
+
+  void VerifyRemoteSuccess() {
+    EXPECT_EQ(base::TimeDelta::FromMinutes(1), config_client()->GetDelay());
+    EXPECT_EQ(kSuccessOrigin, configurator()->origin());
+    EXPECT_EQ(kSuccessFallback, configurator()->fallback_origin());
+    EXPECT_TRUE(configurator()->ssl_origin().empty());
+    EXPECT_EQ(kSuccessSessionKey, request_options()->GetSecureSession());
+  }
+
   DataReductionProxyParams* params() {
     return test_context_->test_params();
   }
@@ -104,7 +141,14 @@
     test_context_->RunUntilIdle();
   }
 
+  net::MockClientSocketFactory* mock_socket_factory() {
+    return &mock_socket_factory_;
+  }
+
  private:
+  net::TestURLRequestContext context_;
+  net::MockClientSocketFactory mock_socket_factory_;
+
   scoped_ptr<DataReductionProxyTestContext> test_context_;
   scoped_ptr<DataReductionProxyRequestOptions> request_options_;
 };
@@ -118,6 +162,8 @@
 }
 
 TEST_F(DataReductionProxyConfigServiceClientTest, SuccessfulLoop) {
+  // Use a local/static config.
+  config_client()->SetConfigServiceURL(GURL());
   RequestOptionsPopulator populator(
       base::Time::UnixEpoch() + base::TimeDelta::FromDays(1),
       base::TimeDelta::FromDays(1));
@@ -148,6 +194,8 @@
 }
 
 TEST_F(DataReductionProxyConfigServiceClientTest, SuccessfulLoopShortDuration) {
+  // Use a local/static config.
+  config_client()->SetConfigServiceURL(GURL());
   RequestOptionsPopulator populator(
       base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1),
       base::TimeDelta::FromSeconds(1));
@@ -168,6 +216,8 @@
 }
 
 TEST_F(DataReductionProxyConfigServiceClientTest, EnsureBackoff) {
+  // Use a local/static config.
+  config_client()->SetConfigServiceURL(GURL());
   SetDataReductionProxyEnabled(true);
   EXPECT_TRUE(configurator()->origin().empty());
   EXPECT_TRUE(configurator()->fallback_origin().empty());
@@ -188,6 +238,8 @@
 }
 
 TEST_F(DataReductionProxyConfigServiceClientTest, ConfigDisabled) {
+  // Use a local/static config.
+  config_client()->SetConfigServiceURL(GURL());
   RequestOptionsPopulator populator(
       base::Time::UnixEpoch() + base::TimeDelta::FromDays(1),
       base::TimeDelta::FromDays(1));
@@ -206,4 +258,133 @@
   EXPECT_EQ(base::TimeDelta::FromDays(1), config_client()->GetDelay());
 }
 
+TEST_F(DataReductionProxyConfigServiceClientTest, GetConfigServiceURL) {
+  const struct {
+    std::string flag_value;
+    GURL expected;
+  } tests[] = {
+      {
+       "", GURL(),
+      },
+      {
+       "http://configservice.chrome-test.com",
+       GURL("http://configservice.chrome-test.com"),
+      },
+  };
+
+  for (const auto& test : tests) {
+    // Reset all flags.
+    base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+        switches::kDataReductionProxyConfigURL, test.flag_value);
+    EXPECT_EQ(test.expected,
+              DataReductionProxyConfigServiceClient::GetConfigServiceURL(
+                  *base::CommandLine::ForCurrentProcess()));
+  }
+}
+
+TEST_F(DataReductionProxyConfigServiceClientTest, RemoteConfigSuccess) {
+  net::MockRead mock_reads[] = {
+      net::MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+      net::MockRead(kSuccessResponse),
+      net::MockRead(net::SYNCHRONOUS, net::OK),
+  };
+  net::StaticSocketDataProvider socket_data_provider(
+      mock_reads, arraysize(mock_reads), nullptr, 0);
+  mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);
+  config_client()->SetConfigServiceURL(GURL("http://configservice.com"));
+  SetDataReductionProxyEnabled(true);
+  EXPECT_TRUE(configurator()->origin().empty());
+  EXPECT_TRUE(configurator()->fallback_origin().empty());
+  EXPECT_TRUE(configurator()->ssl_origin().empty());
+  EXPECT_CALL(*request_options(), PopulateConfigResponse(testing::_)).Times(0);
+  config_client()->RetrieveConfig();
+  RunUntilIdle();
+  VerifyRemoteSuccess();
+}
+
+TEST_F(DataReductionProxyConfigServiceClientTest,
+       RemoteConfigSuccessAfterFailure) {
+  net::MockRead mock_reads_array[][3] = {
+      {
+       // Failure due to 404 error.
+       net::MockRead("HTTP/1.1 404 Not found\r\n\r\n"),
+       net::MockRead(""),
+       net::MockRead(net::SYNCHRONOUS, net::OK),
+      },
+      {
+       // Success.
+       net::MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+       net::MockRead(kSuccessResponse),
+       net::MockRead(net::SYNCHRONOUS, net::OK),
+      },
+  };
+
+  ScopedVector<net::SocketDataProvider> socket_data_providers;
+  for (net::MockRead* mock_reads : mock_reads_array) {
+    socket_data_providers.push_back(
+        new net::StaticSocketDataProvider(mock_reads, 3, nullptr, 0));
+    mock_socket_factory()->AddSocketDataProvider(socket_data_providers.back());
+  }
+
+  config_client()->SetConfigServiceURL(GURL("http://configservice.com"));
+  SetDataReductionProxyEnabled(true);
+  EXPECT_TRUE(configurator()->origin().empty());
+  EXPECT_TRUE(configurator()->fallback_origin().empty());
+  EXPECT_TRUE(configurator()->ssl_origin().empty());
+  EXPECT_CALL(*request_options(), PopulateConfigResponse(testing::_)).Times(0);
+  config_client()->RetrieveConfig();
+  RunUntilIdle();
+  EXPECT_EQ(base::TimeDelta::FromSeconds(20), config_client()->GetDelay());
+  EXPECT_TRUE(configurator()->origin().empty());
+  EXPECT_TRUE(configurator()->fallback_origin().empty());
+  EXPECT_TRUE(configurator()->ssl_origin().empty());
+  EXPECT_TRUE(request_options()->GetSecureSession().empty());
+  config_client()->RetrieveConfig();
+  RunUntilIdle();
+  VerifyRemoteSuccess();
+}
+
+TEST_F(DataReductionProxyConfigServiceClientTest, OnIPAddressChange) {
+  config_client()->SetConfigServiceURL(GURL("http://configservice.com"));
+  SetDataReductionProxyEnabled(true);
+  config_client()->RetrieveConfig();
+  EXPECT_CALL(*request_options(), PopulateConfigResponse(testing::_)).Times(0);
+
+  static const int kFailureCount = 5;
+
+  net::MockRead failure_reads[] = {
+      net::MockRead("HTTP/1.1 404 Not found\r\n\r\n"),
+      net::MockRead(""),
+      net::MockRead(net::SYNCHRONOUS, net::OK),
+  };
+
+  ScopedVector<net::SocketDataProvider> socket_data_providers;
+  for (int i = 0; i < kFailureCount; ++i) {
+    socket_data_providers.push_back(
+        new net::StaticSocketDataProvider(failure_reads, 3, nullptr, 0));
+    mock_socket_factory()->AddSocketDataProvider(socket_data_providers.back());
+    config_client()->RetrieveConfig();
+    RunUntilIdle();
+  }
+
+  EXPECT_EQ(base::TimeDelta::FromSeconds(320), config_client()->GetDelay());
+  EXPECT_EQ(kFailureCount, config_client()->GetBackoffErrorCount());
+  config_client()->OnIPAddressChanged();
+  EXPECT_EQ(0, config_client()->GetBackoffErrorCount());
+  ResetBackoffEntryReleaseTime();
+
+  net::MockRead success_reads[] = {
+      net::MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+      net::MockRead(kSuccessResponse),
+      net::MockRead(net::SYNCHRONOUS, net::OK),
+  };
+  net::StaticSocketDataProvider socket_data_provider(
+      success_reads, arraysize(success_reads), nullptr, 0);
+  mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);
+  config_client()->RetrieveConfig();
+  RunUntilIdle();
+  VerifyRemoteSuccess();
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
index dbbde520..43b5140 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
@@ -21,15 +21,15 @@
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     net::NetLog* net_log,
     DataReductionProxyConfigurator* configurator,
-    DataReductionProxyEventStore* event_store)
+    DataReductionProxyEventCreator* event_creator)
     : TestDataReductionProxyConfig(
-          make_scoped_ptr(
-              new TestDataReductionProxyParams(params_flags,
-                                               params_definitions)).Pass(),
+          make_scoped_ptr(new TestDataReductionProxyParams(params_flags,
+                                                           params_definitions))
+              .Pass(),
           task_runner,
           net_log,
           configurator,
-          event_store) {
+          event_creator) {
 }
 
 TestDataReductionProxyConfig::TestDataReductionProxyConfig(
@@ -37,12 +37,12 @@
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     net::NetLog* net_log,
     DataReductionProxyConfigurator* configurator,
-    DataReductionProxyEventStore* event_store)
+    DataReductionProxyEventCreator* event_creator)
     : DataReductionProxyConfig(task_runner,
                                net_log,
                                config_values.Pass(),
                                configurator,
-                               event_store) {
+                               event_creator) {
   network_interfaces_.reset(new net::NetworkInterfaceList());
 }
 
@@ -92,12 +92,12 @@
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     net::NetLog* net_log,
     DataReductionProxyConfigurator* configurator,
-    DataReductionProxyEventStore* event_store)
+    DataReductionProxyEventCreator* event_creator)
     : TestDataReductionProxyConfig(config_values.Pass(),
                                    task_runner,
                                    net_log,
                                    configurator,
-                                   event_store) {
+                                   event_creator) {
 }
 
 MockDataReductionProxyConfig::~MockDataReductionProxyConfig() {
@@ -112,9 +112,4 @@
                                                restricted, at_startup);
 }
 
-void MockDataReductionProxyConfig::HandleSecureProxyCheckResponse(
-    const std::string& response, const net::URLRequestStatus& status) {
-  DataReductionProxyConfig::HandleSecureProxyCheckResponse(response, status);
-}
-
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
index 759b29ce..a07dc59a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
@@ -22,7 +22,7 @@
 namespace data_reduction_proxy {
 
 class DataReductionProxyConfigurator;
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 class DataReductionProxyMutableConfigValues;
 class TestDataReductionProxyParams;
 
@@ -39,7 +39,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
       net::NetLog* net_log,
       DataReductionProxyConfigurator* configurator,
-      DataReductionProxyEventStore* event_store);
+      DataReductionProxyEventCreator* event_creator);
 
   // Creates a |TestDataReductionProxyConfig| with the provided |config_values|.
   // This permits any DataReductionProxyConfigValues to be used (such as
@@ -49,7 +49,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       net::NetLog* net_log,
       DataReductionProxyConfigurator* configurator,
-      DataReductionProxyEventStore* event_store);
+      DataReductionProxyEventCreator* event_creator);
 
   ~TestDataReductionProxyConfig() override;
 
@@ -92,7 +92,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
       net::NetLog* net_log,
       DataReductionProxyConfigurator* configurator,
-      DataReductionProxyEventStore* event_store);
+      DataReductionProxyEventCreator* event_creator);
   ~MockDataReductionProxyConfig();
 
   MOCK_METHOD1(RecordSecureProxyCheckFetchResult,
@@ -125,12 +125,6 @@
                           bool alternative_enabled,
                           bool restricted,
                           bool at_startup) override;
-
-  // HandleSecureProxyCheckResponse should always call
-  // RecordSecureProxyCheckFetchResult exactly once.
-  void HandleSecureProxyCheckResponse(
-      const std::string& response,
-      const net::URLRequestStatus& status) override;
 };
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index 1b9c9d9..6dfb7b8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -10,9 +10,10 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
+#include "net/http/http_status_code.h"
 #include "net/log/test_net_log.h"
 #include "net/proxy/proxy_server.h"
 #include "net/url_request/test_url_fetcher_factory.h"
@@ -109,11 +110,12 @@
   class TestResponder {
    public:
     void ExecuteCallback(FetcherResponseCallback callback) {
-      callback.Run(response, status);
+      callback.Run(response, status, http_response_code);
     }
 
     std::string response;
     net::URLRequestStatus status;
+    int http_response_code;
   };
 
   void CheckSecureProxyCheckOnIPChange(
@@ -131,6 +133,7 @@
     responder.response = response;
     responder.status =
         net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK);
+    responder.http_response_code = net::HTTP_OK;
     EXPECT_CALL(*config(), SecureProxyCheck(_, _))
         .Times(1)
         .WillRepeatedly(testing::WithArgs<1>(
@@ -160,7 +163,7 @@
     params->EnableQuic(false);
     return make_scoped_ptr(new DataReductionProxyConfig(
         test_context_->task_runner(), test_context_->net_log(), params.Pass(),
-        test_context_->configurator(), test_context_->event_store()));
+        test_context_->configurator(), test_context_->event_creator()));
   }
 
   MockDataReductionProxyConfig* config() {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc
index 2a804f1..35c8828 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc
@@ -6,17 +6,17 @@
 
 #include "base/strings/string_util.h"
 #include "base/values.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "net/proxy/proxy_config.h"
 
 namespace data_reduction_proxy {
 
 DataReductionProxyConfigurator::DataReductionProxyConfigurator(
     net::NetLog* net_log,
-    DataReductionProxyEventStore* event_store)
-    : net_log_(net_log), data_reduction_proxy_event_store_(event_store) {
+    DataReductionProxyEventCreator* event_creator)
+    : net_log_(net_log), data_reduction_proxy_event_creator_(event_creator) {
   DCHECK(net_log);
-  DCHECK(event_store);
+  DCHECK(event_creator);
   // Constructed on the UI thread, but should be checked on the IO thread.
   thread_checker_.DetachFromThread();
 }
@@ -63,7 +63,7 @@
   // config will return invalid.
   net::ProxyConfig::ID unused_id = 1;
   config.set_id(unused_id);
-  data_reduction_proxy_event_store_->AddProxyEnabledEvent(
+  data_reduction_proxy_event_creator_->AddProxyEnabledEvent(
       net_log_, primary_restricted, fallback_restricted, primary_origin,
       fallback_origin, ssl_origin);
   config_ = config;
@@ -72,7 +72,7 @@
 void DataReductionProxyConfigurator::Disable() {
   DCHECK(thread_checker_.CalledOnValidThread());
   net::ProxyConfig config = net::ProxyConfig::CreateDirect();
-  data_reduction_proxy_event_store_->AddProxyDisabledEvent(net_log_);
+  data_reduction_proxy_event_creator_->AddProxyDisabledEvent(net_log_);
   config_ = config;
 }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h
index e239b542..f62bb7f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h
@@ -22,16 +22,15 @@
 
 namespace data_reduction_proxy {
 
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 
 class DataReductionProxyConfigurator {
  public:
-  // Constructs a configurator. |net_log| and |event_store| are used to
+  // Constructs a configurator. |net_log| and |event_creator| are used to
   // track network and Data Reduction Proxy events respectively, must not be
   // null, and must outlive this instance.
-  DataReductionProxyConfigurator(
-      net::NetLog* net_log,
-      DataReductionProxyEventStore* event_store);
+  DataReductionProxyConfigurator(net::NetLog* net_log,
+                                 DataReductionProxyEventCreator* event_creator);
 
   virtual ~DataReductionProxyConfigurator();
 
@@ -76,7 +75,7 @@
 
   // Used for logging of network- and Data Reduction Proxy-related events.
   net::NetLog* net_log_;
-  DataReductionProxyEventStore* data_reduction_proxy_event_store_;
+  DataReductionProxyEventCreator* data_reduction_proxy_event_creator_;
 
   // Enforce usage on the IO thread.
   base::ThreadChecker thread_checker_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.cc
index e373aad..27d9d38 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.cc
@@ -8,8 +8,8 @@
 
 TestDataReductionProxyConfigurator::TestDataReductionProxyConfigurator(
     net::NetLog* net_log,
-    DataReductionProxyEventStore* event_store)
-    : DataReductionProxyConfigurator(net_log, event_store),
+    DataReductionProxyEventCreator* event_creator)
+    : DataReductionProxyConfigurator(net_log, event_creator),
       enabled_(false),
       restricted_(false),
       fallback_restricted_(false) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h
index bcfccd5..9125bfd 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h
@@ -15,14 +15,14 @@
 
 namespace data_reduction_proxy {
 
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 
 class TestDataReductionProxyConfigurator
     : public DataReductionProxyConfigurator {
  public:
   TestDataReductionProxyConfigurator(
       net::NetLog* net_log,
-      DataReductionProxyEventStore* event_store);
+      DataReductionProxyEventCreator* event_creator);
   ~TestDataReductionProxyConfigurator() override;
 
   // Overrides of DataReductionProxyConfigurator
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
index ee10e1d..d669dcd 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
@@ -7,10 +7,10 @@
 #include <string>
 
 #include "base/memory/scoped_ptr.h"
-#include "base/test/test_simple_task_runner.h"
 #include "base/values.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
-#include "net/log/test_net_log.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -19,12 +19,18 @@
 class DataReductionProxyConfiguratorTest : public testing::Test {
  public:
   void SetUp() override {
-    task_runner_ = new base::TestSimpleTaskRunner();
-    net_log_.reset(new net::TestNetLog());
-    data_reduction_proxy_event_store_.reset(
-        new data_reduction_proxy::DataReductionProxyEventStore(task_runner_));
+    test_context_ =
+        DataReductionProxyTestContext::Builder()
+            .WithParamsFlags(DataReductionProxyParams::kAllowed |
+                             DataReductionProxyParams::kFallbackAllowed |
+                             DataReductionProxyParams::kPromoAllowed)
+            .WithParamsDefinitions(
+                 TestDataReductionProxyParams::HAS_EVERYTHING &
+                 ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
+                 ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)
+            .Build();
     config_.reset(new DataReductionProxyConfigurator(
-        net_log_.get(), data_reduction_proxy_event_store_.get()));
+        test_context_->net_log(), test_context_->event_creator()));
   }
 
   void CheckProxyConfig(
@@ -32,7 +38,7 @@
       const std::string& expected_http_proxies,
       const std::string& expected_https_proxies,
       const std::string& expected_bypass_list) {
-    task_runner_->RunUntilIdle();
+    test_context_->RunUntilIdle();
     const net::ProxyConfig::ProxyRules& rules =
         config_->GetProxyConfig().proxy_rules();
     ASSERT_EQ(expected_rules_type, rules.type);
@@ -44,11 +50,8 @@
     }
   }
 
+  scoped_ptr<DataReductionProxyTestContext> test_context_;
   scoped_ptr<DataReductionProxyConfigurator> config_;
-  scoped_ptr<net::NetLog> net_log_;
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-  scoped_ptr<data_reduction_proxy::DataReductionProxyEventStore>
-      data_reduction_proxy_event_store_;
 };
 
 TEST_F(DataReductionProxyConfiguratorTest, TestUnrestricted) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
index 28de78c..8a1145a6 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
@@ -6,6 +6,7 @@
 
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_request.h"
@@ -19,10 +20,10 @@
 DataReductionProxyInterceptor::DataReductionProxyInterceptor(
     DataReductionProxyConfig* config,
     DataReductionProxyBypassStats* stats,
-    DataReductionProxyEventStore* event_store)
+    DataReductionProxyEventCreator* event_creator)
     : bypass_stats_(stats),
       bypass_protocol_(
-          new DataReductionProxyBypassProtocol(config, event_store)) {
+          new DataReductionProxyBypassProtocol(config, event_creator)) {
 }
 
 DataReductionProxyInterceptor::~DataReductionProxyInterceptor() {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h
index ab7ece8..33c360a121 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h
@@ -11,7 +11,7 @@
 namespace data_reduction_proxy {
 class DataReductionProxyBypassProtocol;
 class DataReductionProxyConfig;
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 class DataReductionProxyBypassStats;
 
 // Used to intercept responses that contain explicit and implicit signals
@@ -20,11 +20,11 @@
 // without use of the proxy.
 class DataReductionProxyInterceptor : public net::URLRequestInterceptor {
  public:
-  // Constructs the interceptor. |config|, |stats|, and |event_store| must
+  // Constructs the interceptor. |config|, |stats|, and |event_creator| must
   // outlive |this|. |stats| may be NULL.
   DataReductionProxyInterceptor(DataReductionProxyConfig* config,
                                 DataReductionProxyBypassStats* stats,
-                                DataReductionProxyEventStore* event_store);
+                                DataReductionProxyEventCreator* event_creator);
 
   // Destroys the interceptor.
   ~DataReductionProxyInterceptor() override;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
index 9034bae2..5a4c5d8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/prefs/pref_member.h"
 #include "base/single_thread_task_runner.h"
@@ -21,26 +22,87 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "net/log/net_log.h"
+#include "net/url_request/http_user_agent_settings.h"
+#include "net/url_request/static_http_user_agent_settings.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+#include "net/url_request/url_request_context_getter.h"
 
 namespace data_reduction_proxy {
 
+// A |net::URLRequestContextGetter| which uses only vanilla HTTP/HTTPS for
+// performing requests. This is used by the secure proxy check to prevent the
+// use of SPDY and QUIC which may be used by the primary request contexts.
+class BasicHTTPURLRequestContextGetter : public net::URLRequestContextGetter {
+ public:
+  BasicHTTPURLRequestContextGetter(
+      const std::string& user_agent,
+      const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner);
+
+  // Overridden from net::URLRequestContextGetter:
+  net::URLRequestContext* GetURLRequestContext() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+      const override;
+
+ private:
+  ~BasicHTTPURLRequestContextGetter() override;
+
+  scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
+  scoped_ptr<net::HttpUserAgentSettings> user_agent_settings_;
+  scoped_ptr<net::URLRequestContext> url_request_context_;
+
+  DISALLOW_COPY_AND_ASSIGN(BasicHTTPURLRequestContextGetter);
+};
+
+BasicHTTPURLRequestContextGetter::BasicHTTPURLRequestContextGetter(
+    const std::string& user_agent,
+    const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner)
+    : network_task_runner_(network_task_runner),
+      user_agent_settings_(
+          new net::StaticHttpUserAgentSettings(std::string(), user_agent)) {
+}
+
+net::URLRequestContext*
+BasicHTTPURLRequestContextGetter::GetURLRequestContext() {
+  if (!url_request_context_) {
+    net::URLRequestContextBuilder builder;
+    builder.set_proxy_service(net::ProxyService::CreateDirect());
+    builder.SetSpdyAndQuicEnabled(false, false);
+    url_request_context_.reset(builder.Build());
+  }
+
+  return url_request_context_.get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+BasicHTTPURLRequestContextGetter::GetNetworkTaskRunner() const {
+  return network_task_runner_;
+}
+
+BasicHTTPURLRequestContextGetter::~BasicHTTPURLRequestContextGetter() {
+}
+
 DataReductionProxyIOData::DataReductionProxyIOData(
     const Client& client,
     int param_flags,
     net::NetLog* net_log,
     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
-    bool enable_quic)
+    bool enable_quic,
+    const std::string& user_agent)
     : client_(client),
       net_log_(net_log),
       io_task_runner_(io_task_runner),
       ui_task_runner_(ui_task_runner),
       shutdown_on_ui_(false),
       url_request_context_getter_(nullptr),
+      basic_url_request_context_getter_(
+          new BasicHTTPURLRequestContextGetter(user_agent, io_task_runner)),
       weak_factory_(this) {
   DCHECK(net_log);
   DCHECK(io_task_runner_);
@@ -48,9 +110,9 @@
   scoped_ptr<DataReductionProxyParams> params(
       new DataReductionProxyParams(param_flags));
   params->EnableQuic(enable_quic);
-  event_store_.reset(new DataReductionProxyEventStore(ui_task_runner));
+  event_creator_.reset(new DataReductionProxyEventCreator(this));
   configurator_.reset(
-      new DataReductionProxyConfigurator(net_log, event_store_.get()));
+      new DataReductionProxyConfigurator(net_log, event_creator_.get()));
   bool use_config_client = DataReductionProxyParams::IsConfigClientEnabled();
   DataReductionProxyMutableConfigValues* raw_mutable_config = nullptr;
   if (use_config_client) {
@@ -59,11 +121,11 @@
     raw_mutable_config = mutable_config.get();
     config_.reset(new DataReductionProxyConfig(
         io_task_runner_, net_log, mutable_config.Pass(), configurator_.get(),
-        event_store_.get()));
+        event_creator_.get()));
   } else {
-    config_.reset(
-        new DataReductionProxyConfig(io_task_runner_, net_log, params.Pass(),
-                                     configurator_.get(), event_store_.get()));
+    config_.reset(new DataReductionProxyConfig(
+        io_task_runner_, net_log, params.Pass(), configurator_.get(),
+        event_creator_.get()));
   }
 
   // It is safe to use base::Unretained here, since it gets executed
@@ -124,9 +186,9 @@
 
 void DataReductionProxyIOData::InitializeOnIOThread() {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
-  config_->InitializeOnIOThread(url_request_context_getter_);
+  config_->InitializeOnIOThread(basic_url_request_context_getter_.get());
   if (config_client_.get())
-    config_client_->RetrieveConfig();
+    config_client_->InitializeOnIOThread(url_request_context_getter_);
   ui_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&DataReductionProxyService::SetIOData,
@@ -140,11 +202,17 @@
              switches::kEnableDataReductionProxy);
 }
 
+void DataReductionProxyIOData::RetrieveConfig() {
+  DCHECK(io_task_runner_->BelongsToCurrentThread());
+  if (config_client_)
+    config_client_->RetrieveConfig();
+}
+
 scoped_ptr<net::URLRequestInterceptor>
 DataReductionProxyIOData::CreateInterceptor() {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   return make_scoped_ptr(new DataReductionProxyInterceptor(
-      config_.get(), bypass_stats_.get(), event_store_.get()));
+      config_.get(), bypass_stats_.get(), event_creator_.get()));
 }
 
 scoped_ptr<DataReductionProxyNetworkDelegate>
@@ -181,6 +249,34 @@
                  data_reduction_proxy_enabled, request_type));
 }
 
+void DataReductionProxyIOData::AddEnabledEvent(scoped_ptr<base::Value> entry,
+                                               bool enabled) {
+  DCHECK(io_task_runner_->BelongsToCurrentThread());
+  ui_task_runner_->PostTask(
+      FROM_HERE, base::Bind(&DataReductionProxyService::AddEnabledEvent,
+                            service_, base::Passed(&entry), enabled));
+}
+
+void DataReductionProxyIOData::AddEventAndSecureProxyCheckState(
+    scoped_ptr<base::Value> entry,
+    SecureProxyCheckState state) {
+  DCHECK(io_task_runner_->BelongsToCurrentThread());
+  ui_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&DataReductionProxyService::AddEventAndSecureProxyCheckState,
+                 service_, base::Passed(&entry), state));
+}
+
+void DataReductionProxyIOData::AddAndSetLastBypassEvent(
+    scoped_ptr<base::Value> entry,
+    int64 expiration_ticks) {
+  DCHECK(io_task_runner_->BelongsToCurrentThread());
+  ui_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&DataReductionProxyService::AddAndSetLastBypassEvent, service_,
+                 base::Passed(&entry), expiration_ticks));
+}
+
 void DataReductionProxyIOData::SetUnreachable(bool unreachable) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   ui_task_runner_->PostTask(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
index 7e45c16..9a6f3b8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_IO_DATA_H_
 #define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_IO_DATA_H_
 
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/prefs/pref_member.h"
@@ -13,6 +15,11 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
+
+namespace base {
+class Value;
+}
 
 namespace net {
 class NetLog;
@@ -26,12 +33,12 @@
 class DataReductionProxyConfig;
 class DataReductionProxyConfigServiceClient;
 class DataReductionProxyConfigurator;
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 class DataReductionProxyService;
 
 // Contains and initializes all Data Reduction Proxy objects that operate on
 // the IO thread.
-class DataReductionProxyIOData {
+class DataReductionProxyIOData : public DataReductionProxyEventStorageDelegate {
  public:
   // Constructs a DataReductionProxyIOData object. |param_flags| is used to
   // set information about the DNS names used by the proxy, and allowable
@@ -42,7 +49,8 @@
       net::NetLog* net_log,
       scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
-      bool enable_quic);
+      bool enable_quic,
+      const std::string& user_agent);
 
   virtual ~DataReductionProxyIOData();
 
@@ -57,6 +65,8 @@
   void SetDataReductionProxyService(
       base::WeakPtr<DataReductionProxyService> data_reduction_proxy_service);
 
+  void RetrieveConfig();
+
   // Creates an interceptor suitable for following the Data Reduction Proxy
   // bypass protocol.
   scoped_ptr<net::URLRequestInterceptor> CreateInterceptor();
@@ -83,6 +93,14 @@
                             bool data_reduction_proxy_enabled,
                             DataReductionProxyRequestType request_type);
 
+  // Overrides of DataReductionProxyEventStorageDelegate. Bridges to the UI
+  // thread objects.
+  void AddEnabledEvent(scoped_ptr<base::Value> entry, bool enabled) override;
+  void AddEventAndSecureProxyCheckState(scoped_ptr<base::Value> entry,
+                                        SecureProxyCheckState state) override;
+  void AddAndSetLastBypassEvent(scoped_ptr<base::Value> entry,
+                                int64 expiration_ticks) override;
+
   // Returns true if the Data Reduction Proxy is enabled and false otherwise.
   bool IsEnabled() const;
 
@@ -95,14 +113,18 @@
     return config_.get();
   }
 
-  DataReductionProxyEventStore* event_store() const {
-    return event_store_.get();
+  DataReductionProxyEventCreator* event_creator() const {
+    return event_creator_.get();
   }
 
   DataReductionProxyRequestOptions* request_options() const {
     return request_options_.get();
   }
 
+  DataReductionProxyConfigServiceClient* config_client() const {
+    return config_client_.get();
+  }
+
   net::ProxyDelegate* proxy_delegate() const {
     return proxy_delegate_.get();
   }
@@ -131,6 +153,7 @@
 
  private:
   friend class TestDataReductionProxyIOData;
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyIODataTest, TestConstruction);
 
   // Used for testing.
   DataReductionProxyIOData();
@@ -153,8 +176,8 @@
   // interstitials.
   mutable scoped_ptr<DataReductionProxyDebugUIService> debug_ui_service_;
 
-  // Tracker of Data Reduction Proxy-related events, e.g., for logging.
-  scoped_ptr<DataReductionProxyEventStore> event_store_;
+  // Creates Data Reduction Proxy-related events for logging.
+  scoped_ptr<DataReductionProxyEventCreator> event_creator_;
 
   // Setter of the Data Reduction Proxy-specific proxy configuration.
   scoped_ptr<DataReductionProxyConfigurator> configurator_;
@@ -192,6 +215,10 @@
   // The net::URLRequestContextGetter used for making URL requests.
   net::URLRequestContextGetter* url_request_context_getter_;
 
+  // A net::URLRequestContextGetter used for making secure proxy checks. It
+  // does not use alternate protocols.
+  scoped_refptr<net::URLRequestContextGetter> basic_url_request_context_getter_;
+
   base::WeakPtrFactory<DataReductionProxyIOData> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(DataReductionProxyIOData);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
index c9c92e1..4caf215 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -14,7 +14,11 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
+#include "net/http/http_network_session.h"
 #include "net/log/net_log.h"
+#include "net/socket/next_proto.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_interceptor.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -90,7 +94,22 @@
 TEST_F(DataReductionProxyIODataTest, TestConstruction) {
   scoped_ptr<DataReductionProxyIOData> io_data(new DataReductionProxyIOData(
       Client::UNKNOWN, DataReductionProxyParams::kAllowed, net_log(),
-      message_loop_proxy(), message_loop_proxy(), false /* enable_quic */));
+      message_loop_proxy(), message_loop_proxy(), false /* enable_quic */,
+      std::string() /* user_agent */));
+
+  // Check that the SimpleURLRequestContextGetter uses vanilla HTTP.
+  net::URLRequestContext* request_context =
+      io_data->basic_url_request_context_getter_.get()->GetURLRequestContext();
+  const net::HttpNetworkSession::Params* http_params =
+      request_context->GetNetworkSessionParams();
+  EXPECT_TRUE(http_params->use_alternate_protocols);
+  EXPECT_FALSE(http_params->enable_quic);
+  net::NextProtoVector expected_protos =
+      net::NextProtosWithSpdyAndQuic(false, false);
+  EXPECT_EQ(expected_protos.size(), http_params->next_protos.size());
+  size_t proto_index = 0;
+  for (const auto& proto : expected_protos)
+    EXPECT_EQ(proto, http_params->next_protos[proto_index++]);
 
   // Check that io_data creates an interceptor. Such an interceptor is
   // thoroughly tested by DataReductionProxyInterceptoTest.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
index 8bd3d23..12b67856 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
@@ -4,6 +4,8 @@
 
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
 
+#include <vector>
+
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/single_thread_task_runner.h"
@@ -40,6 +42,7 @@
 
 const char kSessionHeaderOption[] = "ps";
 const char kCredentialsHeaderOption[] = "sid";
+const char kSecureSessionHeaderOption[] = "s";
 const char kBuildNumberHeaderOption[] = "b";
 const char kPatchNumberHeaderOption[] = "p";
 const char kClientHeaderOption[] = "c";
@@ -300,6 +303,19 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   session_ = session;
   credentials_ = credentials;
+  secure_session_.clear();
+  // Force skipping of credential regeneration. It should be handled by the
+  // caller.
+  use_assigned_credentials_ = true;
+  RegenerateRequestHeaderValue();
+}
+
+void DataReductionProxyRequestOptions::SetSecureSession(
+    const std::string& secure_session) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  session_.clear();
+  credentials_.clear();
+  secure_session_ = secure_session;
   // Force skipping of credential regeneration. It should be handled by the
   // caller.
   use_assigned_credentials_ = true;
@@ -326,6 +342,10 @@
   return key;
 }
 
+const std::string& DataReductionProxyRequestOptions::GetSecureSession() const {
+  return secure_session_;
+}
+
 void DataReductionProxyRequestOptions::MaybeAddRequestHeaderImpl(
     const net::HostPortPair& proxy_server,
     bool expect_ssl,
@@ -341,18 +361,27 @@
 }
 
 void DataReductionProxyRequestOptions::RegenerateRequestHeaderValue() {
-  header_value_ = FormatOption(kSessionHeaderOption, session_)
-                + ", " + FormatOption(kCredentialsHeaderOption, credentials_)
-                + (client_.empty() ?
-                       "" : ", " + FormatOption(kClientHeaderOption, client_))
-                + (build_.empty() || patch_.empty() ?
-                       "" :
-                       ", " + FormatOption(kBuildNumberHeaderOption, build_)
-                       + ", " + FormatOption(kPatchNumberHeaderOption, patch_))
-                + (lofi_.empty() ?
-                       "" : ", " + FormatOption(kLoFiHeaderOption, lofi_));
+  std::vector<std::string> headers;
+  if (!session_.empty())
+    headers.push_back(FormatOption(kSessionHeaderOption, session_));
+  if (!credentials_.empty())
+    headers.push_back(FormatOption(kCredentialsHeaderOption, credentials_));
+  if (!secure_session_.empty()) {
+    headers.push_back(
+        FormatOption(kSecureSessionHeaderOption, secure_session_));
+  }
+  if (!client_.empty())
+    headers.push_back(FormatOption(kClientHeaderOption, client_));
+  if (!build_.empty() && !patch_.empty()) {
+    headers.push_back(FormatOption(kBuildNumberHeaderOption, build_));
+    headers.push_back(FormatOption(kPatchNumberHeaderOption, patch_));
+  }
+  if (!lofi_.empty())
+    headers.push_back(FormatOption(kLoFiHeaderOption, lofi_));
   for (const auto& experiment : experiments_)
-    header_value_ += ", " + FormatOption(kExperimentsOption, experiment);
+    headers.push_back(FormatOption(kExperimentsOption, experiment));
+
+  header_value_ = JoinString(headers, ", ");
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h
index 2aa8dce..0721dab5 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h
@@ -29,6 +29,7 @@
 
 extern const char kSessionHeaderOption[];
 extern const char kCredentialsHeaderOption[];
+extern const char kSecureSessionHeaderOption[];
 extern const char kBuildNumberHeaderOption[];
 extern const char kPatchNumberHeaderOption[];
 extern const char kClientHeaderOption[];
@@ -126,6 +127,9 @@
   void SetCredentials(const std::string& session,
                       const std::string& credentials);
 
+  // Sets the credentials for sending to the Data Reduction Proxy.
+  void SetSecureSession(const std::string& secure_session);
+
  protected:
   void SetHeader(net::HttpRequestHeaders* headers);
 
@@ -146,6 +150,9 @@
                                    const std::string& version,
                                    DataReductionProxyConfig* config);
 
+  // Visible for testing.
+  virtual const std::string& GetSecureSession() const;
+
  private:
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest,
                            AuthHashForSalt);
@@ -201,6 +208,7 @@
   std::string version_;
   std::string session_;
   std::string credentials_;
+  std::string secure_session_;
   std::string build_;
   std::string patch_;
   std::string lofi_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
index 95c3465..4ea8a9a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
@@ -35,6 +35,8 @@
 const char kExpectedCredentials2[] = "c911fdb402f578787562cf7f00eda972";
 const char kExpectedSession2[] = "0-1633771873-1633771873-1633771873";
 const char kDataReductionProxyKey[] = "12345";
+
+const char kSecureSession[] = "TestSecureSessionKey";
 }  // namespace
 
 
@@ -78,6 +80,7 @@
 
 void SetHeaderExpectations(const std::string& session,
                            const std::string& credentials,
+                           const std::string& secure_session,
                            const std::string& client,
                            const std::string& build,
                            const std::string& patch,
@@ -93,6 +96,10 @@
     expected_options.push_back(
         std::string(kCredentialsHeaderOption) + "=" + credentials);
   }
+  if (!secure_session.empty()) {
+    expected_options.push_back(std::string(kSecureSessionHeaderOption) + "=" +
+                               secure_session);
+  }
   if (!client.empty()) {
     expected_options.push_back(
         std::string(kClientHeaderOption) + "=" + client);
@@ -182,15 +189,17 @@
 
 TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationOnIOThread) {
   std::string expected_header;
-  SetHeaderExpectations(kExpectedSession2, kExpectedCredentials2, kClientStr,
-                        kExpectedBuild, kExpectedPatch, std::string(),
-                        std::vector<std::string>(), &expected_header);
+  SetHeaderExpectations(kExpectedSession2, kExpectedCredentials2, std::string(),
+                        kClientStr, kExpectedBuild, kExpectedPatch,
+                        std::string(), std::vector<std::string>(),
+                        &expected_header);
 
   std::string expected_header2;
   SetHeaderExpectations("86401-1633771873-1633771873-1633771873",
-                        "d7c1c34ef6b90303b01c48a6c1db6419", kClientStr,
-                        kExpectedBuild, kExpectedPatch, std::string(),
-                        std::vector<std::string>(), &expected_header2);
+                        "d7c1c34ef6b90303b01c48a6c1db6419", std::string(),
+                        kClientStr, kExpectedBuild, kExpectedPatch,
+                        std::string(), std::vector<std::string>(),
+                        &expected_header2);
 
   CreateRequestOptions(kVersion);
   test_context_->RunUntilIdle();
@@ -233,9 +242,10 @@
 
 TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationIgnoresEmptyKey) {
   std::string expected_header;
-  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr,
-                        kExpectedBuild, kExpectedPatch, std::string(),
-                        std::vector<std::string>(), &expected_header);
+  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+                        kClientStr, kExpectedBuild, kExpectedPatch,
+                        std::string(), std::vector<std::string>(),
+                        &expected_header);
   CreateRequestOptions(kVersion);
   VerifyExpectedHeader(params()->DefaultOrigin(), expected_header);
 
@@ -247,8 +257,8 @@
 
 TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationBogusVersion) {
   std::string expected_header;
-  SetHeaderExpectations(kExpectedSession2, kExpectedCredentials2, kClientStr,
-                        std::string(), std::string(), std::string(),
+  SetHeaderExpectations(kExpectedSession2, kExpectedCredentials2, std::string(),
+                        kClientStr, std::string(), std::string(), std::string(),
                         std::vector<std::string>(), &expected_header);
 
   CreateRequestOptions(kBogusVersion);
@@ -260,8 +270,8 @@
 
 TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationLoFi) {
   std::string expected_header;
-  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr,
-                        std::string(), std::string(), "low",
+  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+                        kClientStr, std::string(), std::string(), "low",
                         std::vector<std::string>(), &expected_header);
 
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
@@ -277,14 +287,25 @@
       data_reduction_proxy::switches::kEnableDataReductionProxyLoFi);
 
   std::string expected_header;
-  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr,
-                        std::string(), std::string(), "low",
+  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+                        kClientStr, std::string(), std::string(), "low",
                         std::vector<std::string>(), &expected_header);
 
   CreateRequestOptions(kBogusVersion);
   VerifyExpectedHeader(params()->DefaultOrigin(), expected_header);
 }
 
+TEST_F(DataReductionProxyRequestOptionsTest, SecureSession) {
+  std::string expected_header;
+  SetHeaderExpectations(std::string(), std::string(), kSecureSession,
+                        kClientStr, std::string(), std::string(), std::string(),
+                        std::vector<std::string>(), &expected_header);
+
+  CreateRequestOptions(kBogusVersion);
+  request_options()->SetSecureSession(kSecureSession);
+  VerifyExpectedHeader(params()->DefaultOrigin(), expected_header);
+}
+
 TEST_F(DataReductionProxyRequestOptionsTest, ParseExperiments) {
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       data_reduction_proxy::switches::kDataReductionProxyExperiment,
@@ -293,8 +314,8 @@
   expected_experiments.push_back("staging");
   expected_experiments.push_back("\"foo,bar\"");
   std::string expected_header;
-  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr,
-                        std::string(), std::string(), std::string(),
+  SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+                        kClientStr, std::string(), std::string(), std::string(),
                         expected_experiments, &expected_header);
 
   CreateRequestOptions(kBogusVersion);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
index 1b90a14..cf25df9 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -11,6 +11,7 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service_observer.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
 
 namespace data_reduction_proxy {
 
@@ -26,6 +27,7 @@
       weak_factory_(this) {
   DCHECK(settings);
   compression_stats_ = compression_stats.Pass();
+  event_store_.reset(new DataReductionProxyEventStore());
 }
 
 DataReductionProxyService::~DataReductionProxyService() {
@@ -68,6 +70,26 @@
   }
 }
 
+void DataReductionProxyService::AddEnabledEvent(scoped_ptr<base::Value> entry,
+                                                bool enabled) {
+  DCHECK(CalledOnValidThread());
+  event_store_->AddEnabledEvent(entry.Pass(), enabled);
+}
+
+void DataReductionProxyService::AddEventAndSecureProxyCheckState(
+    scoped_ptr<base::Value> entry,
+    SecureProxyCheckState state) {
+  DCHECK(CalledOnValidThread());
+  event_store_->AddEventAndSecureProxyCheckState(entry.Pass(), state);
+}
+
+void DataReductionProxyService::AddAndSetLastBypassEvent(
+    scoped_ptr<base::Value> entry,
+    int64 expiration_ticks) {
+  DCHECK(CalledOnValidThread());
+  event_store_->AddAndSetLastBypassEvent(entry.Pass(), expiration_ticks);
+}
+
 void DataReductionProxyService::SetUnreachable(bool unreachable) {
   DCHECK(CalledOnValidThread());
   settings_->SetUnreachable(unreachable);
@@ -83,6 +105,13 @@
                  io_data_, enabled, alternative_enabled, at_startup));
 }
 
+void DataReductionProxyService::RetrieveConfig() {
+  DCHECK(CalledOnValidThread());
+  io_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&DataReductionProxyIOData::RetrieveConfig, io_data_));
+}
+
 void DataReductionProxyService::AddObserver(
     DataReductionProxyServiceObserver* observer) {
   DCHECK(CalledOnValidThread());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
index ed393073..54a3365 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
@@ -14,6 +14,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/threading/non_thread_safe.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
 
 class GURL;
 class PrefService;
@@ -21,6 +22,7 @@
 namespace base {
 class SequencedTaskRunner;
 class TimeDelta;
+class Value;
 }
 
 namespace net {
@@ -30,13 +32,16 @@
 namespace data_reduction_proxy {
 
 class DataReductionProxyCompressionStats;
+class DataReductionProxyEventStore;
 class DataReductionProxyIOData;
 class DataReductionProxyServiceObserver;
 class DataReductionProxySettings;
 
 // Contains and initializes all Data Reduction Proxy objects that have a
 // lifetime based on the UI thread.
-class DataReductionProxyService : public base::NonThreadSafe {
+class DataReductionProxyService
+    : public base::NonThreadSafe,
+      public DataReductionProxyEventStorageDelegate {
  public:
   // The caller must ensure that |settings| and |request_context| remain alive
   // for the lifetime of the |DataReductionProxyService| instance. This instance
@@ -73,6 +78,13 @@
                             bool data_reduction_proxy_enabled,
                             DataReductionProxyRequestType request_type);
 
+  // Overrides of DataReductionProxyEventStorageDelegate.
+  void AddEnabledEvent(scoped_ptr<base::Value> entry, bool enabled) override;
+  void AddEventAndSecureProxyCheckState(scoped_ptr<base::Value> entry,
+                                        SecureProxyCheckState state) override;
+  void AddAndSetLastBypassEvent(scoped_ptr<base::Value> entry,
+                                int64 expiration_ticks) override;
+
   // Records whether the Data Reduction Proxy is unreachable or not.
   void SetUnreachable(bool unreachable);
 
@@ -81,6 +93,7 @@
   virtual void SetProxyPrefs(bool enabled,
                              bool alternative_enabled,
                              bool at_startup);
+  void RetrieveConfig();
 
   // Methods for adding/removing observers on |this|.
   void AddObserver(DataReductionProxyServiceObserver* observer);
@@ -95,6 +108,10 @@
     return settings_;
   }
 
+  DataReductionProxyEventStore* event_store() const {
+    return event_store_.get();
+  }
+
   net::URLRequestContextGetter* url_request_context_getter() const {
     return url_request_context_getter_;
   }
@@ -107,6 +124,8 @@
   // Tracks compression statistics to be displayed to the user.
   scoped_ptr<DataReductionProxyCompressionStats> compression_stats_;
 
+  scoped_ptr<DataReductionProxyEventStore> event_store_;
+
   DataReductionProxySettings* settings_;
 
   // Used to post tasks to |io_data_|.
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 408ad45c..57f18bb6 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
@@ -49,7 +49,6 @@
       alternative_allowed_(false),
       promo_allowed_(false),
       prefs_(NULL),
-      event_store_(NULL),
       config_(nullptr) {
 }
 
@@ -88,11 +87,9 @@
   DCHECK(prefs);
   DCHECK(io_data);
   DCHECK(io_data->config());
-  DCHECK(io_data->event_store());
   DCHECK(data_reduction_proxy_service.get());
   prefs_ = prefs;
   config_ = io_data->config();
-  event_store_ = io_data->event_store();
   data_reduction_proxy_service_ = data_reduction_proxy_service.Pass();
   data_reduction_proxy_service_->AddObserver(this);
   InitPrefMembers();
@@ -226,6 +223,7 @@
   data_reduction_proxy_service_->SetProxyPrefs(
       IsDataReductionProxyEnabled(), IsDataReductionProxyAlternativeEnabled(),
       at_startup);
+  data_reduction_proxy_service_->RetrieveConfig();
 }
 
 void DataReductionProxySettings::MaybeActivateDataReductionProxy(
@@ -251,6 +249,14 @@
     UpdateIOData(at_startup);
 }
 
+DataReductionProxyEventStore* DataReductionProxySettings::GetEventStore()
+    const {
+  if (data_reduction_proxy_service_)
+    return data_reduction_proxy_service_->event_store();
+
+  return nullptr;
+}
+
 // Metrics methods
 void DataReductionProxySettings::RecordDataReductionInit() {
   DCHECK(thread_checker_.CalledOnValidThread());
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 c7f3685..213a248b 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
@@ -126,9 +126,7 @@
 
   // Returns the event store being used. May be null if
   // InitDataReductionProxySettings has not been called.
-  DataReductionProxyEventStore* GetEventStore() const {
-    return event_store_;
-  }
+  DataReductionProxyEventStore* GetEventStore() const;
 
   // Returns true if the data reduction proxy configuration may be used.
   bool Allowed() const {
@@ -253,9 +251,6 @@
 
   PrefService* prefs_;
 
-  // The caller must ensure that the |event_store_| outlives this instance.
-  DataReductionProxyEventStore* event_store_;
-
   // The caller must ensure that the |config_| outlives this instance.
   DataReductionProxyConfig* config_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
index 2b1a17b..dce4f0a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -185,18 +185,6 @@
             .SkipSettingsInitialization()
             .Build();
 
-    // Enabling QUIC should have no effect since secure proxy should not
-    // use QUIC. If secure proxy check incorrectly uses QUIC, the tests will
-    // fail because Mock sockets do not speak QUIC.
-    scoped_ptr<net::HttpNetworkSession::Params> params(
-        new net::HttpNetworkSession::Params());
-    params->use_alternate_protocols = true;
-    params->enable_quic = true;
-    params->origin_to_force_quic_on = net::HostPortPair::FromString(
-        TestDataReductionProxyParams::DefaultSecureProxyCheckURL());
-
-    context.set_http_network_session_params(params.Pass());
-
     context.set_net_log(drp_test_context->net_log());
     net::MockClientSocketFactory mock_socket_factory;
     context.set_client_socket_factory(&mock_socket_factory);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.cc
index a9f75c42..823d0a7 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.cc
@@ -109,15 +109,9 @@
   }
 
   // Chrome-Proxy header has not been tampered with, and thus other
-  // fingerprints are valid. Reports the number of responses that other
-  // fingerprints will be checked.
-  REPORT_TAMPER_DETECTION_UMA(
-      scheme_is_https,
-      "DataReductionProxy.HeaderTamperDetectionHTTPS",
-      "DataReductionProxy.HeaderTamperDetectionHTTP",
-      carrier_id);
-
+  // fingerprints are valid.
   bool tampered = false;
+  int64 original_content_length = -1;
   std::string fingerprint;
 
   if (GetDataReductionProxyActionFingerprintVia(headers, &fingerprint)) {
@@ -140,7 +134,6 @@
 
   if (GetDataReductionProxyActionFingerprintContentLength(
       headers, &fingerprint)) {
-    int64 original_content_length;
     if (tamper_detection.ValidateContentLength(fingerprint,
                                                content_length,
                                                &original_content_length)) {
@@ -158,6 +151,10 @@
         carrier_id);
   }
 
+  // Reports the number of responses that other fingerprints will be checked,
+  // separated by MIME type.
+  tamper_detection.ReportUMAForTamperDetectionCount(original_content_length);
+
   return tampered;
 }
 
@@ -174,6 +171,88 @@
 
 DataReductionProxyTamperDetection::~DataReductionProxyTamperDetection() {};
 
+void DataReductionProxyTamperDetection::ReportUMAForTamperDetectionCount(
+    int64 original_content_length) const {
+  REPORT_TAMPER_DETECTION_UMA(
+      scheme_is_https_, "DataReductionProxy.HeaderTamperDetectionHTTPS",
+      "DataReductionProxy.HeaderTamperDetectionHTTP", carrier_id_);
+
+  std::string mime_type;
+  response_headers_->GetMimeType(&mime_type);
+
+  if (net::MatchesMimeType("text/javascript", mime_type) ||
+      net::MatchesMimeType("application/x-javascript", mime_type) ||
+      net::MatchesMimeType("application/javascript", mime_type)) {
+    REPORT_TAMPER_DETECTION_UMA(
+        scheme_is_https_, "DataReductionProxy.HeaderTamperDetectionHTTPS_JS",
+        "DataReductionProxy.HeaderTamperDetectionHTTP_JS", carrier_id_);
+  } else if (net::MatchesMimeType("text/css", mime_type)) {
+    REPORT_TAMPER_DETECTION_UMA(
+        scheme_is_https_, "DataReductionProxy.HeaderTamperDetectionHTTPS_CSS",
+        "DataReductionProxy.HeaderTamperDetectionHTTP_CSS", carrier_id_);
+  } else if (net::MatchesMimeType("image/*", mime_type)) {
+    REPORT_TAMPER_DETECTION_UMA(
+        scheme_is_https_, "DataReductionProxy.HeaderTamperDetectionHTTPS_Image",
+        "DataReductionProxy.HeaderTamperDetectionHTTP_Image", carrier_id_);
+
+    if (net::MatchesMimeType("image/gif", mime_type)) {
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_GIF",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_GIF",
+          carrier_id_);
+    } else if (net::MatchesMimeType("image/jpeg", mime_type) ||
+               net::MatchesMimeType("image/jpg", mime_type)) {
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_JPG",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_JPG",
+          carrier_id_);
+    } else if (net::MatchesMimeType("image/png", mime_type)) {
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_PNG",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_PNG",
+          carrier_id_);
+    } else if (net::MatchesMimeType("image/webp", mime_type)) {
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_WEBP",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_WEBP",
+          carrier_id_);
+    }
+
+    if (original_content_length == -1)
+      return;
+
+    if (original_content_length < 10 * 1024) {  // 0-10KB
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_0_10KB",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_0_10KB",
+          carrier_id_);
+    } else if (original_content_length < 100 * 1024) {  // 10-100KB
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_10_100KB",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_10_100KB",
+          carrier_id_);
+    } else if (original_content_length < 500 * 1024) {  // 100-500KB
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_100_500KB",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_100_500KB",
+          carrier_id_);
+    } else {  // >=500KB
+      REPORT_TAMPER_DETECTION_UMA(
+          scheme_is_https_,
+          "DataReductionProxy.HeaderTamperDetectionHTTPS_Image_500KB",
+          "DataReductionProxy.HeaderTamperDetectionHTTP_Image_500KB",
+          carrier_id_);
+    }
+  }
+}
+
 // |fingerprint| is Base64 encoded. Decodes it first. Then calculates the
 // fingerprint of received Chrome-Proxy header, and compares the two to see
 // whether they are equal or not.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.h
index 4f52412..2c5712b 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection.h
@@ -101,8 +101,14 @@
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest,
                            GetHeaderValues);
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest,
+                           HistogramCount);
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest,
                            DetectAndReport);
 
+  // Reports UMA for the numbers of responses with valid fingerprints, separated
+  // by MIME type.
+  void ReportUMAForTamperDetectionCount(int64 original_content_length) const;
+
   // Returns the result of validating Chrome-Proxy header.
   bool ValidateChromeProxyHeader(const std::string& fingerprint) const;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection_unittest.cc
index 8023c31..cdda92c 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_tamper_detection_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
+#include "base/test/histogram_tester.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h"
 #include "net/http/http_response_headers.h"
@@ -594,6 +595,107 @@
   }
 }
 
+// Tests UMA histogram count.
+TEST_F(DataReductionProxyTamperDetectionTest, HistogramCount) {
+  struct {
+    std::string raw_header;
+    std::string histogram_name_suffix;
+    int original_content_length;
+    std::string image_histogram_name_suffix;
+  } tests[] = {
+      // Checks the correctness of histogram for Javascript
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: text/javascript\n",
+       "_JS",
+       -1,
+       ""},
+      // Checks the correctness of histogram for CSS
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: text/css\n",
+       "_CSS",
+       -1,
+       ""},
+      // Checks the correctness of histogram for image
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: image/test\n",
+       "_Image",
+       1,
+       "_Image_0_10KB"},
+      // Checks the correctness of histogram for GIF
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: image/gif\n",
+       "_Image_GIF",
+       20 * 1024,
+       "_Image_10_100KB"},
+      // Checks the correctness of histogram for JPG
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: image/jpeg\n",
+       "_Image_JPG",
+       200 * 1024,
+       "_Image_100_500KB"},
+      // Checks the correctness of histogram for PNG
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: image/png\n",
+       "_Image_PNG",
+       600 * 1024,
+       "_Image_500KB"},
+      // Checks the correctness of histogram for WebP
+      {"HTTP/1.1 200 OK\n"
+       "Content-Type: image/webp\n",
+       "_Image_WEBP",
+       -1,
+       ""},
+  };
+
+  const int carrier_id = 100;
+
+  for (auto& test : tests) {
+    std::string raw_headers(test.raw_header);
+    HeadersToRaw(&raw_headers);
+    scoped_refptr<net::HttpResponseHeaders> headers(
+        new net::HttpResponseHeaders(raw_headers));
+
+    // Test HTTPS and HTTP separately.
+    int https_values[] = {true, false};
+    for (auto https : https_values) {
+      base::HistogramTester histogram_tester;
+
+      DataReductionProxyTamperDetection tamper_detection(headers.get(), https,
+                                                         carrier_id);
+      tamper_detection.ReportUMAForTamperDetectionCount(
+          test.original_content_length);
+      histogram_tester.ExpectTotalCount(
+          std::string("DataReductionProxy.HeaderTamperDetectionHTTP") +
+              (https ? "S" : "") + test.histogram_name_suffix + "_Total",
+          1);
+      histogram_tester.ExpectUniqueSample(
+          std::string("DataReductionProxy.HeaderTamperDetectionHTTP") +
+              (https ? "S" : "") + test.histogram_name_suffix,
+          carrier_id, 1);
+      histogram_tester.ExpectTotalCount(
+          std::string("DataReductionProxy.HeaderTamperDetectionHTTP") +
+              (https ? "S" : "") + "_Total",
+          1);
+      histogram_tester.ExpectUniqueSample(
+          std::string("DataReductionProxy.HeaderTamperDetectionHTTP") +
+              (https ? "S" : ""),
+          carrier_id, 1);
+
+      if (test.original_content_length != -1) {
+        histogram_tester.ExpectTotalCount(
+            std::string("DataReductionProxy.HeaderTamperDetectionHTTP") +
+                (https ? "S" : "") + test.image_histogram_name_suffix +
+                "_Total",
+            1);
+        histogram_tester.ExpectUniqueSample(
+            std::string("DataReductionProxy.HeaderTamperDetectionHTTP") +
+                (https ? "S" : "") + test.image_histogram_name_suffix,
+            carrier_id, 1);
+      }
+    }
+  }
+}
+
 // Tests main function DetectAndReport.
 TEST_F(DataReductionProxyTamperDetectionTest, DetectAndReport) {
   struct {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index b3c9c4a..f070f13 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -15,6 +15,8 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.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/common/data_reduction_proxy_event_creator.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
@@ -23,6 +25,7 @@
 #include "net/url_request/url_request_intercepting_job_factory.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "net/url_request/url_request_test_util.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -71,11 +74,16 @@
   now_offset_ = now_offset;
 }
 
+const std::string& TestDataReductionProxyRequestOptions::GetSecureSession()
+    const {
+  return DataReductionProxyRequestOptions::GetSecureSession();
+}
+
 MockDataReductionProxyRequestOptions::MockDataReductionProxyRequestOptions(
     Client client,
     const std::string& version,
     DataReductionProxyConfig* config)
-    : DataReductionProxyRequestOptions(client, version, config) {
+    : TestDataReductionProxyRequestOptions(client, version, config) {
 }
 
 MockDataReductionProxyRequestOptions::~MockDataReductionProxyRequestOptions() {
@@ -113,6 +121,16 @@
   return config_refresh_timer_.GetCurrentDelay();
 }
 
+int TestDataReductionProxyConfigServiceClient::GetBackoffErrorCount() {
+  return test_backoff_entry_.failure_count();
+}
+
+void TestDataReductionProxyConfigServiceClient::SetConfigServiceURL(
+    const GURL& service_url) {
+  config_service_url_ = service_url;
+  use_local_config_ = !config_service_url_.is_valid();
+}
+
 base::Time TestDataReductionProxyConfigServiceClient::Now() {
   return tick_clock_.Now();
 }
@@ -157,7 +175,7 @@
 TestDataReductionProxyIOData::TestDataReductionProxyIOData(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     scoped_ptr<DataReductionProxyConfig> config,
-    scoped_ptr<DataReductionProxyEventStore> event_store,
+    scoped_ptr<DataReductionProxyEventCreator> event_creator,
     scoped_ptr<DataReductionProxyRequestOptions> request_options,
     scoped_ptr<DataReductionProxyConfigurator> configurator,
     scoped_ptr<DataReductionProxyConfigServiceClient> config_client)
@@ -165,7 +183,7 @@
   io_task_runner_ = task_runner;
   ui_task_runner_ = task_runner;
   config_ = config.Pass();
-  event_store_ = event_store.Pass();
+  event_creator_ = event_creator.Pass();
   request_options_ = request_options.Pass();
   configurator_ = configurator.Pass();
   config_client_ = config_client.Pass();
@@ -297,16 +315,18 @@
         task_runner, test_request_context.Pass());
   }
 
-  scoped_ptr<DataReductionProxyEventStore> event_store(
-      new DataReductionProxyEventStore(task_runner));
+  scoped_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate(
+      new TestDataReductionProxyEventStorageDelegate());
+  scoped_ptr<DataReductionProxyEventCreator> event_creator(
+      new DataReductionProxyEventCreator(storage_delegate.get()));
   scoped_ptr<DataReductionProxyConfigurator> configurator;
   if (use_test_configurator_) {
     test_context_flags |= USE_TEST_CONFIGURATOR;
     configurator.reset(new TestDataReductionProxyConfigurator(
-        net_log.get(), event_store.get()));
+        net_log.get(), event_creator.get()));
   } else {
     configurator.reset(
-        new DataReductionProxyConfigurator(net_log.get(), event_store.get()));
+        new DataReductionProxyConfigurator(net_log.get(), event_creator.get()));
   }
 
   scoped_ptr<TestDataReductionProxyConfig> config;
@@ -322,16 +342,16 @@
     raw_mutable_config = mutable_config.get();
     config.reset(new TestDataReductionProxyConfig(
         mutable_config.Pass(), task_runner, net_log.get(), configurator.get(),
-        event_store.get()));
+        event_creator.get()));
   } else if (use_mock_config_) {
     test_context_flags |= USE_MOCK_CONFIG;
     config.reset(new MockDataReductionProxyConfig(
         params.Pass(), task_runner, net_log.get(), configurator.get(),
-        event_store.get()));
+        event_creator.get()));
   } else {
     config.reset(new TestDataReductionProxyConfig(
         params.Pass(), task_runner, net_log.get(), configurator.get(),
-        event_store.get()));
+        event_creator.get()));
   }
 
   scoped_ptr<DataReductionProxyRequestOptions> request_options;
@@ -367,15 +387,17 @@
 
   scoped_ptr<TestDataReductionProxyIOData> io_data(
       new TestDataReductionProxyIOData(
-          task_runner, config.Pass(), event_store.Pass(),
+          task_runner, config.Pass(), event_creator.Pass(),
           request_options.Pass(), configurator.Pass(), config_client.Pass()));
   io_data->InitOnUIThread(pref_service.get());
+  io_data->SetSimpleURLRequestContextGetter(request_context_getter);
 
   scoped_ptr<DataReductionProxyTestContext> test_context(
       new DataReductionProxyTestContext(
           loop.Pass(), task_runner, pref_service.Pass(), net_log.Pass(),
           request_context_getter, mock_socket_factory_, io_data.Pass(),
-          settings.Pass(), raw_params, test_context_flags));
+          settings.Pass(), storage_delegate.Pass(), raw_params,
+          test_context_flags));
 
   if (!skip_settings_initialization_)
     test_context->InitSettingsWithoutCheck();
@@ -392,6 +414,7 @@
     net::MockClientSocketFactory* mock_socket_factory,
     scoped_ptr<TestDataReductionProxyIOData> io_data,
     scoped_ptr<DataReductionProxySettings> settings,
+    scoped_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate,
     TestDataReductionProxyParams* params,
     unsigned int test_context_flags)
     : test_context_flags_(test_context_flags),
@@ -403,6 +426,7 @@
       mock_socket_factory_(mock_socket_factory),
       io_data_(io_data.Pass()),
       settings_(settings.Pass()),
+      storage_delegate_(storage_delegate.Pass()),
       params_(params) {
 }
 
@@ -423,8 +447,13 @@
   settings_->InitDataReductionProxySettings(
       simple_pref_service_.get(), io_data_.get(),
       CreateDataReductionProxyServiceInternal());
+  storage_delegate_->SetStorageDelegate(
+      settings_->data_reduction_proxy_service()->event_store());
   io_data_->SetDataReductionProxyService(
       settings_->data_reduction_proxy_service()->GetWeakPtr());
+  if (io_data_->config_client())
+    io_data_->config_client()->InitializeOnIOThread(
+        request_context_getter_.get());
   settings_->data_reduction_proxy_service()->SetIOData(io_data_->GetWeakPtr());
 }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
index b1d29d2..e5c4ca0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -22,8 +22,10 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h"
 #include "net/base/backoff_entry.h"
 #include "net/log/test_net_log.h"
+#include "net/url_request/url_request_context_getter.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
+class GURL;
 class TestingPrefServiceSimple;
 
 namespace base {
@@ -34,14 +36,13 @@
 class MockClientSocketFactory;
 class NetLog;
 class URLRequestContext;
-class URLRequestContextGetter;
 class URLRequestContextStorage;
 }
 
 namespace data_reduction_proxy {
 
 class DataReductionProxyConfigurator;
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 class DataReductionProxyMutableConfigValues;
 class DataReductionProxyRequestOptions;
 class DataReductionProxySettings;
@@ -49,6 +50,7 @@
 class MockDataReductionProxyConfig;
 class TestDataReductionProxyConfig;
 class TestDataReductionProxyConfigurator;
+class TestDataReductionProxyEventStorageDelegate;
 class TestDataReductionProxyParams;
 
 // Test version of |DataReductionProxyRequestOptions|.
@@ -67,13 +69,16 @@
   // Time after the unix epoch that Now() reports.
   void set_offset(const base::TimeDelta& now_offset);
 
+  // Visible for testing.
+  const std::string& GetSecureSession() const override;
+
  private:
   base::TimeDelta now_offset_;
 };
 
 // Mock version of |DataReductionProxyRequestOptions|.
 class MockDataReductionProxyRequestOptions
-    : public DataReductionProxyRequestOptions {
+    : public TestDataReductionProxyRequestOptions {
  public:
   MockDataReductionProxyRequestOptions(Client client,
                                        const std::string& version,
@@ -104,6 +109,10 @@
 
   base::TimeDelta GetDelay() const;
 
+  int GetBackoffErrorCount();
+
+  void SetConfigServiceURL(const GURL& service_url);
+
  protected:
   // Overrides of DataReductionProxyConfigServiceClient
   base::Time Now() override;
@@ -155,7 +164,7 @@
   TestDataReductionProxyIOData(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       scoped_ptr<DataReductionProxyConfig> config,
-      scoped_ptr<DataReductionProxyEventStore> event_store,
+      scoped_ptr<DataReductionProxyEventCreator> event_creator,
       scoped_ptr<DataReductionProxyRequestOptions> request_options,
       scoped_ptr<DataReductionProxyConfigurator> configurator,
       scoped_ptr<DataReductionProxyConfigServiceClient> config_client);
@@ -169,6 +178,11 @@
     return config_client_.get();
   }
 
+  void SetSimpleURLRequestContextGetter(
+      const scoped_refptr<net::URLRequestContextGetter> context_getter) {
+    basic_url_request_context_getter_ = context_getter;
+  }
+
   base::WeakPtr<DataReductionProxyIOData> GetWeakPtr() {
     return weak_factory_.GetWeakPtr();
   }
@@ -330,8 +344,8 @@
     return request_context_getter_.get();
   }
 
-  DataReductionProxyEventStore* event_store() const {
-    return io_data_->event_store();
+  DataReductionProxyEventCreator* event_creator() const {
+    return io_data_->event_creator();
   }
 
   DataReductionProxyConfigurator* configurator() const {
@@ -380,6 +394,7 @@
       net::MockClientSocketFactory* mock_socket_factory,
       scoped_ptr<TestDataReductionProxyIOData> io_data,
       scoped_ptr<DataReductionProxySettings> settings,
+      scoped_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate,
       TestDataReductionProxyParams* params,
       unsigned int test_context_flags);
 
@@ -402,6 +417,7 @@
 
   scoped_ptr<TestDataReductionProxyIOData> io_data_;
   scoped_ptr<DataReductionProxySettings> settings_;
+  scoped_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate_;
 
   TestDataReductionProxyParams* params_;
 
diff --git a/components/data_reduction_proxy/core/common/BUILD.gn b/components/data_reduction_proxy/core/common/BUILD.gn
index 6976004..c0788de 100644
--- a/components/data_reduction_proxy/core/common/BUILD.gn
+++ b/components/data_reduction_proxy/core/common/BUILD.gn
@@ -10,6 +10,9 @@
     "data_reduction_proxy_client_config_parser.cc",
     "data_reduction_proxy_client_config_parser.h",
     "data_reduction_proxy_config_values.h",
+    "data_reduction_proxy_event_creator.cc",
+    "data_reduction_proxy_event_creator.h",
+    "data_reduction_proxy_event_storage_delegate.h",
     "data_reduction_proxy_event_store.cc",
     "data_reduction_proxy_event_store.h",
     "data_reduction_proxy_headers.cc",
@@ -36,6 +39,8 @@
 source_set("test_support") {
   testonly = true
   sources = [
+    "data_reduction_proxy_event_storage_delegate_test_utils.cc",
+    "data_reduction_proxy_event_storage_delegate_test_utils.h",
     "data_reduction_proxy_headers_test_utils.cc",
     "data_reduction_proxy_headers_test_utils.h",
     "data_reduction_proxy_params_test_utils.cc",
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.cc
new file mode 100644
index 0000000..1ce6246e
--- /dev/null
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.cc
@@ -0,0 +1,267 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
+
+#include "base/bind.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "net/proxy/proxy_server.h"
+
+namespace {
+
+scoped_ptr<base::Value> BuildDataReductionProxyEvent(
+    net::NetLog::EventType type,
+    const net::NetLog::Source& source,
+    net::NetLog::EventPhase phase,
+    const net::NetLog::ParametersCallback& parameters_callback) {
+  base::TimeTicks ticks_now = base::TimeTicks::Now();
+  net::NetLog::EntryData entry_data(type, source, phase, ticks_now,
+                                    &parameters_callback);
+  net::NetLog::Entry entry(&entry_data,
+                           net::NetLogCaptureMode::IncludeSocketBytes());
+  scoped_ptr<base::Value> entry_value(entry.ToValue());
+
+  return entry_value;
+}
+
+int64 GetExpirationTicks(int bypass_seconds) {
+  base::TimeTicks expiration_ticks =
+      base::TimeTicks::Now() + base::TimeDelta::FromSeconds(bypass_seconds);
+  return (expiration_ticks - base::TimeTicks()).InMilliseconds();
+}
+
+// The following method creates a string resembling the output of
+// net::ProxyServer::ToURI().
+std::string GetNormalizedProxyString(const std::string& proxy_origin) {
+  net::ProxyServer proxy_server =
+      net::ProxyServer::FromURI(proxy_origin, net::ProxyServer::SCHEME_HTTP);
+  if (proxy_server.is_valid())
+    return proxy_origin;
+
+  return std::string();
+}
+
+// A callback which creates a base::Value containing information about enabling
+// the Data Reduction Proxy. Ownership of the base::Value is passed to the
+// caller.
+base::Value* EnableDataReductionProxyCallback(
+    bool primary_restricted,
+    bool fallback_restricted,
+    const std::string& primary_origin,
+    const std::string& fallback_origin,
+    const std::string& ssl_origin,
+    net::NetLogCaptureMode /* capture_mode */) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetBoolean("enabled", true);
+  dict->SetBoolean("primary_restricted", primary_restricted);
+  dict->SetBoolean("fallback_restricted", fallback_restricted);
+  dict->SetString("primary_origin", GetNormalizedProxyString(primary_origin));
+  dict->SetString("fallback_origin", GetNormalizedProxyString(fallback_origin));
+  dict->SetString("ssl_origin", GetNormalizedProxyString(ssl_origin));
+  return dict;
+}
+
+// A callback which creates a base::Value containing information about disabling
+// the Data Reduction Proxy. Ownership of the base::Value is passed to the
+// caller.
+base::Value* DisableDataReductionProxyCallback(
+    net::NetLogCaptureMode /* capture_mode */) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetBoolean("enabled", false);
+  return dict;
+}
+
+// A callback which creates a base::Value containing information about bypassing
+// the Data Reduction Proxy. Ownership of the base::Value is passed to the
+// caller.
+base::Value* UrlBypassActionCallback(
+    const std::string& action,
+    const GURL& url,
+    int bypass_seconds,
+    int64 expiration_ticks,
+    net::NetLogCaptureMode /* capture_mode */) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetString("action", action);
+  dict->SetString("url", url.spec());
+  dict->SetString("bypass_duration_seconds",
+                  base::Int64ToString(bypass_seconds));
+  dict->SetString("expiration", base::Int64ToString(expiration_ticks));
+  return dict;
+}
+
+// A callback which creates a base::Value containing information about bypassing
+// the Data Reduction Proxy. Ownership of the base::Value is passed to the
+// caller.
+base::Value* UrlBypassTypeCallback(
+    data_reduction_proxy::DataReductionProxyBypassType bypass_type,
+    const GURL& url,
+    int bypass_seconds,
+    int64 expiration_ticks,
+    net::NetLogCaptureMode /* capture_mode */) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetInteger("bypass_type", bypass_type);
+  dict->SetString("url", url.spec());
+  dict->SetString("bypass_duration_seconds",
+                  base::Int64ToString(bypass_seconds));
+  dict->SetString("expiration", base::Int64ToString(expiration_ticks));
+  return dict;
+}
+
+// A callback which creates a base::Value containing information about
+// completing the Data Reduction Proxy secure proxy check. Ownership of the
+// base::Value is passed to the caller.
+base::Value* EndCanaryRequestCallback(
+    int net_error,
+    int http_response_code,
+    bool succeeded,
+    net::NetLogCaptureMode /* capture_mode */) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetInteger("net_error", net_error);
+  dict->SetInteger("http_response_code", http_response_code);
+  dict->SetBoolean("check_succeeded", succeeded);
+  return dict;
+}
+
+}  // namespace
+
+namespace data_reduction_proxy {
+
+DataReductionProxyEventCreator::DataReductionProxyEventCreator(
+    DataReductionProxyEventStorageDelegate* storage_delegate)
+    : storage_delegate_(storage_delegate) {
+  DCHECK(storage_delegate);
+  // Constructed on the UI thread, but should be checked on the IO thread.
+  thread_checker_.DetachFromThread();
+}
+
+DataReductionProxyEventCreator::~DataReductionProxyEventCreator() {
+}
+
+void DataReductionProxyEventCreator::AddProxyEnabledEvent(
+    net::NetLog* net_log,
+    bool primary_restricted,
+    bool fallback_restricted,
+    const std::string& primary_origin,
+    const std::string& fallback_origin,
+    const std::string& ssl_origin) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  const net::NetLog::ParametersCallback& parameters_callback = base::Bind(
+      &EnableDataReductionProxyCallback, primary_restricted,
+      fallback_restricted, primary_origin, fallback_origin, ssl_origin);
+  PostEnabledEvent(net_log, net::NetLog::TYPE_DATA_REDUCTION_PROXY_ENABLED,
+                   true, parameters_callback);
+}
+
+void DataReductionProxyEventCreator::AddProxyDisabledEvent(
+    net::NetLog* net_log) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  const net::NetLog::ParametersCallback& parameters_callback =
+      base::Bind(&DisableDataReductionProxyCallback);
+  PostEnabledEvent(net_log, net::NetLog::TYPE_DATA_REDUCTION_PROXY_ENABLED,
+                   false, parameters_callback);
+}
+
+void DataReductionProxyEventCreator::AddBypassActionEvent(
+    const net::BoundNetLog& net_log,
+    const std::string& bypass_action,
+    const GURL& url,
+    const base::TimeDelta& bypass_duration) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  int64 expiration_ticks = GetExpirationTicks(bypass_duration.InSeconds());
+  const net::NetLog::ParametersCallback& parameters_callback =
+      base::Bind(&UrlBypassActionCallback, bypass_action, url,
+                 bypass_duration.InSeconds(), expiration_ticks);
+  PostBoundNetLogBypassEvent(
+      net_log, net::NetLog::TYPE_DATA_REDUCTION_PROXY_BYPASS_REQUESTED,
+      net::NetLog::PHASE_NONE, expiration_ticks, parameters_callback);
+}
+
+void DataReductionProxyEventCreator::AddBypassTypeEvent(
+    const net::BoundNetLog& net_log,
+    DataReductionProxyBypassType bypass_type,
+    const GURL& url,
+    const base::TimeDelta& bypass_duration) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  int64 expiration_ticks = GetExpirationTicks(bypass_duration.InSeconds());
+  const net::NetLog::ParametersCallback& parameters_callback =
+      base::Bind(&UrlBypassTypeCallback, bypass_type, url,
+                 bypass_duration.InSeconds(), expiration_ticks);
+  PostBoundNetLogBypassEvent(
+      net_log, net::NetLog::TYPE_DATA_REDUCTION_PROXY_BYPASS_REQUESTED,
+      net::NetLog::PHASE_NONE, expiration_ticks, parameters_callback);
+}
+
+void DataReductionProxyEventCreator::BeginSecureProxyCheck(
+    const net::BoundNetLog& net_log,
+    const GURL& url) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  // This callback must be invoked synchronously
+  const net::NetLog::ParametersCallback& parameters_callback =
+      net::NetLog::StringCallback("url", &url.spec());
+  PostBoundNetLogSecureProxyCheckEvent(
+      net_log, net::NetLog::TYPE_DATA_REDUCTION_PROXY_CANARY_REQUEST,
+      net::NetLog::PHASE_BEGIN,
+      DataReductionProxyEventStorageDelegate::CHECK_PENDING,
+      parameters_callback);
+}
+
+void DataReductionProxyEventCreator::EndSecureProxyCheck(
+    const net::BoundNetLog& net_log,
+    int net_error,
+    int http_response_code,
+    bool succeeded) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  const net::NetLog::ParametersCallback& parameters_callback = base::Bind(
+      &EndCanaryRequestCallback, net_error, http_response_code, succeeded);
+  PostBoundNetLogSecureProxyCheckEvent(
+      net_log, net::NetLog::TYPE_DATA_REDUCTION_PROXY_CANARY_REQUEST,
+      net::NetLog::PHASE_END,
+      net_error == 0 ? DataReductionProxyEventStorageDelegate::CHECK_SUCCESS
+                     : DataReductionProxyEventStorageDelegate::CHECK_FAILED,
+      parameters_callback);
+}
+
+void DataReductionProxyEventCreator::PostEnabledEvent(
+    net::NetLog* net_log,
+    net::NetLog::EventType type,
+    bool enabled,
+    const net::NetLog::ParametersCallback& callback) {
+  scoped_ptr<base::Value> event = BuildDataReductionProxyEvent(
+      type, net::NetLog::Source(), net::NetLog::PHASE_NONE, callback);
+  if (event)
+    storage_delegate_->AddEnabledEvent(event.Pass(), enabled);
+
+  if (net_log)
+    net_log->AddGlobalEntry(type, callback);
+}
+
+void DataReductionProxyEventCreator::PostBoundNetLogBypassEvent(
+    const net::BoundNetLog& net_log,
+    net::NetLog::EventType type,
+    net::NetLog::EventPhase phase,
+    int64 expiration_ticks,
+    const net::NetLog::ParametersCallback& callback) {
+  scoped_ptr<base::Value> event =
+      BuildDataReductionProxyEvent(type, net_log.source(), phase, callback);
+  if (event)
+    storage_delegate_->AddAndSetLastBypassEvent(event.Pass(), expiration_ticks);
+  net_log.AddEntry(type, phase, callback);
+}
+
+void DataReductionProxyEventCreator::PostBoundNetLogSecureProxyCheckEvent(
+    const net::BoundNetLog& net_log,
+    net::NetLog::EventType type,
+    net::NetLog::EventPhase phase,
+    DataReductionProxyEventStorageDelegate::SecureProxyCheckState state,
+    const net::NetLog::ParametersCallback& callback) {
+  scoped_ptr<base::Value> event(
+      BuildDataReductionProxyEvent(type, net_log.source(), phase, callback));
+  if (event)
+    storage_delegate_->AddEventAndSecureProxyCheckState(event.Pass(), state);
+  net_log.AddEntry(type, phase, callback);
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h
new file mode 100644
index 0000000..cd37e83
--- /dev/null
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h
@@ -0,0 +1,119 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_CREATOR_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_CREATOR_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
+#include "net/log/net_log.h"
+
+class GURL;
+
+namespace base {
+class TimeDelta;
+class Value;
+}
+
+namespace net {
+class BoundNetLog;
+}
+
+namespace data_reduction_proxy {
+
+// Central location for creating debug events for the Data Reduction Proxy.
+// This object lives on the IO thread and all of its methods are expected to be
+// called from there.
+class DataReductionProxyEventCreator {
+ public:
+  // Constructs a DataReductionProxyEventCreator object. |storage_delegate| must
+  // outlive |this| and can be used to store Data Reduction Proxy events for
+  // debugging without requiring a net::NetLog.
+  explicit DataReductionProxyEventCreator(
+      DataReductionProxyEventStorageDelegate* storage_delegate);
+
+  ~DataReductionProxyEventCreator();
+
+  // Adds the DATA_REDUCTION_PROXY_ENABLED event (with enabled=true) to the
+  // event store.
+  void AddProxyEnabledEvent(net::NetLog* net_log,
+                            bool primary_restricted,
+                            bool fallback_restricted,
+                            const std::string& primary_origin,
+                            const std::string& fallback_origin,
+                            const std::string& ssl_origin);
+
+  // Adds the DATA_REDUCTION_PROXY_ENABLED event (with enabled=false) to the
+  // event store.
+  void AddProxyDisabledEvent(net::NetLog* net_log);
+
+  // Adds a DATA_REDUCTION_PROXY_BYPASS_REQUESTED event to the event store
+  // when the bypass reason is initiated by the data reduction proxy.
+  void AddBypassActionEvent(const net::BoundNetLog& net_log,
+                            const std::string& bypass_action,
+                            const GURL& gurl,
+                            const base::TimeDelta& bypass_duration);
+
+  // Adds a DATA_REDUCTION_PROXY_BYPASS_REQUESTED event to the event store
+  // when the bypass reason is not initiated by the data reduction proxy, such
+  // as network errors.
+  void AddBypassTypeEvent(const net::BoundNetLog& net_log,
+                          DataReductionProxyBypassType bypass_type,
+                          const GURL& gurl,
+                          const base::TimeDelta& bypass_duration);
+
+  // Adds a DATA_REDUCTION_PROXY_CANARY_REQUEST event to the event store
+  // when the secure proxy request has started.
+  void BeginSecureProxyCheck(const net::BoundNetLog& net_log, const GURL& gurl);
+
+  // Adds a DATA_REDUCTION_PROXY_CANARY_REQUEST event to the event store
+  // when the secure proxy request has ended.
+  void EndSecureProxyCheck(const net::BoundNetLog& net_log,
+                           int net_error,
+                           int http_response_code,
+                           bool succeeded);
+
+ private:
+  // Prepare and post enabling/disabling proxy events for the event store on the
+  // a net::NetLog.
+  void PostEnabledEvent(net::NetLog* net_log,
+                        net::NetLog::EventType type,
+                        bool enable,
+                        const net::NetLog::ParametersCallback& callback);
+
+  // Prepare and post a Data Reduction Proxy bypass event for the event store
+  // on a BoundNetLog.
+  void PostBoundNetLogBypassEvent(
+      const net::BoundNetLog& net_log,
+      net::NetLog::EventType type,
+      net::NetLog::EventPhase phase,
+      int64 expiration_ticks,
+      const net::NetLog::ParametersCallback& callback);
+
+  // Prepare and post a secure proxy check event for the event store on a
+  // BoundNetLog.
+  void PostBoundNetLogSecureProxyCheckEvent(
+      const net::BoundNetLog& net_log,
+      net::NetLog::EventType type,
+      net::NetLog::EventPhase phase,
+      DataReductionProxyEventStorageDelegate::SecureProxyCheckState state,
+      const net::NetLog::ParametersCallback& callback);
+
+  // Must outlive |this|. Used for posting calls to the UI thread.
+  DataReductionProxyEventStorageDelegate* storage_delegate_;
+
+  // Enforce usage on the IO thread.
+  base::ThreadChecker thread_checker_;
+
+  DISALLOW_COPY_AND_ASSIGN(DataReductionProxyEventCreator);
+};
+
+}  // namespace data_reduction_proxy
+#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_CREATOR_H_
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h
new file mode 100644
index 0000000..d80bcaf
--- /dev/null
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h
@@ -0,0 +1,42 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORAGE_DELEGATE_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORAGE_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class Value;
+}
+
+namespace data_reduction_proxy {
+
+// Defines an interface for storing Data Reduction Proxy events.
+class DataReductionProxyEventStorageDelegate {
+ public:
+  enum SecureProxyCheckState {
+    CHECK_UNKNOWN,
+    CHECK_PENDING,
+    CHECK_SUCCESS,
+    CHECK_FAILED,
+  };
+
+  // Stores a DATA_REDUCTION_PROXY_ENABLED event.
+  virtual void AddEnabledEvent(scoped_ptr<base::Value> event, bool enabled) = 0;
+
+  // Stores a DATA_REDUCTION_PROXY_BYPASS_REQUESTED event.
+  virtual void AddAndSetLastBypassEvent(scoped_ptr<base::Value> event,
+                                        int64 expiration_ticks) = 0;
+
+  // Stores a DATA_REDUCTION_PROXY_CANARY_REQUEST event.
+  virtual void AddEventAndSecureProxyCheckState(
+      scoped_ptr<base::Value> event,
+      SecureProxyCheckState state) = 0;
+};
+
+}  // namespace data_reduction_proxy
+
+#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORAGE_DELEGATE_H_
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.cc
new file mode 100644
index 0000000..a20a68e
--- /dev/null
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.cc
@@ -0,0 +1,49 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h"
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
+
+namespace data_reduction_proxy {
+
+TestDataReductionProxyEventStorageDelegate::
+    TestDataReductionProxyEventStorageDelegate()
+    : delegate_(nullptr) {
+}
+
+TestDataReductionProxyEventStorageDelegate::
+    ~TestDataReductionProxyEventStorageDelegate() {
+}
+
+void TestDataReductionProxyEventStorageDelegate::SetStorageDelegate(
+    DataReductionProxyEventStorageDelegate* delegate) {
+  delegate_ = delegate;
+}
+
+void TestDataReductionProxyEventStorageDelegate::AddEnabledEvent(
+    scoped_ptr<base::Value> event,
+    bool enabled) {
+  if (delegate_)
+    delegate_->AddEnabledEvent(event.Pass(), enabled);
+}
+
+void TestDataReductionProxyEventStorageDelegate::AddAndSetLastBypassEvent(
+    scoped_ptr<base::Value> event,
+    int64 expiration_ticks) {
+  if (delegate_)
+    delegate_->AddAndSetLastBypassEvent(event.Pass(), expiration_ticks);
+}
+
+void TestDataReductionProxyEventStorageDelegate::
+    AddEventAndSecureProxyCheckState(scoped_ptr<base::Value> event,
+                                     SecureProxyCheckState state) {
+  if (delegate_)
+    delegate_->AddEventAndSecureProxyCheckState(event.Pass(), state);
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h
new file mode 100644
index 0000000..65d3116
--- /dev/null
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORE_TEST_UTILS_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORE_TEST_UTILS_H_
+
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class Value;
+}
+
+namespace data_reduction_proxy {
+
+class TestDataReductionProxyEventStorageDelegate
+    : public DataReductionProxyEventStorageDelegate {
+ public:
+  TestDataReductionProxyEventStorageDelegate();
+
+  virtual ~TestDataReductionProxyEventStorageDelegate();
+
+  // Sets |delegate_| at a later point in time.
+  void SetStorageDelegate(DataReductionProxyEventStorageDelegate* delegate);
+
+  // Overrides of DataReductionProxyEventStorageDelegate:
+  void AddEnabledEvent(scoped_ptr<base::Value> event, bool enabled) override;
+  void AddAndSetLastBypassEvent(scoped_ptr<base::Value> event,
+                                int64 expiration_ticks) override;
+  void AddEventAndSecureProxyCheckState(scoped_ptr<base::Value> event,
+                                        SecureProxyCheckState state) override;
+
+ private:
+  // If not null, |this| will send DataReductionProxyEventStorageDelegate
+  // calls to |delegate_|.
+  DataReductionProxyEventStorageDelegate* delegate_;
+};
+
+}  // namespace data_reduction_proxy
+
+#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORE_TEST_UTILS_H_
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
index ef12af5..b0734b61 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
@@ -5,19 +5,10 @@
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
 
 #include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "base/values.h"
-#include "net/base/host_port_pair.h"
-#include "net/log/net_log.h"
-#include "net/proxy/proxy_server.h"
-#include "url/gurl.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
 
 namespace {
 
@@ -35,94 +26,6 @@
 #undef BYPASS_EVENT_TYPE
 };
 
-scoped_ptr<base::Value> BuildDataReductionProxyEvent(
-    net::NetLog::EventType type,
-    const net::NetLog::Source& source,
-    net::NetLog::EventPhase phase,
-    const net::NetLog::ParametersCallback& parameters_callback) {
-  base::TimeTicks ticks_now = base::TimeTicks::Now();
-  net::NetLog::EntryData entry_data(
-      type, source, phase, ticks_now, &parameters_callback);
-  net::NetLog::Entry entry(&entry_data, net::NetLog::LOG_ALL);
-  scoped_ptr<base::Value> entry_value(entry.ToValue());
-
-  return entry_value;
-}
-
-int64 GetExpirationTicks(int bypass_seconds) {
-  base::TimeTicks ticks_now = base::TimeTicks::Now();
-  base::TimeTicks expiration_ticks =
-      ticks_now + base::TimeDelta::FromSeconds(bypass_seconds);
-  return (expiration_ticks - base::TimeTicks()).InMilliseconds();
-}
-
-// The following method creates a string resembling the output of
-// net::ProxyServer::ToURI().
-std::string GetNormalizedProxyString(const std::string& proxy_origin) {
-  net::ProxyServer proxy_server = net::ProxyServer::FromURI(
-    proxy_origin, net::ProxyServer::SCHEME_HTTP);
-  if (proxy_server.is_valid())
-    return proxy_origin;
-  else
-    return std::string();
-}
-
-// The following callbacks create a base::Value which contains information
-// about various data reduction proxy events. Ownership of the base::Value is
-// passed to the caller.
-base::Value* EnableDataReductionProxyCallback(
-    bool primary_restricted,
-    bool fallback_restricted,
-    const std::string& primary_origin,
-    const std::string& fallback_origin,
-    const std::string& ssl_origin,
-    net::NetLog::LogLevel /* log_level */) {
-  base::DictionaryValue* dict = new base::DictionaryValue();
-  dict->SetBoolean("enabled", true);
-  dict->SetBoolean("primary_restricted", primary_restricted);
-  dict->SetBoolean("fallback_restricted", fallback_restricted);
-  dict->SetString("primary_origin", GetNormalizedProxyString(primary_origin));
-  dict->SetString("fallback_origin", GetNormalizedProxyString(fallback_origin));
-  dict->SetString("ssl_origin", GetNormalizedProxyString(ssl_origin));
-  return dict;
-}
-
-base::Value* DisableDataReductionProxyCallback(
-    net::NetLog::LogLevel /* log_level */) {
-  base::DictionaryValue* dict = new base::DictionaryValue();
-  dict->SetBoolean("enabled", false);
-  return dict;
-}
-
-base::Value* UrlBypassActionCallback(const std::string& action,
-                                     const GURL& url,
-                                     int bypass_seconds,
-                                     int64 expiration_ticks,
-                                     net::NetLog::LogLevel /* log_level */) {
-  base::DictionaryValue* dict = new base::DictionaryValue();
-  dict->SetString("action", action);
-  dict->SetString("url", url.spec());
-  dict->SetString("bypass_duration_seconds",
-                  base::Int64ToString(bypass_seconds));
-  dict->SetString("expiration", base::Int64ToString(expiration_ticks));
-  return dict;
-}
-
-base::Value* UrlBypassTypeCallback(
-    data_reduction_proxy::DataReductionProxyBypassType bypass_type,
-    const GURL& url,
-    int bypass_seconds,
-    int64 expiration_ticks,
-    net::NetLog::LogLevel /* log_level */) {
-  base::DictionaryValue* dict = new base::DictionaryValue();
-  dict->SetInteger("bypass_type", bypass_type);
-  dict->SetString("url", url.spec());
-  dict->SetString("bypass_duration_seconds",
-                  base::Int64ToString(bypass_seconds));
-  dict->SetString("expiration", base::Int64ToString(expiration_ticks));
-  return dict;
-}
-
 }  // namespace
 
 namespace data_reduction_proxy {
@@ -140,10 +43,8 @@
   constants_dict->Set("dataReductionProxyBypassEventType", dict);
 }
 
-DataReductionProxyEventStore::DataReductionProxyEventStore(
-    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
-    : ui_task_runner_(ui_task_runner),
-      enabled_(false),
+DataReductionProxyEventStore::DataReductionProxyEventStore()
+    : enabled_(false),
       secure_proxy_check_state_(CHECK_UNKNOWN),
       expiration_ticks_(0) {
 }
@@ -152,159 +53,8 @@
   STLDeleteElements(&stored_events_);
 }
 
-void DataReductionProxyEventStore::AddProxyEnabledEvent(
-    net::NetLog* net_log,
-    bool primary_restricted,
-    bool fallback_restricted,
-    const std::string& primary_origin,
-    const std::string& fallback_origin,
-    const std::string& ssl_origin) {
-  const net::NetLog::ParametersCallback& parameters_callback =
-      base::Bind(&EnableDataReductionProxyCallback, primary_restricted,
-                 fallback_restricted, primary_origin, fallback_origin,
-                 ssl_origin);
-  PostEnabledEvent(net_log,
-                   net::NetLog::TYPE_DATA_REDUCTION_PROXY_ENABLED,
-                   true,
-                   parameters_callback);
-}
-
-void DataReductionProxyEventStore::AddProxyDisabledEvent(
-    net::NetLog* net_log) {
-  const net::NetLog::ParametersCallback& parameters_callback =
-      base::Bind(&DisableDataReductionProxyCallback);
-  PostEnabledEvent(net_log,
-                   net::NetLog::TYPE_DATA_REDUCTION_PROXY_ENABLED,
-                   false,
-                   parameters_callback);
-}
-
-void DataReductionProxyEventStore::AddBypassActionEvent(
-    const net::BoundNetLog& net_log,
-    const std::string& bypass_action,
-    const GURL& url,
-    const base::TimeDelta& bypass_duration) {
-  int64 expiration_ticks = GetExpirationTicks(bypass_duration.InSeconds());
-  const net::NetLog::ParametersCallback& parameters_callback =
-      base::Bind(&UrlBypassActionCallback, bypass_action, url,
-                 bypass_duration.InSeconds(), expiration_ticks);
-  PostBoundNetLogBypassEvent(
-      net_log,
-      net::NetLog::TYPE_DATA_REDUCTION_PROXY_BYPASS_REQUESTED,
-      net::NetLog::PHASE_NONE,
-      expiration_ticks,
-      parameters_callback);
-}
-
-void DataReductionProxyEventStore::AddBypassTypeEvent(
-    const net::BoundNetLog& net_log,
-    DataReductionProxyBypassType bypass_type,
-    const GURL& url,
-    const base::TimeDelta& bypass_duration) {
-  int64 expiration_ticks = GetExpirationTicks(bypass_duration.InSeconds());
-  const net::NetLog::ParametersCallback& parameters_callback =
-      base::Bind(&UrlBypassTypeCallback, bypass_type, url,
-                 bypass_duration.InSeconds(), expiration_ticks);
-  PostBoundNetLogBypassEvent(
-      net_log,
-      net::NetLog::TYPE_DATA_REDUCTION_PROXY_BYPASS_REQUESTED,
-      net::NetLog::PHASE_NONE,
-      expiration_ticks,
-      parameters_callback);
-}
-
-void DataReductionProxyEventStore::BeginSecureProxyCheck(
-    const net::BoundNetLog& net_log,
-    const GURL& url) {
-  // This callback must be invoked synchronously
-  const net::NetLog::ParametersCallback& parameters_callback =
-      net::NetLog::StringCallback("url", &url.spec());
-  PostBoundNetLogSecureProxyCheckEvent(
-      net_log,
-      net::NetLog::TYPE_DATA_REDUCTION_PROXY_CANARY_REQUEST,
-      net::NetLog::PHASE_BEGIN,
-      CHECK_PENDING,
-      parameters_callback);
-}
-
-void DataReductionProxyEventStore::EndSecureProxyCheck(
-    const net::BoundNetLog& net_log,
-    int net_error) {
-  const net::NetLog::ParametersCallback& parameters_callback =
-      net::NetLog::IntegerCallback("net_error", net_error);
-  PostBoundNetLogSecureProxyCheckEvent(
-      net_log,
-      net::NetLog::TYPE_DATA_REDUCTION_PROXY_CANARY_REQUEST,
-      net::NetLog::PHASE_END,
-      net_error == 0 ? CHECK_SUCCESS : CHECK_FAILED,
-      parameters_callback);
-}
-
-void DataReductionProxyEventStore::PostEnabledEvent(
-    net::NetLog* net_log,
-    net::NetLog::EventType type,
-    bool enabled,
-    const net::NetLog::ParametersCallback& callback) {
-  scoped_ptr<base::Value> event = BuildDataReductionProxyEvent(
-      type, net::NetLog::Source(), net::NetLog::PHASE_NONE, callback);
-  if (event.get()) {
-    ui_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&DataReductionProxyEventStore::AddEnabledEventOnUIThread,
-                   base::Unretained(this),
-                   base::Passed(&event),
-                   enabled));
-  }
-
-  if (net_log)
-    net_log->AddGlobalEntry(type, callback);
-}
-
-void DataReductionProxyEventStore::PostBoundNetLogBypassEvent(
-    const net::BoundNetLog& net_log,
-    net::NetLog::EventType type,
-    net::NetLog::EventPhase phase,
-    int64 expiration_ticks,
-    const net::NetLog::ParametersCallback& callback) {
-  scoped_ptr<base::Value> event = BuildDataReductionProxyEvent(
-      type, net_log.source(), phase, callback);
-  if (event.get()) {
-    ui_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(
-            &DataReductionProxyEventStore::AddAndSetLastBypassEventOnUIThread,
-            base::Unretained(this),
-            base::Passed(&event),
-            expiration_ticks));
-  }
-
-  net_log.AddEntry(type, phase, callback);
-}
-
-void DataReductionProxyEventStore::PostBoundNetLogSecureProxyCheckEvent(
-    const net::BoundNetLog& net_log,
-    net::NetLog::EventType type,
-    net::NetLog::EventPhase phase,
-    SecureProxyCheckState state,
-    const net::NetLog::ParametersCallback& callback) {
-  scoped_ptr<base::Value> event(
-      BuildDataReductionProxyEvent(type, net_log.source(), phase, callback));
-  if (event.get()) {
-    ui_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(
-            &DataReductionProxyEventStore::
-                AddEventAndSecureProxyCheckStateOnUIThread,
-            base::Unretained(this),
-            base::Passed(&event),
-            state));
-  }
-  net_log.AddEntry(type, phase, callback);
-}
-
 base::Value* DataReductionProxyEventStore::GetSummaryValue() const {
-  DCHECK(ui_task_runner_->BelongsToCurrentThread());
-
+  DCHECK(thread_checker_.CalledOnValidThread());
   scoped_ptr<base::DictionaryValue> data_reduction_proxy_values(
       new base::DictionaryValue());
   data_reduction_proxy_values->SetBoolean("enabled", enabled_);
@@ -351,9 +101,7 @@
   return data_reduction_proxy_values.release();
 }
 
-void DataReductionProxyEventStore::AddEventOnUIThread(
-    scoped_ptr<base::Value> entry) {
-  DCHECK(ui_task_runner_->BelongsToCurrentThread());
+void DataReductionProxyEventStore::AddEvent(scoped_ptr<base::Value> entry) {
   if (stored_events_.size() == kMaxEventsToStore) {
     base::Value* head = stored_events_.front();
     stored_events_.pop_front();
@@ -363,33 +111,33 @@
   stored_events_.push_back(entry.release());
 }
 
-void DataReductionProxyEventStore::AddEnabledEventOnUIThread(
+void DataReductionProxyEventStore::AddEnabledEvent(
     scoped_ptr<base::Value> entry,
     bool enabled) {
-  DCHECK(ui_task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   enabled_ = enabled;
   if (enabled)
     current_configuration_.reset(entry->DeepCopy());
   else
     current_configuration_.reset();
-  AddEventOnUIThread(entry.Pass());
+  AddEvent(entry.Pass());
 }
 
-void DataReductionProxyEventStore::AddEventAndSecureProxyCheckStateOnUIThread(
+void DataReductionProxyEventStore::AddEventAndSecureProxyCheckState(
     scoped_ptr<base::Value> entry,
     SecureProxyCheckState state) {
-  DCHECK(ui_task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   secure_proxy_check_state_ = state;
-  AddEventOnUIThread(entry.Pass());
+  AddEvent(entry.Pass());
 }
 
-void DataReductionProxyEventStore::AddAndSetLastBypassEventOnUIThread(
+void DataReductionProxyEventStore::AddAndSetLastBypassEvent(
     scoped_ptr<base::Value> entry,
     int64 expiration_ticks) {
-  DCHECK(ui_task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   last_bypass_event_.reset(entry->DeepCopy());
   expiration_ticks_ = expiration_ticks;
-  AddEventOnUIThread(entry.Pass());
+  AddEvent(entry.Pass());
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h
index ff3e3ea..e55eb04 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h
@@ -6,89 +6,33 @@
 #define COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_EVENT_STORE_H_
 
 #include <deque>
-#include <string>
 
 #include "base/basictypes.h"
 #include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/values.h"
+#include "base/threading/thread_checker.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
-#include "net/log/net_log.h"
-
-class GURL;
 
 namespace base {
-class SingleThreadTaskRunner;
+class DictionaryValue;
 class TimeDelta;
 class Value;
 }
 
-namespace net {
-class BoundNetLog;
-class NetLog;
-}
-
 namespace data_reduction_proxy {
 
-enum SecureProxyCheckState {
-  CHECK_UNKNOWN,
-  CHECK_PENDING,
-  CHECK_SUCCESS,
-  CHECK_FAILED,
-};
-
-class DataReductionProxyEventStore {
+class DataReductionProxyEventStore
+    : public DataReductionProxyEventStorageDelegate {
  public:
   // Adds data reduction proxy specific constants to the net_internals
   // constants dictionary.
   static void AddConstants(base::DictionaryValue* constants_dict);
 
-  // Constructs a DataReductionProxyEventStore object with the given UI
-  // task runner.
-  explicit DataReductionProxyEventStore(
-      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner);
+  // Constructs a DataReductionProxyEventStore object
+  explicit DataReductionProxyEventStore();
 
-  ~DataReductionProxyEventStore();
-
-  // Adds the DATA_REDUCTION_PROXY_ENABLED event (with enabled=true) to the
-  // event store.
-  void AddProxyEnabledEvent(
-      net::NetLog* net_log,
-      bool primary_restricted,
-      bool fallback_restricted,
-      const std::string& primary_origin,
-      const std::string& fallback_origin,
-      const std::string& ssl_origin);
-
-  // Adds the DATA_REDUCTION_PROXY_ENABLED event (with enabled=false) to the
-  // event store.
-  void AddProxyDisabledEvent(net::NetLog* net_log);
-
-  // Adds a DATA_REDUCTION_PROXY_BYPASS_REQUESTED event to the event store
-  // when the bypass reason is initiated by the data reduction proxy.
-  void AddBypassActionEvent(
-      const net::BoundNetLog& net_log,
-      const std::string& bypass_action,
-      const GURL& gurl,
-      const base::TimeDelta& bypass_duration);
-
-  // Adds a DATA_REDUCTION_PROXY_BYPASS_REQUESTED event to the event store
-  // when the bypass reason is not initiated by the data reduction proxy, such
-  // as network errors.
-  void AddBypassTypeEvent(
-      const net::BoundNetLog& net_log,
-      DataReductionProxyBypassType bypass_type,
-      const GURL& gurl,
-      const base::TimeDelta& bypass_duration);
-
-  // Adds a DATA_REDUCTION_PROXY_CANARY_REQUEST event to the event store
-  // when the secure proxy request has started.
-  void BeginSecureProxyCheck(const net::BoundNetLog& net_log, const GURL& gurl);
-
-  // Adds a DATA_REDUCTION_PROXY_CANARY_REQUEST event to the event store
-  // when the secure proxy request has ended.
-  void EndSecureProxyCheck(const net::BoundNetLog& net_log, int net_error);
+  virtual ~DataReductionProxyEventStore();
 
   // Creates a Value summary of Data Reduction Proxy related information:
   // - Whether the proxy is enabled
@@ -98,6 +42,22 @@
   // The caller is responsible for deleting the returned value.
   base::Value* GetSummaryValue() const;
 
+  // Override of DataReductionProxyEventStorageDelegate.
+  // Put |entry| on the deque of stored events and set |current_configuration_|.
+  void AddEnabledEvent(scoped_ptr<base::Value> entry, bool enabled) override;
+
+  // Override of DataReductionProxyEventStorageDelegate.
+  // Put |entry| on a deque of events to store and set
+  // |secure_proxy_check_state_|
+  void AddEventAndSecureProxyCheckState(scoped_ptr<base::Value> entry,
+                                        SecureProxyCheckState state) override;
+
+  // Override of DataReductionProxyEventStorageDelegate.
+  // Put |entry| on a deque of events to store and set |last_bypass_event_| and
+  // |expiration_ticks_|
+  void AddAndSetLastBypassEvent(scoped_ptr<base::Value> entry,
+                                int64 expiration_ticks) override;
+
  private:
   friend class DataReductionProxyEventStoreTest;
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyEventStoreTest,
@@ -113,50 +73,9 @@
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyEventStoreTest,
                            TestEndSecureProxyCheck);
 
-  // Prepare and post enabling/disabling proxy events for the event_store on the
-  // global net_log.
-  void PostEnabledEvent(net::NetLog* net_log,
-                        net::NetLog::EventType type,
-                        bool enable,
-                        const net::NetLog::ParametersCallback& callback);
-
-  // Prepare and post a Data Reduction Proxy bypass event for the event_store
-  // on a BoundNetLog.
-  void PostBoundNetLogBypassEvent(
-      const net::BoundNetLog& net_log,
-      net::NetLog::EventType type,
-      net::NetLog::EventPhase phase,
-      int64 expiration_ticks,
-      const net::NetLog::ParametersCallback& callback);
-
-  // Prepare and post a secure proxy check event for the event_store on a
-  // BoundNetLog.
-  void PostBoundNetLogSecureProxyCheckEvent(
-      const net::BoundNetLog& net_log,
-      net::NetLog::EventType type,
-      net::NetLog::EventPhase phase,
-      SecureProxyCheckState state,
-      const net::NetLog::ParametersCallback& callback);
-
   // Put |entry| on a deque of events to store
-  void AddEventOnUIThread(scoped_ptr<base::Value> entry);
+  void AddEvent(scoped_ptr<base::Value> entry);
 
-  // Put |entry| on the deque of stored events and set |current_configuration_|.
-  void AddEnabledEventOnUIThread(scoped_ptr<base::Value> entry, bool enabled);
-
-  // Put |entry| on a deque of events to store and set
-  // |secure_proxy_check_state_|
-  void AddEventAndSecureProxyCheckStateOnUIThread(scoped_ptr<base::Value> entry,
-                                                  SecureProxyCheckState state);
-
-  // Put |entry| on a deque of events to store and set |last_bypass_event_| and
-  // |expiration_ticks_|
-  void AddAndSetLastBypassEventOnUIThread(scoped_ptr<base::Value> entry,
-                                          int64 expiration_ticks);
-
-  // A task runner to ensure that all reads/writes to |stored_events_| takes
-  // place on the UI thread.
-  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
   // A deque of data reduction proxy related events. It is used as a circular
   // buffer to prevent unbounded memory utilization.
   std::deque<base::Value*> stored_events_;
@@ -171,6 +90,9 @@
   // The expiration time of the |last_bypass_event_|.
   int64 expiration_ticks_;
 
+  // Enforce usage on the UI thread.
+  base::ThreadChecker thread_checker_;
+
   DISALLOW_COPY_AND_ASSIGN(DataReductionProxyEventStore);
 };
 
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc
index 6f266dd..05c996bb 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc
@@ -5,11 +5,12 @@
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
 
 #include "base/bind.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
+#include "net/http/http_status_code.h"
 #include "net/log/net_log.h"
 #include "net/log/test_net_log.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -18,16 +19,15 @@
 
 class DataReductionProxyEventStoreTest : public testing::Test {
  public:
-  DataReductionProxyEventStoreTest()
-      : task_runner_(scoped_refptr<base::TestSimpleTaskRunner>(
-            new base::TestSimpleTaskRunner())),
-        net_log_(new net::TestNetLog()) {
+  DataReductionProxyEventStoreTest() : net_log_(new net::TestNetLog()) {
     bound_net_log_ = net::BoundNetLog::Make(
         net_log_.get(), net::NetLog::SOURCE_DATA_REDUCTION_PROXY);
   }
 
   void SetUp() override {
-    proxy_.reset(new DataReductionProxyEventStore(task_runner_));
+    event_store_.reset(new DataReductionProxyEventStore());
+    event_creator_.reset(
+        new DataReductionProxyEventCreator(event_store_.get()));
   }
 
   net::TestNetLog::CapturedEntry GetSingleEntry() const {
@@ -37,12 +37,10 @@
     return entries[0];
   }
 
-  DataReductionProxyEventStore* proxy() {
-    return proxy_.get();
-  }
+  DataReductionProxyEventStore* event_store() { return event_store_.get(); }
 
-  base::TestSimpleTaskRunner* task_runner() {
-    return task_runner_.get();
+  DataReductionProxyEventCreator* event_creator() {
+    return event_creator_.get();
   }
 
   net::TestNetLog* net_log() { return net_log_.get(); }
@@ -52,87 +50,84 @@
   }
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
   scoped_ptr<net::TestNetLog> net_log_;
-  scoped_ptr<DataReductionProxyEventStore> proxy_;
+  scoped_ptr<DataReductionProxyEventStore> event_store_;
+  scoped_ptr<DataReductionProxyEventCreator> event_creator_;
   net::BoundNetLog bound_net_log_;
 };
 
 TEST_F(DataReductionProxyEventStoreTest, TestAddProxyEnabledEvent) {
-  EXPECT_EQ(0u, proxy()->stored_events_.size());
-  proxy()->AddProxyEnabledEvent(
-                                net_log(), false, false,
-      TestDataReductionProxyParams::DefaultOrigin(),
+  EXPECT_EQ(0u, event_store()->stored_events_.size());
+  event_creator()->AddProxyEnabledEvent(
+      net_log(), false, false, TestDataReductionProxyParams::DefaultOrigin(),
       TestDataReductionProxyParams::DefaultFallbackOrigin(),
       TestDataReductionProxyParams::DefaultSSLOrigin());
-  task_runner()->RunPendingTasks();
-  EXPECT_EQ(1u, proxy()->stored_events_.size());
+  EXPECT_EQ(1u, event_store()->stored_events_.size());
   net::TestNetLog::CapturedEntry entry = GetSingleEntry();
   EXPECT_EQ(net::NetLog::TYPE_DATA_REDUCTION_PROXY_ENABLED,
             entry.type);
 }
 
 TEST_F(DataReductionProxyEventStoreTest, TestAddProxyDisabledEvent) {
-  EXPECT_EQ(0u, proxy()->stored_events_.size());
-  proxy()->AddProxyDisabledEvent(net_log());
-  task_runner()->RunPendingTasks();
-  EXPECT_EQ(1u, proxy()->stored_events_.size());
+  EXPECT_EQ(0u, event_store()->stored_events_.size());
+  event_creator()->AddProxyDisabledEvent(net_log());
+  EXPECT_EQ(1u, event_store()->stored_events_.size());
   net::TestNetLog::CapturedEntry entry = GetSingleEntry();
   EXPECT_EQ(net::NetLog::TYPE_DATA_REDUCTION_PROXY_ENABLED,
             entry.type);
 }
 
 TEST_F(DataReductionProxyEventStoreTest, TestAddBypassActionEvent) {
-  EXPECT_EQ(0u, proxy()->stored_events_.size());
-  EXPECT_EQ(nullptr, proxy()->last_bypass_event_.get());
-  proxy()->AddBypassActionEvent(bound_net_log(), "bypass", GURL(),
-                                base::TimeDelta::FromMinutes(1));
-  task_runner()->RunPendingTasks();
-  EXPECT_EQ(1u, proxy()->stored_events_.size());
+  EXPECT_EQ(0u, event_store()->stored_events_.size());
+  EXPECT_EQ(nullptr, event_store()->last_bypass_event_.get());
+  event_creator()->AddBypassActionEvent(bound_net_log(), "bypass", GURL(),
+                                        base::TimeDelta::FromMinutes(1));
+  EXPECT_EQ(1u, event_store()->stored_events_.size());
   net::TestNetLog::CapturedEntry entry = GetSingleEntry();
   EXPECT_EQ(net::NetLog::TYPE_DATA_REDUCTION_PROXY_BYPASS_REQUESTED,
             entry.type);
-  EXPECT_NE(nullptr, proxy()->last_bypass_event_.get());
+  EXPECT_NE(nullptr, event_store()->last_bypass_event_.get());
 }
 
 TEST_F(DataReductionProxyEventStoreTest, TestAddBypassTypeEvent) {
-  EXPECT_EQ(0u, proxy()->stored_events_.size());
-  EXPECT_EQ(nullptr, proxy()->last_bypass_event_.get());
-  proxy()->AddBypassTypeEvent(bound_net_log(), BYPASS_EVENT_TYPE_LONG, GURL(),
-                              base::TimeDelta::FromMinutes(1));
-  task_runner()->RunPendingTasks();
-  EXPECT_EQ(1u, proxy()->stored_events_.size());
+  EXPECT_EQ(0u, event_store()->stored_events_.size());
+  EXPECT_EQ(nullptr, event_store()->last_bypass_event_.get());
+  event_creator()->AddBypassTypeEvent(bound_net_log(), BYPASS_EVENT_TYPE_LONG,
+                                      GURL(), base::TimeDelta::FromMinutes(1));
+  EXPECT_EQ(1u, event_store()->stored_events_.size());
   EXPECT_EQ(1u, net_log()->GetSize());
   net::TestNetLog::CapturedEntry entry = GetSingleEntry();
   EXPECT_EQ(net::NetLog::TYPE_DATA_REDUCTION_PROXY_BYPASS_REQUESTED,
             entry.type);
-  EXPECT_NE(nullptr, proxy()->last_bypass_event_.get());
+  EXPECT_NE(nullptr, event_store()->last_bypass_event_.get());
 }
 
 TEST_F(DataReductionProxyEventStoreTest, TestBeginSecureProxyCheck) {
-  EXPECT_EQ(0u, proxy()->stored_events_.size());
-  EXPECT_EQ(CHECK_UNKNOWN, proxy()->secure_proxy_check_state_);
-  proxy()->BeginSecureProxyCheck(bound_net_log(), GURL());
-  task_runner()->RunPendingTasks();
-  EXPECT_EQ(1u, proxy()->stored_events_.size());
+  EXPECT_EQ(0u, event_store()->stored_events_.size());
+  EXPECT_EQ(DataReductionProxyEventStorageDelegate::CHECK_UNKNOWN,
+            event_store()->secure_proxy_check_state_);
+  event_creator()->BeginSecureProxyCheck(bound_net_log(), GURL());
+  EXPECT_EQ(1u, event_store()->stored_events_.size());
   EXPECT_EQ(1u, net_log()->GetSize());
   net::TestNetLog::CapturedEntry entry = GetSingleEntry();
   EXPECT_EQ(net::NetLog::TYPE_DATA_REDUCTION_PROXY_CANARY_REQUEST,
             entry.type);
-  EXPECT_EQ(CHECK_PENDING, proxy()->secure_proxy_check_state_);
+  EXPECT_EQ(DataReductionProxyEventStorageDelegate::CHECK_PENDING,
+            event_store()->secure_proxy_check_state_);
 }
 
 TEST_F(DataReductionProxyEventStoreTest, TestEndSecureProxyCheck) {
-  EXPECT_EQ(0u, proxy()->stored_events_.size());
-  EXPECT_EQ(CHECK_UNKNOWN, proxy()->secure_proxy_check_state_);
-  proxy()->EndSecureProxyCheck(bound_net_log(), 0);
-  task_runner()->RunPendingTasks();
-  EXPECT_EQ(1u, proxy()->stored_events_.size());
+  EXPECT_EQ(0u, event_store()->stored_events_.size());
+  EXPECT_EQ(DataReductionProxyEventStorageDelegate::CHECK_UNKNOWN,
+            event_store()->secure_proxy_check_state_);
+  event_creator()->EndSecureProxyCheck(bound_net_log(), 0, net::HTTP_OK, true);
+  EXPECT_EQ(1u, event_store()->stored_events_.size());
   EXPECT_EQ(1u, net_log()->GetSize());
   net::TestNetLog::CapturedEntry entry = GetSingleEntry();
   EXPECT_EQ(net::NetLog::TYPE_DATA_REDUCTION_PROXY_CANARY_REQUEST,
             entry.type);
-  EXPECT_EQ(CHECK_SUCCESS, proxy()->secure_proxy_check_state_);
+  EXPECT_EQ(DataReductionProxyEventStorageDelegate::CHECK_SUCCESS,
+            event_store()->secure_proxy_check_state_);
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
index e555cff..12e4c768 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -12,7 +12,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_status_code.h"
 
@@ -111,13 +111,14 @@
   return false;
 }
 
-bool ParseHeadersAndSetProxyInfo(const net::HttpResponseHeaders* headers,
-                                 const GURL& url,
-                                 const net::BoundNetLog& bound_net_log,
-                                 DataReductionProxyInfo* proxy_info,
-                                 DataReductionProxyEventStore* event_store) {
+bool ParseHeadersAndSetProxyInfo(
+    const net::HttpResponseHeaders* headers,
+    const GURL& url,
+    const net::BoundNetLog& bound_net_log,
+    DataReductionProxyInfo* proxy_info,
+    DataReductionProxyEventCreator* event_creator) {
   DCHECK(proxy_info);
-  DCHECK(event_store);
+  DCHECK(event_creator);
 
   // Support header of the form Chrome-Proxy: bypass|block=<duration>, where
   // <duration> is the number of seconds to wait before retrying
@@ -134,8 +135,8 @@
           headers, kChromeProxyActionBlock, &proxy_info->bypass_duration)) {
     proxy_info->bypass_all = true;
     proxy_info->mark_proxies_as_bad = true;
-    event_store->AddBypassActionEvent(bound_net_log, kChromeProxyActionBlock,
-                                      url, proxy_info->bypass_duration);
+    event_creator->AddBypassActionEvent(bound_net_log, kChromeProxyActionBlock,
+                                        url, proxy_info->bypass_duration);
     return true;
   }
 
@@ -144,8 +145,8 @@
           headers, kChromeProxyActionBypass, &proxy_info->bypass_duration)) {
     proxy_info->bypass_all = false;
     proxy_info->mark_proxies_as_bad = true;
-    event_store->AddBypassActionEvent(bound_net_log, kChromeProxyActionBypass,
-                                      url, proxy_info->bypass_duration);
+    event_creator->AddBypassActionEvent(bound_net_log, kChromeProxyActionBypass,
+                                        url, proxy_info->bypass_duration);
     return true;
   }
 
@@ -159,9 +160,9 @@
     proxy_info->bypass_all = true;
     proxy_info->mark_proxies_as_bad = false;
     proxy_info->bypass_duration = TimeDelta();
-    event_store->AddBypassActionEvent(bound_net_log,
-                                      kChromeProxyActionBlockOnce, url,
-                                      proxy_info->bypass_duration);
+    event_creator->AddBypassActionEvent(bound_net_log,
+                                        kChromeProxyActionBlockOnce, url,
+                                        proxy_info->bypass_duration);
     return true;
   }
 
@@ -198,14 +199,11 @@
     const GURL& url,
     const net::BoundNetLog& bound_net_log,
     DataReductionProxyInfo* data_reduction_proxy_info,
-    DataReductionProxyEventStore* event_store,
+    DataReductionProxyEventCreator* event_creator,
     bool* event_logged) {
   DCHECK(data_reduction_proxy_info);
-  if (ParseHeadersAndSetProxyInfo(headers,
-                                  url,
-                                  bound_net_log,
-                                  data_reduction_proxy_info,
-                                  event_store)) {
+  if (ParseHeadersAndSetProxyInfo(headers, url, bound_net_log,
+                                  data_reduction_proxy_info, event_creator)) {
     *event_logged = true;
 
     // A chrome-proxy response header is only present in a 502. For proper
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
index 3df14963..3d37778 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -21,7 +21,7 @@
 
 namespace data_reduction_proxy {
 
-class DataReductionProxyEventStore;
+class DataReductionProxyEventCreator;
 
 // Values of the UMA DataReductionProxy.BypassType{Primary|Fallback} and
 // DataReductionProxy.BlockType{Primary|Fallback} histograms. This enum must
@@ -61,7 +61,7 @@
                                  const GURL& url,
                                  const net::BoundNetLog& bound_net_log,
                                  DataReductionProxyInfo* proxy_info,
-                                 DataReductionProxyEventStore* event_store);
+                                 DataReductionProxyEventCreator* event_creator);
 
 // Returns true if the response contains the data reduction proxy Via header
 // value. If non-NULL, sets |has_intermediary| to true if another server added
@@ -79,7 +79,7 @@
     const GURL& url,
     const net::BoundNetLog& bound_net_log,
     DataReductionProxyInfo* proxy_info,
-    DataReductionProxyEventStore* event_store,
+    DataReductionProxyEventCreator* event_creator,
     bool* event_logged);
 
 // Searches for the specified Chrome-Proxy action, and if present saves its
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc
index cda2159c..460459a 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <vector>
 
-#include "base/test/test_simple_task_runner.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h"
 #include "net/http/http_response_headers.h"
 #include "net/proxy/proxy_service.h"
@@ -16,17 +16,20 @@
 namespace data_reduction_proxy {
 
 class DataReductionProxyHeadersTest : public testing::Test {
- public:
-  DataReductionProxyHeadersTest()
-    : task_runner_(scoped_refptr<base::TestSimpleTaskRunner>(
-          new base::TestSimpleTaskRunner())) {}
-
+ protected:
   void SetUp() override {
-    event_store_.reset(new DataReductionProxyEventStore(task_runner_));
+    storage_delegate_.reset(new TestDataReductionProxyEventStorageDelegate());
+    event_creator_.reset(
+        new DataReductionProxyEventCreator(storage_delegate_.get()));
   }
 
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-  scoped_ptr<DataReductionProxyEventStore> event_store_;
+  DataReductionProxyEventCreator* event_creator() const {
+    return event_creator_.get();
+  }
+
+ private:
+  scoped_ptr<DataReductionProxyEventCreator> event_creator_;
+  scoped_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate_;
 };
 
 TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyActionValue) {
@@ -364,13 +367,10 @@
         new net::HttpResponseHeaders(headers));
 
     DataReductionProxyInfo data_reduction_proxy_info;
-    EXPECT_EQ(
-        tests[i].expected_result,
-        ParseHeadersAndSetProxyInfo(parsed.get(),
-                                    GURL(),
-                                    net::BoundNetLog(),
-                                    &data_reduction_proxy_info,
-                                    event_store_.get()));
+    EXPECT_EQ(tests[i].expected_result,
+              ParseHeadersAndSetProxyInfo(
+                  parsed.get(), GURL(), net::BoundNetLog(),
+                  &data_reduction_proxy_info, event_creator()));
     EXPECT_EQ(tests[i].expected_retry_delay,
               data_reduction_proxy_info.bypass_duration.InSeconds());
     EXPECT_EQ(tests[i].expected_bypass_all,
@@ -392,11 +392,8 @@
 
   DataReductionProxyInfo data_reduction_proxy_info;
   EXPECT_TRUE(
-      ParseHeadersAndSetProxyInfo(parsed.get(),
-                                  GURL(),
-                                  net::BoundNetLog(),
-                                  &data_reduction_proxy_info,
-                                  event_store_.get()));
+      ParseHeadersAndSetProxyInfo(parsed.get(), GURL(), net::BoundNetLog(),
+                                  &data_reduction_proxy_info, event_creator()));
   EXPECT_LE(60, data_reduction_proxy_info.bypass_duration.InSeconds());
   EXPECT_GE(5 * 60, data_reduction_proxy_info.bypass_duration.InSeconds());
   EXPECT_FALSE(data_reduction_proxy_info.bypass_all);
@@ -608,15 +605,10 @@
         new net::HttpResponseHeaders(headers));
     DataReductionProxyInfo chrome_proxy_info;
     bool event_was_logged;
-    EXPECT_EQ(
-        tests[i].expected_result,
-        GetDataReductionProxyBypassType(
-            parsed.get(),
-            GURL(),
-            net::BoundNetLog(),
-            &chrome_proxy_info,
-            event_store_.get(),
-            &event_was_logged));
+    EXPECT_EQ(tests[i].expected_result,
+              GetDataReductionProxyBypassType(
+                  parsed.get(), GURL(), net::BoundNetLog(), &chrome_proxy_info,
+                  event_creator(), &event_was_logged));
   }
 }
 
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
index 2386931..bf676d3 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
@@ -74,5 +74,8 @@
 const char kEnableDataReductionProxyConfigClient[] =
     "enable-data-reduction-proxy-config-client";
 
+// The URL from which to retrieve the Data Reduction Proxy configuration.
+const char kDataReductionProxyConfigURL[] = "data-reduction-proxy-config-url";
+
 }  // namespace switches
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
index 1a8f7c0..90d98df 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
@@ -29,6 +29,7 @@
 extern const char kEnableDataReductionProxyBypassWarning[];
 extern const char kClearDataReductionProxyDataSavings[];
 extern const char kEnableDataReductionProxyConfigClient[];
+extern const char kDataReductionProxyConfigURL[];
 
 }  // namespace switches
 }  // namespace data_reduction_proxy
diff --git a/components/devtools_discovery.gypi b/components/devtools_discovery.gypi
new file mode 100644
index 0000000..9b8232c
--- /dev/null
+++ b/components/devtools_discovery.gypi
@@ -0,0 +1,27 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'targets': [
+    {
+      'target_name': 'devtools_discovery',
+      'type': 'static_library',
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_browser',
+        '../content/content.gyp:content_common',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'sources': [
+        'devtools_discovery/basic_target_descriptor.cc',
+        'devtools_discovery/basic_target_descriptor.h',
+        'devtools_discovery/devtools_discovery_manager.cc',
+        'devtools_discovery/devtools_discovery_manager.h',
+        'devtools_discovery/devtools_target_descriptor.h',
+      ],
+    },
+  ],
+}
diff --git a/components/devtools_discovery/BUILD.gn b/components/devtools_discovery/BUILD.gn
new file mode 100644
index 0000000..a733af4
--- /dev/null
+++ b/components/devtools_discovery/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("devtools_discovery") {
+  sources = [
+    "basic_target_descriptor.cc",
+    "basic_target_descriptor.h",
+    "devtools_discovery_manager.cc",
+    "devtools_discovery_manager.h",
+    "devtools_target_descriptor.h",
+  ]
+
+  deps = [
+    "//base",
+    "//content/public/browser",
+    "//content/public/common",
+  ]
+}
diff --git a/components/devtools_discovery/DEPS b/components/devtools_discovery/DEPS
new file mode 100644
index 0000000..f75ba964
--- /dev/null
+++ b/components/devtools_discovery/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+  "+content/public/browser",
+  "+content/public/common",
+  "+content/public/test",
+]
diff --git a/components/devtools_discovery/OWNERS b/components/devtools_discovery/OWNERS
new file mode 100644
index 0000000..fe38b0fa
--- /dev/null
+++ b/components/devtools_discovery/OWNERS
@@ -0,0 +1,2 @@
+dgozman@chromium.org
+pfeldman@chromium.org
diff --git a/components/devtools_discovery/basic_target_descriptor.cc b/components/devtools_discovery/basic_target_descriptor.cc
new file mode 100644
index 0000000..bbb62d0
--- /dev/null
+++ b/components/devtools_discovery/basic_target_descriptor.cc
@@ -0,0 +1,94 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/devtools_discovery/basic_target_descriptor.h"
+
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+
+using content::DevToolsAgentHost;
+
+namespace devtools_discovery {
+
+const char BasicTargetDescriptor::kTypePage[] = "page";
+const char BasicTargetDescriptor::kTypeServiceWorker[] = "service_worker";
+const char BasicTargetDescriptor::kTypeSharedWorker[] = "worker";
+const char BasicTargetDescriptor::kTypeOther[] = "other";
+
+BasicTargetDescriptor::BasicTargetDescriptor(
+    scoped_refptr<DevToolsAgentHost> agent_host)
+    : agent_host_(agent_host) {
+  if (content::WebContents* web_contents = agent_host_->GetWebContents()) {
+    content::NavigationController& controller = web_contents->GetController();
+    content::NavigationEntry* entry = controller.GetActiveEntry();
+    if (entry != NULL && entry->GetURL().is_valid())
+      favicon_url_ = entry->GetFavicon().url;
+    last_activity_time_ = web_contents->GetLastActiveTime();
+  }
+}
+
+BasicTargetDescriptor::~BasicTargetDescriptor() {
+}
+
+std::string BasicTargetDescriptor::GetId() const {
+  return agent_host_->GetId();
+}
+
+std::string BasicTargetDescriptor::GetParentId() const {
+  return std::string();
+}
+
+std::string BasicTargetDescriptor::GetType() const {
+  switch (agent_host_->GetType()) {
+    case DevToolsAgentHost::TYPE_WEB_CONTENTS:
+      return kTypePage;
+    case DevToolsAgentHost::TYPE_SERVICE_WORKER:
+      return kTypeServiceWorker;
+    case DevToolsAgentHost::TYPE_SHARED_WORKER:
+      return kTypeSharedWorker;
+    default:
+      break;
+  }
+  return kTypeOther;
+}
+
+std::string BasicTargetDescriptor::GetTitle() const {
+  return agent_host_->GetTitle();
+}
+
+std::string BasicTargetDescriptor::GetDescription() const {
+  return std::string();
+}
+
+GURL BasicTargetDescriptor::GetURL() const {
+  return agent_host_->GetURL();
+}
+
+GURL BasicTargetDescriptor::GetFaviconURL() const {
+  return favicon_url_;
+}
+
+base::TimeTicks BasicTargetDescriptor::GetLastActivityTime() const {
+  return last_activity_time_;
+}
+
+bool BasicTargetDescriptor::IsAttached() const {
+  return agent_host_->IsAttached();
+}
+
+scoped_refptr<DevToolsAgentHost> BasicTargetDescriptor::GetAgentHost() const {
+  return agent_host_;
+}
+
+bool BasicTargetDescriptor::Activate() const {
+  return agent_host_->Activate();
+}
+
+bool BasicTargetDescriptor::Close() const {
+  return agent_host_->Close();
+}
+
+}  // namespace devtools_discovery
diff --git a/components/devtools_discovery/basic_target_descriptor.h b/components/devtools_discovery/basic_target_descriptor.h
new file mode 100644
index 0000000..9072e0f5
--- /dev/null
+++ b/components/devtools_discovery/basic_target_descriptor.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DEVTOOLS_DISCOVERY_BASIC_TARGET_DESCRIPTOR_H_
+#define COMPONENTS_DEVTOOLS_DISCOVERY_BASIC_TARGET_DESCRIPTOR_H_
+
+#include "components/devtools_discovery/devtools_target_descriptor.h"
+
+namespace devtools_discovery {
+
+class BasicTargetDescriptor : public DevToolsTargetDescriptor {
+ public:
+  explicit BasicTargetDescriptor(
+      scoped_refptr<content::DevToolsAgentHost> agent_host);
+  ~BasicTargetDescriptor() override;
+
+  static const char kTypePage[];
+  static const char kTypeServiceWorker[];
+  static const char kTypeSharedWorker[];
+  static const char kTypeOther[];
+
+  // DevToolsTargetDescriptor implementation.
+  std::string GetId() const override;
+  std::string GetParentId() const override;
+  std::string GetType() const override;
+  std::string GetTitle() const override;
+  std::string GetDescription() const override;
+  GURL GetURL() const override;
+  GURL GetFaviconURL() const override;
+  base::TimeTicks GetLastActivityTime() const override;
+  bool IsAttached() const override;
+  scoped_refptr<content::DevToolsAgentHost> GetAgentHost() const override;
+  bool Activate() const override;
+  bool Close() const override;
+
+ private:
+  scoped_refptr<content::DevToolsAgentHost> agent_host_;
+  GURL favicon_url_;
+  base::TimeTicks last_activity_time_;
+};
+
+}  // namespace devtools_discovery
+
+#endif  // COMPONENTS_DEVTOOLS_DISCOVERY_BASIC_TARGET_DESCRIPTOR_H_
diff --git a/components/devtools_discovery/devtools_discovery_manager.cc b/components/devtools_discovery/devtools_discovery_manager.cc
new file mode 100644
index 0000000..3138732d
--- /dev/null
+++ b/components/devtools_discovery/devtools_discovery_manager.cc
@@ -0,0 +1,53 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/devtools_discovery/devtools_discovery_manager.h"
+
+#include "base/stl_util.h"
+#include "components/devtools_discovery/basic_target_descriptor.h"
+#include "content/public/browser/devtools_agent_host.h"
+
+using content::DevToolsAgentHost;
+
+namespace devtools_discovery {
+
+// static
+DevToolsDiscoveryManager* DevToolsDiscoveryManager::GetInstance() {
+  return Singleton<DevToolsDiscoveryManager>::get();
+}
+
+DevToolsDiscoveryManager::DevToolsDiscoveryManager() {
+}
+
+DevToolsDiscoveryManager::~DevToolsDiscoveryManager() {
+  STLDeleteElements(&providers_);
+}
+
+void DevToolsDiscoveryManager::AddProvider(scoped_ptr<Provider> provider) {
+  providers_.push_back(provider.release());
+}
+
+DevToolsTargetDescriptor::List DevToolsDiscoveryManager::GetDescriptors() {
+  if (providers_.size())
+    return GetDescriptorsFromProviders();
+
+  DevToolsAgentHost::List agent_hosts = DevToolsAgentHost::GetOrCreateAll();
+  DevToolsTargetDescriptor::List result;
+  result.reserve(agent_hosts.size());
+  for (const auto& agent_host : agent_hosts)
+    result.push_back(new BasicTargetDescriptor(agent_host));
+  return result;
+}
+
+DevToolsTargetDescriptor::List
+DevToolsDiscoveryManager::GetDescriptorsFromProviders() {
+  DevToolsTargetDescriptor::List result;
+  for (const auto& provider : providers_) {
+    DevToolsTargetDescriptor::List partial = provider->GetDescriptors();
+    result.insert(result.begin(), partial.begin(), partial.end());
+  }
+  return result;
+}
+
+}  // namespace devtools_discovery
diff --git a/components/devtools_discovery/devtools_discovery_manager.h b/components/devtools_discovery/devtools_discovery_manager.h
new file mode 100644
index 0000000..c75f844b
--- /dev/null
+++ b/components/devtools_discovery/devtools_discovery_manager.h
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DEVTOOLS_DISCOVERY_DEVTOOLS_DISCOVERY_MANAGER_H_
+#define COMPONENTS_DEVTOOLS_DISCOVERY_DEVTOOLS_DISCOVERY_MANAGER_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+#include "components/devtools_discovery/devtools_target_descriptor.h"
+
+namespace devtools_discovery {
+
+class DevToolsDiscoveryManager {
+ public:
+  class Provider {
+   public:
+    virtual ~Provider() {}
+    virtual DevToolsTargetDescriptor::List GetDescriptors() = 0;
+  };
+
+  // Returns single instance of this class. The instance is destroyed on the
+  // browser main loop exit so this method MUST NOT be called after that point.
+  static DevToolsDiscoveryManager* GetInstance();
+
+  void AddProvider(scoped_ptr<Provider> provider);
+
+  DevToolsTargetDescriptor::List GetDescriptors();
+
+ private:
+  friend struct DefaultSingletonTraits<DevToolsDiscoveryManager>;
+
+  DevToolsDiscoveryManager();
+  ~DevToolsDiscoveryManager();
+  DevToolsTargetDescriptor::List GetDescriptorsFromProviders();
+
+  std::vector<Provider*> providers_;
+
+  DISALLOW_COPY_AND_ASSIGN(DevToolsDiscoveryManager);
+};
+
+}  // namespace devtools_discovery
+
+#endif  // COMPONENTS_DEVTOOLS_DISCOVERY_DEVTOOLS_DISCOVERY_MANAGER_H_
diff --git a/components/devtools_discovery/devtools_target_descriptor.h b/components/devtools_discovery/devtools_target_descriptor.h
new file mode 100644
index 0000000..2e5b104
--- /dev/null
+++ b/components/devtools_discovery/devtools_target_descriptor.h
@@ -0,0 +1,37 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DEVTOOLS_DISCOVERY_DEVTOOLS_TARGET_DESCRIPTOR_H_
+#define COMPONENTS_DEVTOOLS_DISCOVERY_DEVTOOLS_TARGET_DESCRIPTOR_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+#include "content/public/browser/devtools_target.h"
+#include "url/gurl.h"
+
+namespace content {
+class DevToolsAgentHost;
+}
+
+namespace devtools_discovery {
+
+// DevToolsTargetDescriptor provides information about devtools target
+// and can be used to manipulate the target and query its details.
+// Instantiation and discovery of DevToolsTargetDescriptor instances
+// is the responsibility of DevToolsDiscoveryManager.
+// TODO(dgozman): remove content::DevToolsTarget once every embedder migrates
+// to this descriptor.
+class DevToolsTargetDescriptor : public content::DevToolsTarget {
+ public:
+  using List = std::vector<DevToolsTargetDescriptor*>;
+  ~DevToolsTargetDescriptor() override {}
+};
+
+}  // namespace devtools_discovery
+
+#endif  // COMPONENTS_DEVTOOLS_DISCOVERY_DEVTOOLS_TARGET_DESCRIPTOR_H_
diff --git a/components/dom_distiller/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java b/components/dom_distiller/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java
index 03e2a155..39c4ba14 100644
--- a/components/dom_distiller/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java
+++ b/components/dom_distiller/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java
@@ -20,9 +20,9 @@
         public void onIsPageDistillableResult(boolean isDistillable);
     }
 
-    public static void isPageDistillable(
-            WebContents webContents, PageDistillableCallback callback) {
-        nativeIsPageDistillable(webContents, callback);
+    public static void isPageDistillable(WebContents webContents, boolean isMobileOptimized,
+            PageDistillableCallback callback) {
+        nativeIsPageDistillable(webContents, isMobileOptimized, callback);
     }
 
     @CalledByNative
@@ -32,6 +32,6 @@
     }
 
     private static native void nativeIsPageDistillable(
-            WebContents webContents, PageDistillableCallback callback);
+            WebContents webContents, boolean isMobileOptimized, PageDistillableCallback callback);
 }
 
diff --git a/components/dom_distiller/content/distillable_page_utils.cc b/components/dom_distiller/content/distillable_page_utils.cc
index 1267bfb..5d1519c 100644
--- a/components/dom_distiller/content/distillable_page_utils.cc
+++ b/components/dom_distiller/content/distillable_page_utils.cc
@@ -49,6 +49,7 @@
 }
 
 void IsDistillablePage(content::WebContents* web_contents,
+                       bool is_mobile_optimized,
                        base::Callback<void(bool)> callback) {
   switch (GetDistillerHeuristicsType()) {
     case DistillerHeuristicsType::ALWAYS_TRUE:
@@ -59,6 +60,12 @@
       IsOpenGraphArticle(web_contents, callback);
       return;
     case DistillerHeuristicsType::ADABOOST_MODEL:
+      // The adaboost model is only applied to non-mobile pages.
+      if (is_mobile_optimized) {
+        base::MessageLoop::current()->PostTask(FROM_HERE,
+                                               base::Bind(callback, false));
+        return;
+      }
       IsDistillablePageForDetector(
           web_contents, DistillablePageDetector::GetDefault(), callback);
       return;
diff --git a/components/dom_distiller/content/distillable_page_utils.h b/components/dom_distiller/content/distillable_page_utils.h
index e2887db..a7f8c06 100644
--- a/components/dom_distiller/content/distillable_page_utils.h
+++ b/components/dom_distiller/content/distillable_page_utils.h
@@ -15,6 +15,7 @@
 // Checks if the page appears to be distillable based on whichever heuristics
 // are configured to be used (see dom_distiller::GetDistillerHeuristicsType).
 void IsDistillablePage(content::WebContents* web_contents,
+                       bool is_mobile_optimized,
                        base::Callback<void(bool)> callback);
 
 // Checks if the web_contents is has opengraph type=article markup.
diff --git a/components/dom_distiller/content/distillable_page_utils_android.cc b/components/dom_distiller/content/distillable_page_utils_android.cc
index 6250398..eac1f247 100644
--- a/components/dom_distiller/content/distillable_page_utils_android.cc
+++ b/components/dom_distiller/content/distillable_page_utils_android.cc
@@ -27,6 +27,7 @@
 static void IsPageDistillable(JNIEnv* env,
                               jclass jcaller,
                               jobject webContents,
+                              jboolean is_mobile_optimized,
                               jobject callback) {
   content::WebContents* web_contents(
       content::WebContents::FromJavaWebContents(webContents));
@@ -40,8 +41,9 @@
                               base::Passed(&callback_holder), false));
     return;
   }
-  IsDistillablePage(web_contents, base::Bind(OnIsPageDistillableResult,
-                                             base::Passed(&callback_holder)));
+  IsDistillablePage(
+      web_contents, is_mobile_optimized,
+      base::Bind(OnIsPageDistillableResult, base::Passed(&callback_holder)));
 }
 
 bool RegisterDistillablePageUtils(JNIEnv* env) {
diff --git a/components/dom_distiller/content/distillable_page_utils_browsertest.cc b/components/dom_distiller/content/distillable_page_utils_browsertest.cc
index 95259828..c320eedb 100644
--- a/components/dom_distiller/content/distillable_page_utils_browsertest.cc
+++ b/components/dom_distiller/content/distillable_page_utils_browsertest.cc
@@ -50,7 +50,12 @@
   void AddComponentsResources() {
     base::FilePath pak_file;
     base::FilePath pak_dir;
+#if defined(OS_ANDROID)
+    CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir));
+    pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks"));
+#else
     PathService::Get(base::DIR_MODULE, &pak_dir);
+#endif  // OS_ANDROID
     pak_file =
         pak_dir.Append(FILE_PATH_LITERAL("components_tests_resources.pak"));
     ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
diff --git a/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc b/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc
index 79d557a..d1d2dff 100644
--- a/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc
+++ b/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc
@@ -104,7 +104,12 @@
   void AddComponentsResources() {
     base::FilePath pak_file;
     base::FilePath pak_dir;
+#if defined(OS_ANDROID)
+    CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir));
+    pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks"));
+#else
     PathService::Get(base::DIR_MODULE, &pak_dir);
+#endif  // OS_ANDROID
     pak_file =
         pak_dir.Append(FILE_PATH_LITERAL("components_tests_resources.pak"));
     ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
diff --git a/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc b/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc
index 53b37b6..6d26962 100644
--- a/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc
+++ b/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc
@@ -76,8 +76,14 @@
   void AddComponentsResources() {
     base::FilePath pak_file;
     base::FilePath pak_dir;
+#if defined(OS_ANDROID)
+    CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir));
+    pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks"));
+#else
     PathService::Get(base::DIR_MODULE, &pak_dir);
-    pak_file = pak_dir.Append(FILE_PATH_LITERAL("components_resources.pak"));
+#endif  // OS_ANDROID
+    pak_file =
+        pak_dir.Append(FILE_PATH_LITERAL("components_tests_resources.pak"));
     ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
         pak_file, ui::SCALE_FACTOR_NONE);
   }
diff --git a/components/favicon.gypi b/components/favicon.gypi
index d150316..d2f9195 100644
--- a/components/favicon.gypi
+++ b/components/favicon.gypi
@@ -36,6 +36,8 @@
         'favicon/core/favicon_service.h',
         'favicon/core/favicon_url.cc',
         'favicon/core/favicon_url.h',
+        'favicon/core/large_icon_service.cc',
+        'favicon/core/large_icon_service.h',
       ],
       'include_dirs': [
         '..',
diff --git a/components/favicon/core/BUILD.gn b/components/favicon/core/BUILD.gn
index 7f9b762..f4e8a15e 100644
--- a/components/favicon/core/BUILD.gn
+++ b/components/favicon/core/BUILD.gn
@@ -19,6 +19,8 @@
     "favicon_service.h",
     "favicon_url.cc",
     "favicon_url.h",
+    "large_icon_service.cc",
+    "large_icon_service.h",
   ]
 
   deps = [
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc
index aff1626..1d5eac7 100644
--- a/components/favicon/core/favicon_handler.cc
+++ b/components/favicon/core/favicon_handler.cc
@@ -235,7 +235,10 @@
   url_ = url;
 
   favicon_expired_or_incomplete_ = got_favicon_from_history_ = false;
+  download_requests_.clear();
   image_urls_.clear();
+  history_results_.clear();
+  best_favicon_candidate_ = FaviconCandidate();
 
   // Request the favicon from the history service. In parallel to this the
   // renderer is going to notify us (well WebContents) when the favicon url is
@@ -298,19 +301,12 @@
   if (ShouldSaveFavicon(url))
     SetHistoryFavicons(url, icon_url, icon_type, image);
 
-  if (!UrlMatches(url, url_) || PageChangedSinceFaviconWasRequested())
-    return;
-
-  NotifyFaviconAvailable(
-      icon_url,
-      image,
-      icon_type == favicon_base::FAVICON && !download_largest_icon_);
+  NotifyFaviconAvailable(icon_url, image);
 }
 
 void FaviconHandler::NotifyFaviconAvailable(
     const std::vector<favicon_base::FaviconRawBitmapResult>&
-        favicon_bitmap_results,
-    bool is_active_favicon) {
+        favicon_bitmap_results) {
   gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
       favicon_bitmap_results,
       favicon_base::GetFaviconScales(),
@@ -319,23 +315,27 @@
   // not matter which result we get the |icon_url| from.
   const GURL icon_url = favicon_bitmap_results.empty() ?
       GURL() : favicon_bitmap_results[0].icon_url;
-  NotifyFaviconAvailable(icon_url, resized_image, is_active_favicon);
+  NotifyFaviconAvailable(icon_url, resized_image);
 }
 
 void FaviconHandler::NotifyFaviconAvailable(const GURL& icon_url,
-                                            const gfx::Image& image,
-                                            bool is_active_favicon) {
+                                            const gfx::Image& image) {
   gfx::Image image_with_adjusted_colorspace = image;
   favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace);
 
+  bool is_active_favicon =
+      (handler_type_ == FAVICON && !download_largest_icon_);
+
   driver_->OnFaviconAvailable(
       image_with_adjusted_colorspace, icon_url, is_active_favicon);
 }
 
 void FaviconHandler::OnUpdateFaviconURL(
     const std::vector<FaviconURL>& candidates) {
+  download_requests_.clear();
   image_urls_.clear();
   best_favicon_candidate_ = FaviconCandidate();
+
   for (const FaviconURL& candidate : candidates) {
     if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_))
       image_urls_.push_back(candidate);
@@ -393,14 +393,19 @@
   DownloadRequest download_request = i->second;
   download_requests_.erase(i);
 
-  if (current_candidate() &&
-      DoUrlAndIconMatch(*current_candidate(),
-                        image_url,
-                        download_request.icon_type)) {
-    bool request_next_icon = true;
+  if (PageChangedSinceFaviconWasRequested() ||
+      !current_candidate() ||
+      !DoUrlAndIconMatch(*current_candidate(),
+                         image_url,
+                         download_request.icon_type)) {
+    return;
+  }
+
+  bool request_next_icon = true;
+  if (!bitmaps.empty()) {
     float score = 0.0f;
     gfx::ImageSkia image_skia;
-    if (download_largest_icon_ && !bitmaps.empty()) {
+    if (download_largest_icon_) {
       int index = -1;
       // Use the largest bitmap if FaviconURL doesn't have sizes attribute.
       if (current_candidate()->icon_sizes.empty()) {
@@ -424,29 +429,26 @@
       gfx::Image image(image_skia);
       // The downloaded icon is still valid when there is no FaviconURL update
       // during the downloading.
-      if (!bitmaps.empty()) {
-        request_next_icon = !UpdateFaviconCandidate(
-            download_request.url, image_url, image, score,
-            download_request.icon_type);
-      }
+      request_next_icon = !UpdateFaviconCandidate(
+          download_request.url, image_url, image, score,
+          download_request.icon_type);
     }
-    if (request_next_icon && !PageChangedSinceFaviconWasRequested() &&
-        image_urls_.size() > 1) {
-      // Remove the first member of image_urls_ and process the remaining.
-      image_urls_.erase(image_urls_.begin());
-      ProcessCurrentUrl();
-    } else if (best_favicon_candidate_.icon_type !=
-               favicon_base::INVALID_ICON) {
-      // No more icons to request, set the favicon from the candidate.
-      SetFavicon(best_favicon_candidate_.url,
-                 best_favicon_candidate_.image_url,
-                 best_favicon_candidate_.image,
-                 best_favicon_candidate_.icon_type);
-      // Reset candidate.
-      image_urls_.clear();
-      download_requests_.clear();
-      best_favicon_candidate_ = FaviconCandidate();
-    }
+  }
+
+  if (request_next_icon && image_urls_.size() > 1) {
+    // Remove the first member of image_urls_ and process the remaining.
+    image_urls_.erase(image_urls_.begin());
+    ProcessCurrentUrl();
+  } else if (best_favicon_candidate_.icon_type != favicon_base::INVALID_ICON) {
+    // No more icons to request, set the favicon from the candidate.
+    SetFavicon(best_favicon_candidate_.url,
+               best_favicon_candidate_.image_url,
+               best_favicon_candidate_.image,
+               best_favicon_candidate_.icon_type);
+    // Reset candidate.
+    image_urls_.clear();
+    download_requests_.clear();
+    best_favicon_candidate_ = FaviconCandidate();
   }
 }
 
@@ -569,7 +571,7 @@
       // doesn't have an icon. Set the favicon now, and if the favicon turns out
       // to be expired (or the wrong url) we'll fetch later on. This way the
       // user doesn't see a flash of the default favicon.
-      NotifyFaviconAvailable(favicon_bitmap_results, true);
+      NotifyFaviconAvailable(favicon_bitmap_results);
     } else {
       // If |favicon_bitmap_results| does not have any valid results, treat the
       // favicon as if it's expired.
@@ -599,7 +601,7 @@
   // renderer to download the icon.
 
   if (has_valid_result && (handler_type_ != FAVICON || download_largest_icon_))
-    NotifyFaviconAvailable(favicon_bitmap_results, false);
+    NotifyFaviconAvailable(favicon_bitmap_results);
 }
 
 void FaviconHandler::DownloadFaviconOrAskFaviconService(
@@ -647,7 +649,7 @@
       // There is a favicon, set it now. If expired we'll download the current
       // one again, but at least the user will get some icon instead of the
       // default and most likely the current one is fine anyway.
-      NotifyFaviconAvailable(favicon_bitmap_results, true);
+      NotifyFaviconAvailable(favicon_bitmap_results);
     }
     if (has_expired_or_incomplete_result) {
       // The favicon is out of date. Request the current one.
@@ -668,11 +670,11 @@
 
   if (has_valid_result &&
       (handler_type_ != FAVICON || download_largest_icon_)) {
-    NotifyFaviconAvailable(favicon_bitmap_results, false);
+    NotifyFaviconAvailable(favicon_bitmap_results);
   }
 }
 
-int FaviconHandler::ScheduleDownload(const GURL& url,
+void FaviconHandler::ScheduleDownload(const GURL& url,
                                      const GURL& image_url,
                                      favicon_base::IconType icon_type) {
   // A max bitmap size is specified to avoid receiving huge bitmaps in
@@ -686,8 +688,6 @@
     download_requests_[download_id] =
         DownloadRequest(url, image_url, icon_type);
   }
-
-  return download_id;
 }
 
 void FaviconHandler::SortAndPruneImageUrls() {
diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h
index 8b7ab97..3fee8be 100644
--- a/components/favicon/core/favicon_handler.h
+++ b/components/favicon/core/favicon_handler.h
@@ -212,9 +212,9 @@
 
   // Schedules a download for the specified entry. This adds the request to
   // download_requests_.
-  int ScheduleDownload(const GURL& url,
-                       const GURL& image_url,
-                       favicon_base::IconType icon_type);
+  void ScheduleDownload(const GURL& url,
+                        const GURL& image_url,
+                        favicon_base::IconType icon_type);
 
   // Updates |favicon_candidate_| and returns true if it is an exact match.
   bool UpdateFaviconCandidate(const GURL& url,
@@ -233,11 +233,9 @@
   // FaviconDriver::NotifyFaviconAvailable() for |is_active_favicon| in detail.
   void NotifyFaviconAvailable(
       const std::vector<favicon_base::FaviconRawBitmapResult>&
-          favicon_bitmap_results,
-      bool is_active_favicon);
+          favicon_bitmap_results);
   void NotifyFaviconAvailable(const GURL& icon_url,
-                              const gfx::Image& image,
-                              bool is_active_favicon);
+                              const gfx::Image& image);
 
   // Return the current candidate if any.
   favicon::FaviconURL* current_candidate() {
@@ -266,9 +264,6 @@
   // URL of the page we're requesting the favicon for.
   GURL url_;
 
-  // Whether we are waiting for data from the FaviconService.
-  bool waiting_for_favicon_service_data_;
-
   // Whether we got data back for the initial request to the FaviconService.
   bool got_favicon_from_history_;
 
diff --git a/components/favicon/core/large_icon_service.cc b/components/favicon/core/large_icon_service.cc
new file mode 100644
index 0000000..702761c8
--- /dev/null
+++ b/components/favicon/core/large_icon_service.cc
@@ -0,0 +1,77 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/favicon/core/large_icon_service.h"
+
+#include "components/favicon/core/favicon_service.h"
+#include "components/favicon_base/fallback_icon_style.h"
+#include "components/favicon_base/favicon_types.h"
+
+namespace favicon {
+
+LargeIconService::LargeIconService(FaviconService* favicon_service)
+    : favicon_service_(favicon_service) {
+  large_icon_types_.push_back(favicon_base::IconType::FAVICON);
+  large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
+  large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
+}
+
+LargeIconService::~LargeIconService() {
+}
+
+base::CancelableTaskTracker::TaskId
+    LargeIconService::GetLargeIconOrFallbackStyle(
+        const GURL& page_url,
+        int desired_size_in_pixel,
+        const favicon_base::LargeIconCallback& callback,
+        base::CancelableTaskTracker* tracker) {
+  // TODO(beaudoin): For now this is just a wrapper around
+  //   GetLargestRawFaviconForPageURL. Add the logic required to select the best
+  //   possible large icon. Also add logic to fetch-on-demand when the URL of
+  //   a large icon is known but its bitmap is not available.
+  return favicon_service_->GetLargestRawFaviconForPageURL(
+      page_url,
+      large_icon_types_,
+      desired_size_in_pixel,
+      base::Bind(&LargeIconService::RunLargeIconCallback,
+                 base::Unretained(this), callback, desired_size_in_pixel),
+      tracker);
+}
+
+void LargeIconService::RunLargeIconCallback(
+    const favicon_base::LargeIconCallback& callback,
+    int desired_size_in_pixel,
+    const favicon_base::FaviconRawBitmapResult& bitmap_result) {
+  // If there are no bitmaps, return a result with an empty |bitmap| and a
+  // default |fallback_icon_style|.
+  favicon_base::LargeIconResult result;
+  if (!bitmap_result.is_valid()) {
+    callback.Run(result);
+    return;
+  }
+
+  // If there is a bitmap but it's smaller than the requested size or
+  // non-square, compute its dominant color and use it as background in
+  // |fallback_icon_style|.
+  if (bitmap_result.pixel_size.width() < desired_size_in_pixel ||
+      bitmap_result.pixel_size.height() < desired_size_in_pixel ||
+      bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height()) {
+    // TODO(beaudoin): Resize the icon if it's large enough. Alternatively,
+    // return it and let the HTML resize it.
+    result.fallback_icon_style.reset(new favicon_base::FallbackIconStyle());
+    favicon_base::SetDominantColorAsBackground(
+        bitmap_result.bitmap_data, result.fallback_icon_style.get());
+    callback.Run(result);
+    return;
+  }
+
+  // The bitmap is square and at least as large as the requested one, return
+  // it.
+  // TODO(beaudoin): Resize the icon if it's too large. Alternatively, return
+  // it and let the HTML resize it.
+  result.bitmap = bitmap_result;
+  callback.Run(result);
+}
+
+}  // namespace favicon
diff --git a/components/favicon/core/large_icon_service.h b/components/favicon/core/large_icon_service.h
new file mode 100644
index 0000000..1063fd7
--- /dev/null
+++ b/components/favicon/core/large_icon_service.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_FAVICON_CORE_LARGE_ICON_SERVICE_H_
+#define COMPONENTS_FAVICON_CORE_LARGE_ICON_SERVICE_H_
+
+#include <vector>
+
+#include "base/task/cancelable_task_tracker.h"
+#include "components/favicon_base/favicon_callback.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class GURL;
+
+namespace favicon_base {
+struct FaviconRawBitmapResult;
+}
+
+namespace favicon {
+
+class FaviconService;
+
+// The large icon service provides methods to access large icons. It relies on
+// the favicon service.
+class LargeIconService : public KeyedService {
+ public:
+  explicit LargeIconService(FaviconService* favicon_service);
+
+  ~LargeIconService() override;
+
+  // Requests the best large icon for the page at |page_url| given the requested
+  // |desired_size_in_pixel|. If no good large icon can be found, returns the
+  // fallback style to use, for which the background is set to the dominant
+  // color of a smaller icon when one is available. This function returns the
+  // style of the fallback icon rather than the rendered version so that clients
+  // can render the icon themselves.
+  base::CancelableTaskTracker::TaskId GetLargeIconOrFallbackStyle(
+    const GURL& page_url,
+    int desired_size_in_pixel,
+    const favicon_base::LargeIconCallback& callback,
+    base::CancelableTaskTracker* tracker);
+
+ private:
+  // Intermediate callback for GetLargeIconOrFallbackStyle(). Ensures the large
+  // icon is at least the desired size, if not compute the icon fallback style
+  // and use it to invoke |callback|.
+  void RunLargeIconCallback(
+      const favicon_base::LargeIconCallback& callback,
+      int desired_size_in_pixel,
+      const favicon_base::FaviconRawBitmapResult& bitmap_result);
+
+  FaviconService* favicon_service_;
+
+  // A pre-populated list of the types of icon files to consider when looking
+  // for large icons. This is an optimization over populating an icon type
+  // vector on each request.
+  std::vector<int> large_icon_types_;
+
+  DISALLOW_COPY_AND_ASSIGN(LargeIconService);
+};
+
+}  // namespace favicon
+
+#endif  // COMPONENTS_FAVICON_CORE_LARGE_ICON_SERVICE_H_
diff --git a/components/favicon_base/fallback_icon_style.cc b/components/favicon_base/fallback_icon_style.cc
index e620613..d3e395b1 100644
--- a/components/favicon_base/fallback_icon_style.cc
+++ b/components/favicon_base/fallback_icon_style.cc
@@ -4,6 +4,9 @@
 
 #include "components/favicon_base/fallback_icon_style.h"
 
+#include <algorithm>
+
+#include "ui/gfx/color_analysis.h"
 #include "ui/gfx/color_utils.h"
 
 namespace favicon_base {
@@ -12,14 +15,19 @@
 
 // Luminance threshold for background color determine whether to use dark or
 // light text color.
-int kDarkTextLuminanceThreshold = 190;
+const int kDarkTextLuminanceThreshold = 190;
+
+// The maximum luminance of the background color to ensure light text is
+// readable.
+const double kMaxBackgroundColorLuminance = 0.67;
 
 // Default values for FallbackIconStyle.
-SkColor kDefaultBackgroundColor = SkColorSetRGB(0x80, 0x80, 0x80);
-SkColor kDefaultTextColorDark = SK_ColorBLACK;
-SkColor kDefaultTextColorLight = SK_ColorWHITE;
-double kDefaultFontSizeRatio = 0.8;
-double kDefaultRoundness = 0.125;  // 1 / 8.
+const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78);
+const SkColor kDefaultTextColorDark = SK_ColorBLACK;
+const SkColor kDefaultTextColorLight = SK_ColorWHITE;
+const double kDefaultFontSizeRatio = 0.44;
+const double kDefaultRoundness = 0;  // Square. Round corners are applied
+                                     // externally (Javascript or Java).
 
 }  // namespace
 
@@ -45,4 +53,18 @@
       style.roundness >= 0.0 && style.roundness <= 1.0;
 }
 
+void SetDominantColorAsBackground(
+    const scoped_refptr<base::RefCountedMemory>& bitmap_data,
+    FallbackIconStyle* style) {
+  SkColor dominant_color =
+      color_utils::CalculateKMeanColorOfPNG(bitmap_data);
+  // Assumes |style.text_color| is light, and clamps luminance down to a
+  // reasonable maximum value so text is readable.
+  color_utils::HSL color_hsl;
+  color_utils::SkColorToHSL(dominant_color, &color_hsl);
+  color_hsl.l = std::min(color_hsl.l, kMaxBackgroundColorLuminance);
+  style->background_color =
+      color_utils::HSLToSkColor(color_hsl, SK_AlphaOPAQUE);
+}
+
 }  // namespace favicon_base
diff --git a/components/favicon_base/fallback_icon_style.h b/components/favicon_base/fallback_icon_style.h
index 097636b0..84842ed 100644
--- a/components/favicon_base/fallback_icon_style.h
+++ b/components/favicon_base/fallback_icon_style.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_
 #define COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_
 
+#include "base/memory/ref_counted_memory.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace favicon_base {
@@ -37,6 +38,13 @@
 // Returns whether |style| values are within bounds.
 bool ValidateFallbackIconStyle(const FallbackIconStyle& style);
 
+// Set |style|'s background color to the dominant color of |bitmap_data|,
+// clamping luminance down to a reasonable maximum value so that light text is
+// readable.
+void SetDominantColorAsBackground(
+    const scoped_refptr<base::RefCountedMemory>& bitmap_data,
+    FallbackIconStyle* style);
+
 }  // namespace favicon_base
 
 #endif  // COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_
diff --git a/components/favicon_base/favicon_callback.h b/components/favicon_base/favicon_callback.h
index 7616a11..96029f1c 100644
--- a/components/favicon_base/favicon_callback.h
+++ b/components/favicon_base/favicon_callback.h
@@ -13,6 +13,7 @@
 
 struct FaviconRawBitmapResult;
 struct FaviconImageResult;
+struct LargeIconResult;
 
 // Callback for functions that can be used to return a |gfx::Image| and the
 // |GURL| it is loaded from. They are returned as a |FaviconImageResult| object.
@@ -29,6 +30,11 @@
 typedef base::Callback<void(const std::vector<FaviconRawBitmapResult>&)>
     FaviconResultsCallback;
 
+// Callback for functions returning data for a large icon. |LargeIconResult|
+// will contain either the raw bitmap for a large icon or the style of the
+// fallback to use if a sufficiently large icon could not be found.
+typedef base::Callback<void(const LargeIconResult&)> LargeIconCallback;
+
 }  // namespace favicon_base
 
 #endif  // COMPONENTS_FAVICON_BASE_FAVICON_CALLBACK_H_
diff --git a/components/favicon_base/favicon_types.cc b/components/favicon_base/favicon_types.cc
index 0188f1e..e69f1d7be 100644
--- a/components/favicon_base/favicon_types.cc
+++ b/components/favicon_base/favicon_types.cc
@@ -4,6 +4,8 @@
 
 #include "components/favicon_base/favicon_types.h"
 
+#include "components/favicon_base/fallback_icon_style.h"
+
 namespace favicon_base {
 
 // ---------------------------------------------------------
@@ -20,7 +22,13 @@
     : expired(false), icon_type(INVALID_ICON) {
 }
 
-FaviconRawBitmapResult::~FaviconRawBitmapResult() {
-}
+FaviconRawBitmapResult::~FaviconRawBitmapResult() {}
+
+// --------------------------------------------------------
+// LargeIconResult
+
+LargeIconResult::LargeIconResult() {}
+
+LargeIconResult::~LargeIconResult() {}
 
 }  // namespace favicon_base
diff --git a/components/favicon_base/favicon_types.h b/components/favicon_base/favicon_types.h
index ea64754..f7c812ab 100644
--- a/components/favicon_base/favicon_types.h
+++ b/components/favicon_base/favicon_types.h
@@ -6,12 +6,15 @@
 #define COMPONENTS_FAVICON_BASE_FAVICON_TYPES_H_
 
 #include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image.h"
 #include "url/gurl.h"
 
 namespace favicon_base {
 
+struct FallbackIconStyle;
+
 typedef int64 FaviconID;
 
 // Defines the icon types. They are also stored in icon_type field of favicons
@@ -72,6 +75,22 @@
 // HistoryBackend::SetFavicons().
 typedef FaviconRawBitmapResult FaviconRawBitmapData;
 
+// Result returned by LargeIconService::GetLargeIconOrFallbackStyle(). Contains
+// either the bitmap data if the favicon database has a sufficiently large
+// favicon bitmap and the style of the fallback icon otherwise.
+struct LargeIconResult {
+  LargeIconResult();
+  ~LargeIconResult();
+
+  // The bitmap from the favicon database if the database has a sufficiently
+  // large one.
+  FaviconRawBitmapResult bitmap;
+
+  // The fallback icon style if a sufficiently large icon isn't available. This
+  // uses the dominant color of a smaller icon as the background if available.
+  scoped_ptr<FallbackIconStyle> fallback_icon_style;
+};
+
 }  // namespace favicon_base
 
 #endif  // COMPONENTS_FAVICON_BASE_FAVICON_TYPES_H_
diff --git a/mojo/services/html_viewer/BUILD.gn b/components/html_viewer/BUILD.gn
similarity index 84%
rename from mojo/services/html_viewer/BUILD.gn
rename to components/html_viewer/BUILD.gn
index b36bd416..75856bcb 100644
--- a/mojo/services/html_viewer/BUILD.gn
+++ b/components/html_viewer/BUILD.gn
@@ -21,7 +21,7 @@
 }
 
 action("generate_blink_resource_map") {
-  script = "//mojo/services/html_viewer/generate_blink_resource_map.py"
+  script = "//components/html_viewer/generate_blink_resource_map.py"
   args = [
     "--pak-file",
     rebase_path("$target_gen_dir/unified_blink_resources.pak"),
@@ -62,32 +62,37 @@
     "discardable_memory_allocator.h",
     "html_document.cc",
     "html_document.h",
+    "mock_web_blob_registry_impl.cc",
+    "mock_web_blob_registry_impl.h",
     "touch_handler.cc",
     "touch_handler.h",
-    "webclipboard_impl.cc",
-    "webclipboard_impl.h",
-    "webcookiejar_impl.cc",
-    "webcookiejar_impl.h",
-    "weblayertreeview_impl.cc",
-    "weblayertreeview_impl.h",
-    "webmediaplayer_factory.cc",
-    "webmediaplayer_factory.h",
-    "webmimeregistry_impl.cc",
-    "webmimeregistry_impl.h",
-    "webnotificationmanager_impl.cc",
-    "webnotificationmanager_impl.h",
-    "webscheduler_impl.cc",
-    "webscheduler_impl.h",
-    "websockethandle_impl.cc",
-    "websockethandle_impl.h",
-    "webstoragenamespace_impl.cc",
-    "webstoragenamespace_impl.h",
-    "webthemeengine_impl.cc",
-    "webthemeengine_impl.h",
-    "webthread_impl.cc",
-    "webthread_impl.h",
-    "weburlloader_impl.cc",
-    "weburlloader_impl.h",
+    "web_clipboard_impl.cc",
+    "web_clipboard_impl.h",
+    "web_cookie_jar_impl.cc",
+    "web_cookie_jar_impl.h",
+    "web_layer_tree_view_impl.cc",
+    "web_layer_tree_view_impl.h",
+    "web_media_player_factory.cc",
+    "web_media_player_factory.h",
+    "web_media_player_factory.h",
+    "web_message_port_channel_impl.cc",
+    "web_message_port_channel_impl.h",
+    "web_mime_registry_impl.cc",
+    "web_mime_registry_impl.h",
+    "web_notification_manager_impl.cc",
+    "web_notification_manager_impl.h",
+    "web_scheduler_impl.cc",
+    "web_scheduler_impl.h",
+    "web_socket_handle_impl.cc",
+    "web_socket_handle_impl.h",
+    "web_storage_namespace_impl.cc",
+    "web_storage_namespace_impl.h",
+    "web_theme_engine_impl.cc",
+    "web_theme_engine_impl.h",
+    "web_thread_impl.cc",
+    "web_thread_impl.h",
+    "web_url_loader_impl.cc",
+    "web_url_loader_impl.h",
   ]
 
   include_dirs = [ "third_party/WebKit" ]
diff --git a/mojo/services/html_viewer/DEPS b/components/html_viewer/DEPS
similarity index 85%
rename from mojo/services/html_viewer/DEPS
rename to components/html_viewer/DEPS
index 867c136b..c513c40c 100644
--- a/mojo/services/html_viewer/DEPS
+++ b/components/html_viewer/DEPS
@@ -6,13 +6,16 @@
   "+components/webcrypto",
   "+gin",
   "+media",
-  "+mojo/cc",
-  "+mojo/converters/surfaces",
   "+mojo/application",
+  "+mojo/cc",
+  "+mojo/common",
+  "+mojo/converters/surfaces",
+  "+mojo/public",
   "+mojo/services/network",
   "+net/base",
   "+net/test/spawned_test_server",
   "+skia",
+  "+third_party/mojo/src/mojo/public",
   "+third_party/mojo_services/src",
   "+third_party/WebKit/public",
   "+third_party/skia/include",
diff --git a/mojo/services/html_viewer/OWNERS b/components/html_viewer/OWNERS
similarity index 100%
rename from mojo/services/html_viewer/OWNERS
rename to components/html_viewer/OWNERS
diff --git a/mojo/services/html_viewer/android/android_hooks.cc b/components/html_viewer/android/android_hooks.cc
similarity index 89%
rename from mojo/services/html_viewer/android/android_hooks.cc
rename to components/html_viewer/android/android_hooks.cc
index a1a29d2..ab553fe9 100644
--- a/mojo/services/html_viewer/android/android_hooks.cc
+++ b/components/html_viewer/android/android_hooks.cc
@@ -8,7 +8,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/library_loader/library_loader_hooks.h"
 #include "base/bind.h"
-#include "mojo/services/html_viewer/jni/Main_jni.h"
+#include "components/html_viewer/jni/Main_jni.h"
 
 namespace {
 bool RegisterJNI(JNIEnv* env) {
@@ -16,7 +16,8 @@
 }
 
 bool Init() {
-  Java_Main_init(base::android::AttachCurrentThread());
+  Java_Main_init(base::android::AttachCurrentThread(),
+                 base::android::GetApplicationContext());
   return true;
 }
 }  // namespace
diff --git a/mojo/services/html_viewer/android/java/org/chromium/html_viewer/Main.java b/components/html_viewer/android/java/org/chromium/html_viewer/Main.java
similarity index 84%
rename from mojo/services/html_viewer/android/java/org/chromium/html_viewer/Main.java
rename to components/html_viewer/android/java/org/chromium/html_viewer/Main.java
index 283029d1..87a7b59 100644
--- a/mojo/services/html_viewer/android/java/org/chromium/html_viewer/Main.java
+++ b/components/html_viewer/android/java/org/chromium/html_viewer/Main.java
@@ -4,6 +4,8 @@
 
 package org.chromium.html_viewer;
 
+import android.content.Context;
+
 import org.chromium.base.CalledByNative;
 import org.chromium.base.PathUtils;
 
@@ -17,7 +19,7 @@
 
     @SuppressWarnings("unused")
     @CalledByNative
-    private static void init() {
-        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
+    private static void init(Context context) {
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
     }
 }
diff --git a/mojo/services/html_viewer/ax_provider_apptest.cc b/components/html_viewer/ax_provider_apptest.cc
similarity index 100%
rename from mojo/services/html_viewer/ax_provider_apptest.cc
rename to components/html_viewer/ax_provider_apptest.cc
diff --git a/mojo/services/html_viewer/ax_provider_impl.cc b/components/html_viewer/ax_provider_impl.cc
similarity index 95%
rename from mojo/services/html_viewer/ax_provider_impl.cc
rename to components/html_viewer/ax_provider_impl.cc
index 11a1356b..bc7dc3cc 100644
--- a/mojo/services/html_viewer/ax_provider_impl.cc
+++ b/components/html_viewer/ax_provider_impl.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 "mojo/services/html_viewer/ax_provider_impl.h"
+#include "components/html_viewer/ax_provider_impl.h"
 
-#include "mojo/services/html_viewer/blink_basic_type_converters.h"
+#include "components/html_viewer/blink_basic_type_converters.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebAXObject.h"
 #include "third_party/WebKit/public/web/WebSettings.h"
diff --git a/mojo/services/html_viewer/ax_provider_impl.h b/components/html_viewer/ax_provider_impl.h
similarity index 87%
rename from mojo/services/html_viewer/ax_provider_impl.h
rename to components/html_viewer/ax_provider_impl.h
index ec6c8de..cea1d45c 100644
--- a/mojo/services/html_viewer/ax_provider_impl.h
+++ b/components/html_viewer/ax_provider_impl.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 MOJO_SERVICES_HTML_VIEWER_AX_PROVIDER_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_AX_PROVIDER_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_AX_PROVIDER_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_AX_PROVIDER_IMPL_H_
 
 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_impl.h"
 #include "third_party/mojo_services/src/accessibility/public/interfaces/accessibility.mojom.h"
@@ -36,4 +36,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_AX_PROVIDER_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_AX_PROVIDER_IMPL_H_
diff --git a/mojo/services/html_viewer/ax_provider_impl_unittest.cc b/components/html_viewer/ax_provider_impl_unittest.cc
similarity index 97%
rename from mojo/services/html_viewer/ax_provider_impl_unittest.cc
rename to components/html_viewer/ax_provider_impl_unittest.cc
index ec627cf..f8688d3 100644
--- a/mojo/services/html_viewer/ax_provider_impl_unittest.cc
+++ b/components/html_viewer/ax_provider_impl_unittest.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 "mojo/services/html_viewer/ax_provider_impl.h"
+#include "components/html_viewer/ax_provider_impl.h"
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
+#include "components/html_viewer/blink_platform_impl.h"
 #include "gin/v8_initializer.h"
-#include "mojo/services/html_viewer/blink_platform_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebData.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
diff --git a/mojo/services/html_viewer/blink_basic_type_converters.cc b/components/html_viewer/blink_basic_type_converters.cc
similarity index 94%
rename from mojo/services/html_viewer/blink_basic_type_converters.cc
rename to components/html_viewer/blink_basic_type_converters.cc
index 5324a7c3..f7a5ff47 100644
--- a/mojo/services/html_viewer/blink_basic_type_converters.cc
+++ b/components/html_viewer/blink_basic_type_converters.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 "mojo/services/html_viewer/blink_basic_type_converters.h"
+#include "components/html_viewer/blink_basic_type_converters.h"
 
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebString.h"
diff --git a/mojo/services/html_viewer/blink_basic_type_converters.h b/components/html_viewer/blink_basic_type_converters.h
similarity index 87%
rename from mojo/services/html_viewer/blink_basic_type_converters.h
rename to components/html_viewer/blink_basic_type_converters.h
index eb762a85..ad2d08b 100644
--- a/mojo/services/html_viewer/blink_basic_type_converters.h
+++ b/components/html_viewer/blink_basic_type_converters.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 MOJO_SERVICES_HTML_VIEWER_BLINK_BASIC_TYPE_CONVERTERS_H_
-#define MOJO_SERVICES_HTML_VIEWER_BLINK_BASIC_TYPE_CONVERTERS_H_
+#ifndef COMPONENTS_HTML_VIEWER_BLINK_BASIC_TYPE_CONVERTERS_H_
+#define COMPONENTS_HTML_VIEWER_BLINK_BASIC_TYPE_CONVERTERS_H_
 
 #include "third_party/mojo/src/mojo/public/cpp/bindings/type_converter.h"
 
@@ -49,4 +49,4 @@
 
 }  // namespace mojo
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_BLINK_BASIC_TYPE_CONVERTERS_H_
+#endif  // COMPONENTS_HTML_VIEWER_BLINK_BASIC_TYPE_CONVERTERS_H_
diff --git a/mojo/services/html_viewer/blink_input_events_type_converters.cc b/components/html_viewer/blink_input_events_type_converters.cc
similarity index 98%
rename from mojo/services/html_viewer/blink_input_events_type_converters.cc
rename to components/html_viewer/blink_input_events_type_converters.cc
index 3599df6..0fd8366 100644
--- a/mojo/services/html_viewer/blink_input_events_type_converters.cc
+++ b/components/html_viewer/blink_input_events_type_converters.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 "mojo/services/html_viewer/blink_input_events_type_converters.h"
+#include "components/html_viewer/blink_input_events_type_converters.h"
 
 #include "base/logging.h"
 #include "base/time/time.h"
diff --git a/mojo/services/html_viewer/blink_input_events_type_converters.h b/components/html_viewer/blink_input_events_type_converters.h
similarity index 71%
rename from mojo/services/html_viewer/blink_input_events_type_converters.h
rename to components/html_viewer/blink_input_events_type_converters.h
index 442239c..6ea239c 100644
--- a/mojo/services/html_viewer/blink_input_events_type_converters.h
+++ b/components/html_viewer/blink_input_events_type_converters.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 MOJO_SERVICES_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
-#define MOJO_SERVICES_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
+#ifndef COMPONENTS_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
+#define COMPONENTS_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
 
 #include "base/memory/scoped_ptr.h"
 #include "third_party/mojo_services/src/input_events/public/interfaces/input_events.mojom.h"
@@ -21,4 +21,4 @@
 
 }  // namespace mojo
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
+#endif  // COMPONENTS_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
diff --git a/mojo/services/html_viewer/blink_platform_impl.cc b/components/html_viewer/blink_platform_impl.cc
similarity index 91%
rename from mojo/services/html_viewer/blink_platform_impl.cc
rename to components/html_viewer/blink_platform_impl.cc
index 629ffb0..4c4ff85 100644
--- a/mojo/services/html_viewer/blink_platform_impl.cc
+++ b/components/html_viewer/blink_platform_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 "mojo/services/html_viewer/blink_platform_impl.h"
+#include "components/html_viewer/blink_platform_impl.h"
 
 #include <cmath>
 
@@ -12,12 +12,13 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
-#include "mojo/services/html_viewer/blink_resource_constants.h"
-#include "mojo/services/html_viewer/webclipboard_impl.h"
-#include "mojo/services/html_viewer/webcookiejar_impl.h"
-#include "mojo/services/html_viewer/websockethandle_impl.h"
-#include "mojo/services/html_viewer/webthread_impl.h"
-#include "mojo/services/html_viewer/weburlloader_impl.h"
+#include "components/html_viewer/blink_resource_constants.h"
+#include "components/html_viewer/web_clipboard_impl.h"
+#include "components/html_viewer/web_cookie_jar_impl.h"
+#include "components/html_viewer/web_message_port_channel_impl.h"
+#include "components/html_viewer/web_socket_handle_impl.h"
+#include "components/html_viewer/web_thread_impl.h"
+#include "components/html_viewer/web_url_loader_impl.h"
 #include "net/base/data_url.h"
 #include "net/base/mime_util.h"
 #include "net/base/net_errors.h"
@@ -35,7 +36,7 @@
 // TODO(darin): Figure out what our UA should really be.
 const char kDefaultUserAgentString[] =
     "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
-    "Chrome/35.0.1916.153 Safari/537.36";
+    "Chrome/42.0.2311.68 Safari/537.36";
 
 class WebWaitableEventImpl : public blink::WebWaitableEvent {
  public:
@@ -104,6 +105,10 @@
   return blink::WebString::fromUTF8("en-US");
 }
 
+blink::WebBlobRegistry* BlinkPlatformImpl::blobRegistry() {
+  return &blob_registry_;
+}
+
 double BlinkPlatformImpl::currentTime() {
   return base::Time::Now().ToDoubleT();
 }
@@ -169,6 +174,12 @@
   return &compositor_support_;
 }
 
+void BlinkPlatformImpl::createMessageChannel(
+    blink::WebMessagePortChannel** channel1,
+    blink::WebMessagePortChannel** channel2) {
+  WebMessagePortChannelImpl::CreatePair(channel1, channel2);
+}
+
 blink::WebScrollbarBehavior* BlinkPlatformImpl::scrollbarBehavior() {
   return &scrollbar_behavior_;
 }
@@ -194,7 +205,7 @@
 }
 
 blink::WebURLLoader* BlinkPlatformImpl::createURLLoader() {
-  return new WebURLLoaderImpl(network_service_.get());
+  return new WebURLLoaderImpl(network_service_.get(), &blob_registry_);
 }
 
 blink::WebSocketHandle* BlinkPlatformImpl::createWebSocketHandle() {
diff --git a/mojo/services/html_viewer/blink_platform_impl.h b/components/html_viewer/blink_platform_impl.h
similarity index 84%
rename from mojo/services/html_viewer/blink_platform_impl.h
rename to components/html_viewer/blink_platform_impl.h
index 12d23afb..3f9a803 100644
--- a/mojo/services/html_viewer/blink_platform_impl.h
+++ b/components/html_viewer/blink_platform_impl.h
@@ -2,20 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_SERVICES_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
 
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_local_storage.h"
 #include "base/timer/timer.h"
 #include "cc/blink/web_compositor_support_impl.h"
+#include "components/html_viewer/blink_resource_map.h"
+#include "components/html_viewer/mock_web_blob_registry_impl.h"
+#include "components/html_viewer/web_mime_registry_impl.h"
+#include "components/html_viewer/web_notification_manager_impl.h"
+#include "components/html_viewer/web_scheduler_impl.h"
+#include "components/html_viewer/web_theme_engine_impl.h"
 #include "components/webcrypto/webcrypto_impl.h"
-#include "mojo/services/html_viewer/blink_resource_map.h"
-#include "mojo/services/html_viewer/webmimeregistry_impl.h"
-#include "mojo/services/html_viewer/webnotificationmanager_impl.h"
-#include "mojo/services/html_viewer/webscheduler_impl.h"
-#include "mojo/services/html_viewer/webthemeengine_impl.h"
 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
 #include "third_party/WebKit/public/platform/Platform.h"
 #include "third_party/WebKit/public/platform/WebScrollbarBehavior.h"
@@ -42,6 +43,7 @@
   virtual blink::WebThemeEngine* themeEngine();
   virtual blink::WebScheduler* scheduler();
   virtual blink::WebString defaultLocale();
+  virtual blink::WebBlobRegistry* blobRegistry();
   virtual double currentTime();
   virtual double monotonicallyIncreasingTime();
   virtual void cryptographicallyRandomValues(unsigned char* buffer,
@@ -52,6 +54,8 @@
   virtual void callOnMainThread(void (*func)(void*), void* context);
   virtual bool isThreadedCompositingEnabled();
   virtual blink::WebCompositorSupport* compositorSupport();
+  void createMessageChannel(blink::WebMessagePortChannel** channel1,
+                            blink::WebMessagePortChannel** channel2) override;
   virtual blink::WebURLLoader* createURLLoader();
   virtual blink::WebSocketHandle* createWebSocketHandle();
   virtual blink::WebString userAgent();
@@ -104,6 +108,7 @@
   blink::WebScrollbarBehavior scrollbar_behavior_;
   BlinkResourceMap blink_resource_map_;
   mojo::NetworkServicePtr network_service_;
+  MockWebBlobRegistryImpl blob_registry_;
   scoped_ptr<WebCookieJarImpl> cookie_jar_;
   scoped_ptr<WebClipboardImpl> clipboard_;
 
@@ -112,4 +117,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
diff --git a/mojo/services/html_viewer/blink_resource_constants.h b/components/html_viewer/blink_resource_constants.h
similarity index 96%
rename from mojo/services/html_viewer/blink_resource_constants.h
rename to components/html_viewer/blink_resource_constants.h
index 14d08d0..49c5a71b6 100644
--- a/mojo/services/html_viewer/blink_resource_constants.h
+++ b/components/html_viewer/blink_resource_constants.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 MOJO_SERVICES_HTML_VIEWER_BLINK_RESOURCE_CONSTANTS_H_
-#define MOJO_SERVICES_HTML_VIEWER_BLINK_RESOURCE_CONSTANTS_H_
+#ifndef COMPONENTS_HTML_VIEWER_BLINK_RESOURCE_CONSTANTS_H_
+#define COMPONENTS_HTML_VIEWER_BLINK_RESOURCE_CONSTANTS_H_
 
 #include "blink/public/resources/grit/blink_image_resources.h"
 #include "blink/public/resources/grit/blink_resources.h"
@@ -124,4 +124,4 @@
 
 } // namespace html_viewer
 
-#endif // MOJO_SERVICES_HTML_VIEWER_BLINK_RESOURCE_CONSTANTS_H_
+#endif // COMPONENTS_HTML_VIEWER_BLINK_RESOURCE_CONSTANTS_H_
diff --git a/mojo/services/html_viewer/blink_url_request_type_converters.cc b/components/html_viewer/blink_url_request_type_converters.cc
similarity index 97%
rename from mojo/services/html_viewer/blink_url_request_type_converters.cc
rename to components/html_viewer/blink_url_request_type_converters.cc
index 3cae06f..29fbbe69 100644
--- a/mojo/services/html_viewer/blink_url_request_type_converters.cc
+++ b/components/html_viewer/blink_url_request_type_converters.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 "mojo/services/html_viewer/blink_url_request_type_converters.h"
+#include "components/html_viewer/blink_url_request_type_converters.h"
 
 #include "base/strings/string_util.h"
 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
diff --git a/mojo/services/html_viewer/blink_url_request_type_converters.h b/components/html_viewer/blink_url_request_type_converters.h
similarity index 69%
rename from mojo/services/html_viewer/blink_url_request_type_converters.h
rename to components/html_viewer/blink_url_request_type_converters.h
index 43cc050..7812a7c 100644
--- a/mojo/services/html_viewer/blink_url_request_type_converters.h
+++ b/components/html_viewer/blink_url_request_type_converters.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 MOJO_SERVICES_HTML_VIEWER_BLINK_URL_REQUEST_TYPE_CONVERTERS_H_
-#define MOJO_SERVICES_HTML_VIEWER_BLINK_URL_REQUEST_TYPE_CONVERTERS_H_
+#ifndef COMPONENTS_HTML_VIEWER_BLINK_URL_REQUEST_TYPE_CONVERTERS_H_
+#define COMPONENTS_HTML_VIEWER_BLINK_URL_REQUEST_TYPE_CONVERTERS_H_
 
 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
 
@@ -20,4 +20,4 @@
 
 }  // namespace mojo
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_BLINK_URL_REQUEST_TYPE_CONVERTERS_H_
+#endif  // COMPONENTS_HTML_VIEWER_BLINK_URL_REQUEST_TYPE_CONVERTERS_H_
diff --git a/mojo/services/html_viewer/discardable_memory_allocator.cc b/components/html_viewer/discardable_memory_allocator.cc
similarity index 98%
rename from mojo/services/html_viewer/discardable_memory_allocator.cc
rename to components/html_viewer/discardable_memory_allocator.cc
index a75ac63..f76deee 100644
--- a/mojo/services/html_viewer/discardable_memory_allocator.cc
+++ b/components/html_viewer/discardable_memory_allocator.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 "mojo/services/html_viewer/discardable_memory_allocator.h"
+#include "components/html_viewer/discardable_memory_allocator.h"
 
 #include "base/memory/discardable_memory.h"
 #include "base/memory/weak_ptr.h"
diff --git a/mojo/services/html_viewer/discardable_memory_allocator.h b/components/html_viewer/discardable_memory_allocator.h
similarity index 90%
rename from mojo/services/html_viewer/discardable_memory_allocator.h
rename to components/html_viewer/discardable_memory_allocator.h
index 73d6bcf..be7f063e 100644
--- a/mojo/services/html_viewer/discardable_memory_allocator.h
+++ b/components/html_viewer/discardable_memory_allocator.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 MOJO_SERVICES_HTML_VIEWER_DISCARDABLE_MEMORY_ALLOCATOR_H_
-#define MOJO_SERVICES_HTML_VIEWER_DISCARDABLE_MEMORY_ALLOCATOR_H_
+#ifndef COMPONENTS_HTML_VIEWER_DISCARDABLE_MEMORY_ALLOCATOR_H_
+#define COMPONENTS_HTML_VIEWER_DISCARDABLE_MEMORY_ALLOCATOR_H_
 
 #include <list>
 
@@ -58,4 +58,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_DISCARDABLE_MEMORY_ALLOCATOR_H_
+#endif  // COMPONENTS_HTML_VIEWER_DISCARDABLE_MEMORY_ALLOCATOR_H_
diff --git a/mojo/services/html_viewer/discardable_memory_allocator_unittest.cc b/components/html_viewer/discardable_memory_allocator_unittest.cc
similarity index 96%
rename from mojo/services/html_viewer/discardable_memory_allocator_unittest.cc
rename to components/html_viewer/discardable_memory_allocator_unittest.cc
index d63d2c5..cc73fb0 100644
--- a/mojo/services/html_viewer/discardable_memory_allocator_unittest.cc
+++ b/components/html_viewer/discardable_memory_allocator_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 "mojo/services/html_viewer/discardable_memory_allocator.h"
+#include "components/html_viewer/discardable_memory_allocator.h"
 
 #include "base/memory/discardable_memory.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/mojo/services/html_viewer/generate_blink_resource_map.py b/components/html_viewer/generate_blink_resource_map.py
similarity index 93%
rename from mojo/services/html_viewer/generate_blink_resource_map.py
rename to components/html_viewer/generate_blink_resource_map.py
index 0fdee71..e60be14 100644
--- a/mojo/services/html_viewer/generate_blink_resource_map.py
+++ b/components/html_viewer/generate_blink_resource_map.py
@@ -10,7 +10,7 @@
 
 try:
   grit_module_path = os.path.join(
-      os.path.dirname(__file__),  '..', '..', '..', 'tools', 'grit')
+      os.path.dirname(__file__),  '..', '..', 'tools', 'grit')
   sys.path.insert(0, grit_module_path)
   from grit.format import data_pack as DataPack
 except ImportError, e:
@@ -22,8 +22,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_SERVICES_HTML_VIEWER_BLINK_RESOURCE_MAP_H_
-#define MOJO_SERVICES_HTML_VIEWER_BLINK_RESOURCE_MAP_H_
+#ifndef COMPONENTS_HTML_VIEWER_BLINK_RESOURCE_MAP_H_
+#define COMPONENTS_HTML_VIEWER_BLINK_RESOURCE_MAP_H_
 
 #include <map>
 
@@ -54,7 +54,7 @@
 };
 
 } // namespace html_viewer
-#endif // MOJO_SERVICES_HTML_VIEWER_BLINK_RESOURCE_MAP_H_"""
+#endif // COMPONENTS_HTML_VIEWER_BLINK_RESOURCE_MAP_H_"""
 
 cpp_template = \
 """// Copyright 2015 The Chromium Authors. All rights reserved.
diff --git a/mojo/services/html_viewer/html_document.cc b/components/html_viewer/html_document.cc
similarity index 94%
rename from mojo/services/html_viewer/html_document.cc
rename to components/html_viewer/html_document.cc
index 7074080a..e1b57cf 100644
--- a/mojo/services/html_viewer/html_document.cc
+++ b/components/html_viewer/html_document.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 "mojo/services/html_viewer/html_document.h"
+#include "components/html_viewer/html_document.h"
 
 #include "base/bind.h"
 #include "base/location.h"
@@ -12,15 +12,15 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/thread_task_runner_handle.h"
+#include "components/html_viewer/blink_input_events_type_converters.h"
+#include "components/html_viewer/blink_url_request_type_converters.h"
+#include "components/html_viewer/web_layer_tree_view_impl.h"
+#include "components/html_viewer/web_media_player_factory.h"
+#include "components/html_viewer/web_storage_namespace_impl.h"
+#include "components/html_viewer/web_url_loader_impl.h"
 #include "media/blink/webencryptedmediaclient_impl.h"
 #include "media/cdm/default_cdm_factory.h"
 #include "media/filters/default_media_permission.h"
-#include "mojo/services/html_viewer/blink_input_events_type_converters.h"
-#include "mojo/services/html_viewer/blink_url_request_type_converters.h"
-#include "mojo/services/html_viewer/weblayertreeview_impl.h"
-#include "mojo/services/html_viewer/webmediaplayer_factory.h"
-#include "mojo/services/html_viewer/webstoragenamespace_impl.h"
-#include "mojo/services/html_viewer/weburlloader_impl.h"
 #include "skia/ext/refptr.h"
 #include "third_party/WebKit/public/platform/Platform.h"
 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
@@ -98,6 +98,12 @@
   if (EqualsASCII(request.httpMethod(), "POST"))
     return true;
 
+  // Logging into Gmail fails when the referrer isn't sent with a request.
+  // TODO(jam): pass referrer and other HTTP data to NavigatorHost so we can
+  // use a new process in this case.
+  if (!request.httpHeaderField(blink::WebString::fromUTF8("Referer")).isEmpty())
+    return true;
+
   // Otherwise we don't know if we're the right app to handle this request. Ask
   // host to do the navigation for us.
   return false;
diff --git a/mojo/services/html_viewer/html_document.h b/components/html_viewer/html_document.h
similarity index 95%
rename from mojo/services/html_viewer/html_document.h
rename to components/html_viewer/html_document.h
index 49b83ba..4068888 100644
--- a/mojo/services/html_viewer/html_document.h
+++ b/components/html_viewer/html_document.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 MOJO_SERVICES_HTML_VIEWER_HTML_DOCUMENT_H_
-#define MOJO_SERVICES_HTML_VIEWER_HTML_DOCUMENT_H_
+#ifndef COMPONENTS_HTML_VIEWER_HTML_DOCUMENT_H_
+#define COMPONENTS_HTML_VIEWER_HTML_DOCUMENT_H_
 
 #include <set>
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "mojo/services/html_viewer/ax_provider_impl.h"
-#include "mojo/services/html_viewer/touch_handler.h"
+#include "components/html_viewer/ax_provider_impl.h"
+#include "components/html_viewer/touch_handler.h"
 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
 #include "third_party/WebKit/public/web/WebFrameClient.h"
 #include "third_party/WebKit/public/web/WebSandboxFlags.h"
@@ -174,4 +174,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_HTML_DOCUMENT_H_
+#endif  // COMPONENTS_HTML_VIEWER_HTML_DOCUMENT_H_
diff --git a/mojo/services/html_viewer/html_viewer.cc b/components/html_viewer/html_viewer.cc
similarity index 97%
rename from mojo/services/html_viewer/html_viewer.cc
rename to components/html_viewer/html_viewer.cc
index ad7b6ad..d71d043 100644
--- a/mojo/services/html_viewer/html_viewer.cc
+++ b/components/html_viewer/html_viewer.cc
@@ -10,12 +10,12 @@
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
+#include "components/html_viewer/blink_platform_impl.h"
+#include "components/html_viewer/discardable_memory_allocator.h"
+#include "components/html_viewer/html_document.h"
+#include "components/html_viewer/web_media_player_factory.h"
 #include "gin/v8_initializer.h"
 #include "mojo/application/application_runner_chromium.h"
-#include "mojo/services/html_viewer/blink_platform_impl.h"
-#include "mojo/services/html_viewer/discardable_memory_allocator.h"
-#include "mojo/services/html_viewer/html_document.h"
-#include "mojo/services/html_viewer/webmediaplayer_factory.h"
 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
 #include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
diff --git a/mojo/services/html_viewer/html_viewer_version.rc b/components/html_viewer/html_viewer_version.rc
similarity index 100%
rename from mojo/services/html_viewer/html_viewer_version.rc
rename to components/html_viewer/html_viewer_version.rc
diff --git a/components/html_viewer/mock_web_blob_registry_impl.cc b/components/html_viewer/mock_web_blob_registry_impl.cc
new file mode 100644
index 0000000..02cff57
--- /dev/null
+++ b/components/html_viewer/mock_web_blob_registry_impl.cc
@@ -0,0 +1,121 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/html_viewer/mock_web_blob_registry_impl.h"
+
+#include "third_party/WebKit/public/platform/WebBlobData.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebURL.h"
+#include "third_party/WebKit/public/platform/WebVector.h"
+
+using blink::WebBlobData;
+using blink::WebString;
+using blink::WebURL;
+using blink::WebVector;
+
+namespace html_viewer {
+
+MockWebBlobRegistryImpl::MockWebBlobRegistryImpl() {
+}
+
+MockWebBlobRegistryImpl::~MockWebBlobRegistryImpl() {
+}
+
+void MockWebBlobRegistryImpl::registerBlobData(const WebString& uuid,
+                                               const WebBlobData& data) {
+  const std::string uuid_str(uuid.utf8());
+  blob_ref_count_map_[uuid_str] = 1;
+  scoped_ptr<ScopedVector<blink::WebBlobData::Item>> items(
+      new ScopedVector<blink::WebBlobData::Item>);
+  items->reserve(data.itemCount());
+  for (size_t i = 0; i < data.itemCount(); ++i) {
+    scoped_ptr<blink::WebBlobData::Item> item(new blink::WebBlobData::Item);
+    data.itemAt(i, *item);
+    items->push_back(item.release());
+  }
+  blob_data_items_map_.set(uuid_str, items.Pass());
+}
+
+void MockWebBlobRegistryImpl::addBlobDataRef(const WebString& uuid) {
+  blob_ref_count_map_[uuid.utf8()]++;
+}
+
+void MockWebBlobRegistryImpl::removeBlobDataRef(const WebString& uuid) {
+  const std::string uuid_str(uuid.utf8());
+  auto it = blob_ref_count_map_.find(uuid_str);
+  if (it != blob_ref_count_map_.end() && !--it->second) {
+    blob_data_items_map_.erase(uuid_str);
+    blob_ref_count_map_.erase(it);
+  }
+}
+
+void MockWebBlobRegistryImpl::registerPublicBlobURL(const WebURL& url,
+                                                    const WebString& uuid) {
+  public_url_to_uuid_[url.spec()] = uuid;
+  addBlobDataRef(uuid);
+}
+
+void MockWebBlobRegistryImpl::revokePublicBlobURL(const WebURL& url) {
+  auto it = public_url_to_uuid_.find(url.spec());
+  if (it != public_url_to_uuid_.end()) {
+    removeBlobDataRef(it->second);
+    public_url_to_uuid_.erase(it);
+  }
+}
+
+void MockWebBlobRegistryImpl::registerStreamURL(const WebURL& url,
+                                                const WebString& content_type) {
+  NOTIMPLEMENTED();
+}
+
+void MockWebBlobRegistryImpl::registerStreamURL(const WebURL& url,
+                                                const blink::WebURL& src_url) {
+  NOTIMPLEMENTED();
+}
+
+void MockWebBlobRegistryImpl::addDataToStream(const WebURL& url,
+                                              const char* data,
+                                              size_t length) {
+  NOTIMPLEMENTED();
+}
+
+void MockWebBlobRegistryImpl::flushStream(const WebURL& url) {
+  NOTIMPLEMENTED();
+}
+
+void MockWebBlobRegistryImpl::finalizeStream(const WebURL& url) {
+  NOTIMPLEMENTED();
+}
+
+void MockWebBlobRegistryImpl::abortStream(const WebURL& url) {
+  NOTIMPLEMENTED();
+}
+
+void MockWebBlobRegistryImpl::unregisterStreamURL(const WebURL& url) {
+  NOTIMPLEMENTED();
+}
+
+bool MockWebBlobRegistryImpl::GetUUIDForURL(const blink::WebURL& url,
+                                            blink::WebString* uuid) const {
+  auto it = public_url_to_uuid_.find(url.spec());
+  if (it != public_url_to_uuid_.end()) {
+    *uuid = it->second;
+    return true;
+  }
+
+  return false;
+}
+
+bool MockWebBlobRegistryImpl::GetBlobItems(
+    const WebString& uuid,
+    WebVector<WebBlobData::Item*>* items) const {
+  ScopedVector<WebBlobData::Item>* item_vector =
+      blob_data_items_map_.get(uuid.utf8());
+  if (!item_vector)
+    return false;
+  *items = item_vector->get();
+  return true;
+}
+
+}  // namespace html_viewer
diff --git a/components/html_viewer/mock_web_blob_registry_impl.h b/components/html_viewer/mock_web_blob_registry_impl.h
new file mode 100644
index 0000000..8c8acbbb
--- /dev/null
+++ b/components/html_viewer/mock_web_blob_registry_impl.h
@@ -0,0 +1,64 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_HTML_VIEWER_MOCK_WEB_BLOB_REGISTRY_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_MOCK_WEB_BLOB_REGISTRY_IMPL_H_
+
+#include <map>
+
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
+#include "third_party/WebKit/public/platform/WebBlobData.h"
+#include "third_party/WebKit/public/platform/WebBlobRegistry.h"
+#include "third_party/WebKit/public/platform/WebVector.h"
+
+namespace html_viewer {
+
+// TODO(erg): For now, this is a just a copy of content's testing
+// mock. Eventually, this should be turned into a real implementation, but this
+// at least lets us get github working.
+class MockWebBlobRegistryImpl : public blink::WebBlobRegistry {
+ public:
+  MockWebBlobRegistryImpl();
+  virtual ~MockWebBlobRegistryImpl();
+
+  virtual void registerBlobData(const blink::WebString& uuid,
+                                const blink::WebBlobData& data);
+  virtual void addBlobDataRef(const blink::WebString& uuid);
+  virtual void removeBlobDataRef(const blink::WebString& uuid);
+  virtual void registerPublicBlobURL(const blink::WebURL&,
+                                     const blink::WebString& uuid);
+  virtual void revokePublicBlobURL(const blink::WebURL&);
+
+  // Additional support for Streams.
+  virtual void registerStreamURL(const blink::WebURL& url,
+                                 const blink::WebString& content_type);
+  virtual void registerStreamURL(const blink::WebURL& url,
+                                 const blink::WebURL& src_url);
+  virtual void addDataToStream(const blink::WebURL& url,
+                               const char* data,
+                               size_t length);
+  virtual void flushStream(const blink::WebURL& url);
+  virtual void finalizeStream(const blink::WebURL& url);
+  virtual void abortStream(const blink::WebURL& url);
+  virtual void unregisterStreamURL(const blink::WebURL& url);
+
+  bool GetUUIDForURL(const blink::WebURL& url, blink::WebString* uuid) const;
+  bool GetBlobItems(const blink::WebString& uuid,
+                    blink::WebVector<blink::WebBlobData::Item*>* items) const;
+
+ private:
+  base::ScopedPtrHashMap<std::string, ScopedVector<blink::WebBlobData::Item>>
+      blob_data_items_map_;
+  std::map<std::string, int> blob_ref_count_map_;
+
+  std::map<std::string, blink::WebString> public_url_to_uuid_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockWebBlobRegistryImpl);
+};
+
+}  // namespace html_viewer
+
+#endif  // COMPONENTS_HTML_VIEWER_MOCK_WEB_BLOB_REGISTRY_IMPL_H_
diff --git a/mojo/services/html_viewer/test_blink_platform_impl.cc b/components/html_viewer/test_blink_platform_impl.cc
similarity index 88%
rename from mojo/services/html_viewer/test_blink_platform_impl.cc
rename to components/html_viewer/test_blink_platform_impl.cc
index 8875c362..700502df 100644
--- a/mojo/services/html_viewer/test_blink_platform_impl.cc
+++ b/components/html_viewer/test_blink_platform_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 "mojo/services/html_viewer/test_blink_platform_impl.h"
+#include "components/html_viewer/test_blink_platform_impl.h"
 
 namespace html_viewer {
 
diff --git a/mojo/services/html_viewer/test_blink_platform_impl.h b/components/html_viewer/test_blink_platform_impl.h
similarity index 73%
rename from mojo/services/html_viewer/test_blink_platform_impl.h
rename to components/html_viewer/test_blink_platform_impl.h
index 8790e4d..c3b6768 100644
--- a/mojo/services/html_viewer/test_blink_platform_impl.h
+++ b/components/html_viewer/test_blink_platform_impl.h
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_SERVICES_HTML_VIEWER_TEST_BLINK_PLATFORM_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_TEST_BLINK_PLATFORM_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_TEST_BLINK_PLATFORM_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_TEST_BLINK_PLATFORM_IMPL_H_
 
-#include "mojo/services/html_viewer/blink_platform_impl.h"
+#include "components/html_viewer/blink_platform_impl.h"
 
 #include "third_party/WebKit/public/platform/WebClipboard.h"
 #include "third_party/WebKit/public/platform/WebCookieJar.h"
@@ -28,4 +28,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_TEST_BLINK_PLATFORM_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_TEST_BLINK_PLATFORM_IMPL_H_
diff --git a/mojo/services/html_viewer/touch_handler.cc b/components/html_viewer/touch_handler.cc
similarity index 98%
rename from mojo/services/html_viewer/touch_handler.cc
rename to components/html_viewer/touch_handler.cc
index 6261dab..e968e602 100644
--- a/mojo/services/html_viewer/touch_handler.cc
+++ b/components/html_viewer/touch_handler.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 "mojo/services/html_viewer/touch_handler.h"
+#include "components/html_viewer/touch_handler.h"
 
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "third_party/WebKit/public/web/WebView.h"
diff --git a/mojo/services/html_viewer/touch_handler.h b/components/html_viewer/touch_handler.h
similarity index 90%
rename from mojo/services/html_viewer/touch_handler.h
rename to components/html_viewer/touch_handler.h
index a4a8fbb6..460a3d5 100644
--- a/mojo/services/html_viewer/touch_handler.h
+++ b/components/html_viewer/touch_handler.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 MOJO_SERVICES_HTML_VIEWER_TOUCH_HANDLER_H_
-#define MOJO_SERVICES_HTML_VIEWER_TOUCH_HANDLER_H_
+#ifndef COMPONENTS_HTML_VIEWER_TOUCH_HANDLER_H_
+#define COMPONENTS_HTML_VIEWER_TOUCH_HANDLER_H_
 
 #include "base/basictypes.h"
 #include "ui/events/gesture_detection/filtered_gesture_provider.h"
@@ -59,4 +59,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_TOUCH_HANDLER_H_
+#endif  // COMPONENTS_HTML_VIEWER_TOUCH_HANDLER_H_
diff --git a/mojo/services/html_viewer/webclipboard_impl.cc b/components/html_viewer/web_clipboard_impl.cc
similarity index 97%
rename from mojo/services/html_viewer/webclipboard_impl.cc
rename to components/html_viewer/web_clipboard_impl.cc
index 05c0be4..8810c3d0 100644
--- a/mojo/services/html_viewer/webclipboard_impl.cc
+++ b/components/html_viewer/web_clipboard_impl.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 "mojo/services/html_viewer/webclipboard_impl.h"
+#include "components/html_viewer/web_clipboard_impl.h"
 
 #include "base/bind.h"
-#include "mojo/services/html_viewer/blink_basic_type_converters.h"
+#include "components/html_viewer/blink_basic_type_converters.h"
 
 using mojo::Array;
 using mojo::Clipboard;
diff --git a/mojo/services/html_viewer/webclipboard_impl.h b/components/html_viewer/web_clipboard_impl.h
similarity index 90%
rename from mojo/services/html_viewer/webclipboard_impl.h
rename to components/html_viewer/web_clipboard_impl.h
index 8109506..f671e31 100644
--- a/mojo/services/html_viewer/webclipboard_impl.h
+++ b/components/html_viewer/web_clipboard_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBCLIPBOARD_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBCLIPBOARD_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_CLIPBOARD_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_CLIPBOARD_IMPL_H_
 
 #include "third_party/WebKit/public/platform/WebClipboard.h"
 #include "third_party/mojo_services/src/clipboard/public/interfaces/clipboard.mojom.h"
@@ -46,4 +46,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBCLIPBOARD_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_CLIPBOARD_IMPL_H_
diff --git a/mojo/services/html_viewer/webcookiejar_impl.cc b/components/html_viewer/web_cookie_jar_impl.cc
similarity index 96%
rename from mojo/services/html_viewer/webcookiejar_impl.cc
rename to components/html_viewer/web_cookie_jar_impl.cc
index 0b4b012..019acfb 100644
--- a/mojo/services/html_viewer/webcookiejar_impl.cc
+++ b/components/html_viewer/web_cookie_jar_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 "mojo/services/html_viewer/webcookiejar_impl.h"
+#include "components/html_viewer/web_cookie_jar_impl.h"
 
 #include "base/bind.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
diff --git a/mojo/services/html_viewer/webcookiejar_impl.h b/components/html_viewer/web_cookie_jar_impl.h
similarity index 85%
rename from mojo/services/html_viewer/webcookiejar_impl.h
rename to components/html_viewer/web_cookie_jar_impl.h
index 052a45f..bec897e 100644
--- a/mojo/services/html_viewer/webcookiejar_impl.h
+++ b/components/html_viewer/web_cookie_jar_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBCOOKIEJAR_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBCOOKIEJAR_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_COOKIE_JAR_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_COOKIE_JAR_IMPL_H_
 
 #include "mojo/services/network/public/interfaces/cookie_store.mojom.h"
 #include "third_party/WebKit/public/platform/WebCookieJar.h"
@@ -33,4 +33,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBCOOKIEJAR_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_COOKIE_JAR_IMPL_H_
diff --git a/mojo/services/html_viewer/weblayertreeview_impl.cc b/components/html_viewer/web_layer_tree_view_impl.cc
similarity index 98%
rename from mojo/services/html_viewer/weblayertreeview_impl.cc
rename to components/html_viewer/web_layer_tree_view_impl.cc
index fb73ba3d..94f1485 100644
--- a/mojo/services/html_viewer/weblayertreeview_impl.cc
+++ b/components/html_viewer/web_layer_tree_view_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 "mojo/services/html_viewer/weblayertreeview_impl.h"
+#include "components/html_viewer/web_layer_tree_view_impl.h"
 
 #include "base/message_loop/message_loop_proxy.h"
 #include "cc/blink/web_layer_impl.h"
diff --git a/mojo/services/html_viewer/weblayertreeview_impl.h b/components/html_viewer/web_layer_tree_view_impl.h
similarity index 96%
rename from mojo/services/html_viewer/weblayertreeview_impl.h
rename to components/html_viewer/web_layer_tree_view_impl.h
index 32e36a4..b2c352a2 100644
--- a/mojo/services/html_viewer/weblayertreeview_impl.h
+++ b/components/html_viewer/web_layer_tree_view_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBLAYERTREEVIEW_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBLAYERTREEVIEW_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_LAYER_TREE_VIEW_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_LAYER_TREE_VIEW_IMPL_H_
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -133,4 +133,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBLAYERTREEVIEW_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_LAYER_TREE_VIEW_IMPL_H_
diff --git a/mojo/services/html_viewer/webmediaplayer_factory.cc b/components/html_viewer/web_media_player_factory.cc
similarity index 98%
rename from mojo/services/html_viewer/webmediaplayer_factory.cc
rename to components/html_viewer/web_media_player_factory.cc
index e7cec99..0de85f3 100644
--- a/mojo/services/html_viewer/webmediaplayer_factory.cc
+++ b/components/html_viewer/web_media_player_factory.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 "mojo/services/html_viewer/webmediaplayer_factory.h"
+#include "components/html_viewer/web_media_player_factory.h"
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
diff --git a/mojo/services/html_viewer/webmediaplayer_factory.h b/components/html_viewer/web_media_player_factory.h
similarity index 91%
rename from mojo/services/html_viewer/webmediaplayer_factory.h
rename to components/html_viewer/web_media_player_factory.h
index 723b54f..360a696 100644
--- a/mojo/services/html_viewer/webmediaplayer_factory.h
+++ b/components/html_viewer/web_media_player_factory.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 MOJO_SERVICES_HTML_VIEWER_WEBMEDIAPLAYER_FACTORY_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBMEDIAPLAYER_FACTORY_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_MEDIA_PLAYER_FACTORY_H_
+#define COMPONENTS_HTML_VIEWER_WEB_MEDIA_PLAYER_FACTORY_H_
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -73,4 +73,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBMEDIAPLAYER_FACTORY_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_MEDIA_PLAYER_FACTORY_H_
diff --git a/components/html_viewer/web_message_port_channel_impl.cc b/components/html_viewer/web_message_port_channel_impl.cc
new file mode 100644
index 0000000..45e75fc
--- /dev/null
+++ b/components/html_viewer/web_message_port_channel_impl.cc
@@ -0,0 +1,132 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/html_viewer/web_message_port_channel_impl.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "third_party/WebKit/public/platform/WebMessagePortChannelClient.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h"
+
+using blink::WebMessagePortChannel;
+using blink::WebMessagePortChannelArray;
+using blink::WebMessagePortChannelClient;
+using blink::WebString;
+
+namespace html_viewer {
+
+void WebMessagePortChannelImpl::CreatePair(
+    blink::WebMessagePortChannel** channel1,
+    blink::WebMessagePortChannel** channel2) {
+  mojo::ScopedMessagePipeHandle pipe1;
+  mojo::ScopedMessagePipeHandle pipe2;
+  MojoResult result = mojo::CreateMessagePipe(nullptr, &pipe1, &pipe2);
+  if (result != MOJO_RESULT_OK) {
+    NOTREACHED();
+    return;
+  }
+
+  *channel1 = new WebMessagePortChannelImpl(pipe1.Pass());;
+  *channel2 = new WebMessagePortChannelImpl(pipe2.Pass());
+}
+
+WebMessagePortChannelImpl::WebMessagePortChannelImpl(
+    mojo::ScopedMessagePipeHandle pipe)
+    : client_(nullptr), pipe_(pipe.Pass()) {
+  WaitForNextMessage();
+}
+
+WebMessagePortChannelImpl::~WebMessagePortChannelImpl() {
+}
+
+void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) {
+  client_ = client;
+}
+
+void WebMessagePortChannelImpl::destroy() {
+  setClient(nullptr);
+  delete this;
+}
+
+void WebMessagePortChannelImpl::postMessage(
+    const WebString& message_as_string,
+    WebMessagePortChannelArray* channels) {
+  base::string16 string = message_as_string;
+
+  std::vector<MojoHandle> handles;
+  if (channels) {
+    for (size_t i = 0; i < channels->size(); ++i) {
+      WebMessagePortChannelImpl* channel =
+          static_cast<WebMessagePortChannelImpl*>((*channels)[i]);
+      handles.push_back(channel->pipe_.release().value());
+      channel->handle_watcher_.Stop();
+    }
+    delete channels;
+  }
+
+  uint32_t num_handles = static_cast<uint32_t>(handles.size());
+  MojoHandle* handles_ptr = handles.empty() ? nullptr : &handles[0];
+
+  MojoResult result = MojoWriteMessage(
+      pipe_.get().value(), string.c_str(),
+      static_cast<uint32_t>(string.length() * sizeof(base::char16)),
+      handles_ptr, num_handles, MOJO_WRITE_MESSAGE_FLAG_NONE);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
+}
+
+bool WebMessagePortChannelImpl::tryGetMessage(
+    WebString* message,
+    WebMessagePortChannelArray& channels) {
+  uint32_t num_bytes = 0;
+  uint32_t num_handles = 0;
+  MojoResult result = MojoReadMessage(
+      pipe_.get().value(), nullptr, &num_bytes, nullptr, &num_handles,
+      MOJO_READ_MESSAGE_FLAG_NONE);
+  if (result != MOJO_RESULT_RESOURCE_EXHAUSTED)
+    return false;
+
+  base::string16 message16;
+  CHECK(num_bytes % sizeof(base::char16) == 0);
+  message16.resize(num_bytes / sizeof(base::char16));
+  std::vector<MojoHandle> handles;
+  handles.resize(num_handles);
+
+  MojoHandle* handles_ptr = handles.empty() ? nullptr : &handles[0];
+  result = MojoReadMessage(
+      pipe_.get().value(), &message16[0], &num_bytes, handles_ptr, &num_handles,
+      MOJO_READ_MESSAGE_FLAG_NONE);
+  if (result != MOJO_RESULT_OK) {
+    NOTREACHED();
+    return false;
+  }
+
+  *message = message16;
+  WebMessagePortChannelArray ports(handles.size());
+  for (size_t i = 0; i < handles.size(); ++i) {
+    mojo::MessagePipeHandle mph(handles[i]);
+    mojo::ScopedMessagePipeHandle handle(mph);
+    ports[i] = new WebMessagePortChannelImpl(handle.Pass());
+  }
+  channels = ports;
+  return true;
+}
+
+void WebMessagePortChannelImpl::WaitForNextMessage() {
+  handle_watcher_.Start(
+      pipe_.get(),
+      MOJO_HANDLE_SIGNAL_READABLE,
+      MOJO_DEADLINE_INDEFINITE,
+      base::Bind(&WebMessagePortChannelImpl::OnMessageAvailable,
+                 base::Unretained(this)));
+}
+
+void WebMessagePortChannelImpl::OnMessageAvailable(MojoResult result) {
+  DCHECK_EQ(MOJO_RESULT_OK, result);
+  client_->messageAvailable();
+  WaitForNextMessage();
+}
+
+}  // namespace html_viewer
diff --git a/components/html_viewer/web_message_port_channel_impl.h b/components/html_viewer/web_message_port_channel_impl.h
new file mode 100644
index 0000000..8c723bc
--- /dev/null
+++ b/components/html_viewer/web_message_port_channel_impl.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_HTML_VIEWER_WEB_MESSAGE_PORT_CHANNEL_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_MESSAGE_PORT_CHANNEL_IMPL_H_
+
+#include "base/basictypes.h"
+#include "mojo/common/handle_watcher.h"
+#include "third_party/WebKit/public/platform/WebMessagePortChannel.h"
+#include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h"
+
+namespace html_viewer {
+
+class WebMessagePortChannelImpl : public blink::WebMessagePortChannel {
+ public:
+  static void CreatePair(
+      blink::WebMessagePortChannel** channel1,
+      blink::WebMessagePortChannel** channel2);
+
+ private:
+  explicit WebMessagePortChannelImpl(mojo::ScopedMessagePipeHandle pipe);
+  virtual ~WebMessagePortChannelImpl();
+
+  // blink::WebMessagePortChannel implementation.
+  virtual void setClient(blink::WebMessagePortChannelClient* client);
+  virtual void destroy();
+  virtual void postMessage(const blink::WebString& message,
+                           blink::WebMessagePortChannelArray* channels);
+  virtual bool tryGetMessage(blink::WebString* message,
+                             blink::WebMessagePortChannelArray& channels);
+
+  void WaitForNextMessage();
+  void OnMessageAvailable(MojoResult result);
+
+  blink::WebMessagePortChannelClient* client_;
+  mojo::ScopedMessagePipeHandle pipe_;
+  mojo::common::HandleWatcher handle_watcher_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebMessagePortChannelImpl);
+};
+
+}  // namespace html_viewer
+
+#endif  // COMPONENTS_HTML_VIEWER_WEB_MESSAGE_PORT_CHANNEL_IMPL_H_
diff --git a/mojo/services/html_viewer/webmimeregistry_impl.cc b/components/html_viewer/web_mime_registry_impl.cc
similarity index 98%
rename from mojo/services/html_viewer/webmimeregistry_impl.cc
rename to components/html_viewer/web_mime_registry_impl.cc
index 9878e87..46c7c03 100644
--- a/mojo/services/html_viewer/webmimeregistry_impl.cc
+++ b/components/html_viewer/web_mime_registry_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 "mojo/services/html_viewer/webmimeregistry_impl.h"
+#include "components/html_viewer/web_mime_registry_impl.h"
 
 #include "base/files/file_path.h"
 #include "base/strings/string_util.h"
diff --git a/mojo/services/html_viewer/webmimeregistry_impl.h b/components/html_viewer/web_mime_registry_impl.h
similarity index 89%
rename from mojo/services/html_viewer/webmimeregistry_impl.h
rename to components/html_viewer/web_mime_registry_impl.h
index 87c0156..17f7f1b 100644
--- a/mojo/services/html_viewer/webmimeregistry_impl.h
+++ b/components/html_viewer/web_mime_registry_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBMIMEREGISTRY_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBMIMEREGISTRY_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_MIME_REGISTRY_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_MIME_REGISTRY_IMPL_H_
 
 #include "base/compiler_specific.h"
 #include "third_party/WebKit/public/platform/WebMimeRegistry.h"
@@ -41,4 +41,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBMIMEREGISTRY_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_MIME_REGISTRY_IMPL_H_
diff --git a/mojo/services/html_viewer/webnotificationmanager_impl.cc b/components/html_viewer/web_notification_manager_impl.cc
similarity index 95%
rename from mojo/services/html_viewer/webnotificationmanager_impl.cc
rename to components/html_viewer/web_notification_manager_impl.cc
index fabca5e..c597ec24 100644
--- a/mojo/services/html_viewer/webnotificationmanager_impl.cc
+++ b/components/html_viewer/web_notification_manager_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 "mojo/services/html_viewer/webnotificationmanager_impl.h"
+#include "components/html_viewer/web_notification_manager_impl.h"
 
 #include "base/logging.h"
 
diff --git a/mojo/services/html_viewer/webnotificationmanager_impl.h b/components/html_viewer/web_notification_manager_impl.h
similarity index 89%
rename from mojo/services/html_viewer/webnotificationmanager_impl.h
rename to components/html_viewer/web_notification_manager_impl.h
index 0cf178a..1110aca 100644
--- a/mojo/services/html_viewer/webnotificationmanager_impl.h
+++ b/components/html_viewer/web_notification_manager_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBNOTIFICATIONMANAGER_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBNOTIFICATIONMANAGER_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_NOTIFICATION_MANAGER_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_NOTIFICATION_MANAGER_IMPL_H_
 
 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificationManager.h"
 
@@ -43,4 +43,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBNOTIFICATIONMANAGER_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_NOTIFICATION_MANAGER_IMPL_H_
diff --git a/mojo/services/html_viewer/webscheduler_impl.cc b/components/html_viewer/web_scheduler_impl.cc
similarity index 97%
rename from mojo/services/html_viewer/webscheduler_impl.cc
rename to components/html_viewer/web_scheduler_impl.cc
index f414cb6..7f1ada5c 100644
--- a/mojo/services/html_viewer/webscheduler_impl.cc
+++ b/components/html_viewer/web_scheduler_impl.cc
@@ -8,7 +8,7 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/tracked_objects.h"
-#include "mojo/services/html_viewer/webscheduler_impl.h"
+#include "components/html_viewer/web_scheduler_impl.h"
 
 namespace html_viewer {
 
diff --git a/mojo/services/html_viewer/webscheduler_impl.h b/components/html_viewer/web_scheduler_impl.h
similarity index 88%
rename from mojo/services/html_viewer/webscheduler_impl.h
rename to components/html_viewer/web_scheduler_impl.h
index 112e7ee1..e0d754f 100644
--- a/mojo/services/html_viewer/webscheduler_impl.h
+++ b/components/html_viewer/web_scheduler_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBSCHEDULER_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBSCHEDULER_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_SCHEDULER_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_SCHEDULER_IMPL_H_
 
 #include "third_party/WebKit/public/platform/WebScheduler.h"
 #include "third_party/WebKit/public/platform/WebThread.h"
@@ -37,4 +37,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBSCHEDULER_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_SCHEDULER_IMPL_H_
diff --git a/mojo/services/html_viewer/websockethandle_impl.cc b/components/html_viewer/web_socket_handle_impl.cc
similarity index 97%
rename from mojo/services/html_viewer/websockethandle_impl.cc
rename to components/html_viewer/web_socket_handle_impl.cc
index 2138546..59d9160bf 100644
--- a/mojo/services/html_viewer/websockethandle_impl.cc
+++ b/components/html_viewer/web_socket_handle_impl.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/services/html_viewer/websockethandle_impl.h"
+#include "components/html_viewer/web_socket_handle_impl.h"
 
 #include <vector>
 
 #include "base/bind.h"
 #include "base/macros.h"
 #include "base/memory/scoped_vector.h"
-#include "mojo/services/html_viewer/blink_basic_type_converters.h"
+#include "components/html_viewer/blink_basic_type_converters.h"
 #include "mojo/services/network/public/cpp/web_socket_read_queue.h"
 #include "mojo/services/network/public/cpp/web_socket_write_queue.h"
 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
diff --git a/mojo/services/html_viewer/websockethandle_impl.h b/components/html_viewer/web_socket_handle_impl.h
similarity index 91%
rename from mojo/services/html_viewer/websockethandle_impl.h
rename to components/html_viewer/web_socket_handle_impl.h
index 4796f4d1c..0456228b 100644
--- a/mojo/services/html_viewer/websockethandle_impl.h
+++ b/components/html_viewer/web_socket_handle_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBSOCKETHANDLE_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBSOCKETHANDLE_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_SOCKET_HANDLE_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_SOCKET_HANDLE_IMPL_H_
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
@@ -60,4 +60,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBSOCKETHANDLE_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_SOCKET_HANDLE_IMPL_H_
diff --git a/mojo/services/html_viewer/webstoragenamespace_impl.cc b/components/html_viewer/web_storage_namespace_impl.cc
similarity index 93%
rename from mojo/services/html_viewer/webstoragenamespace_impl.cc
rename to components/html_viewer/web_storage_namespace_impl.cc
index 47d7918..f61a63f 100644
--- a/mojo/services/html_viewer/webstoragenamespace_impl.cc
+++ b/components/html_viewer/web_storage_namespace_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 "mojo/services/html_viewer/webstoragenamespace_impl.h"
+#include "components/html_viewer/web_storage_namespace_impl.h"
 
 #include <stdio.h>
 
diff --git a/mojo/services/html_viewer/webstoragenamespace_impl.h b/components/html_viewer/web_storage_namespace_impl.h
similarity index 79%
rename from mojo/services/html_viewer/webstoragenamespace_impl.h
rename to components/html_viewer/web_storage_namespace_impl.h
index 32e17c0..1c199aa 100644
--- a/mojo/services/html_viewer/webstoragenamespace_impl.h
+++ b/components/html_viewer/web_storage_namespace_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBSTORAGENAMESPACE_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBSTORAGENAMESPACE_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_STORAGE_NAMESPACE_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_STORAGE_NAMESPACE_IMPL_H_
 
 #include "base/macros.h"
 #include "third_party/WebKit/public/platform/WebStorageNamespace.h"
@@ -27,4 +27,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBSTORAGENAMESPACE_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_STORAGE_NAMESPACE_IMPL_H_
diff --git a/mojo/services/html_viewer/webthemeengine_impl.cc b/components/html_viewer/web_theme_engine_impl.cc
similarity index 98%
rename from mojo/services/html_viewer/webthemeengine_impl.cc
rename to components/html_viewer/web_theme_engine_impl.cc
index c91462cb..69518ee1 100644
--- a/mojo/services/html_viewer/webthemeengine_impl.cc
+++ b/components/html_viewer/web_theme_engine_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 "mojo/services/html_viewer/webthemeengine_impl.h"
+#include "components/html_viewer/web_theme_engine_impl.h"
 
 #include "skia/ext/platform_canvas.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
diff --git a/mojo/services/html_viewer/webthemeengine_impl.h b/components/html_viewer/web_theme_engine_impl.h
similarity index 86%
rename from mojo/services/html_viewer/webthemeengine_impl.h
rename to components/html_viewer/web_theme_engine_impl.h
index 58e56ab7..e146e9d 100644
--- a/mojo/services/html_viewer/webthemeengine_impl.h
+++ b/components/html_viewer/web_theme_engine_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBTHEMEENGINE_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBTHEMEENGINE_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_THEME_ENGINE_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_THEME_ENGINE_IMPL_H_
 
 #include "third_party/WebKit/public/platform/WebThemeEngine.h"
 
@@ -28,4 +28,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBTHEMEENGINE_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_THEME_ENGINE_IMPL_H_
diff --git a/mojo/services/html_viewer/webthread_impl.cc b/components/html_viewer/web_thread_impl.cc
similarity index 98%
rename from mojo/services/html_viewer/webthread_impl.cc
rename to components/html_viewer/web_thread_impl.cc
index a6f6f64..6f3bb53 100644
--- a/mojo/services/html_viewer/webthread_impl.cc
+++ b/components/html_viewer/web_thread_impl.cc
@@ -5,7 +5,7 @@
 // An implementation of WebThread in terms of base::MessageLoop and
 // base::Thread
 
-#include "mojo/services/html_viewer/webthread_impl.h"
+#include "components/html_viewer/web_thread_impl.h"
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
diff --git a/mojo/services/html_viewer/webthread_impl.h b/components/html_viewer/web_thread_impl.h
similarity index 91%
rename from mojo/services/html_viewer/webthread_impl.h
rename to components/html_viewer/web_thread_impl.h
index e7b499d..b9fc8044 100644
--- a/mojo/services/html_viewer/webthread_impl.h
+++ b/components/html_viewer/web_thread_impl.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 MOJO_SERVICES_HTML_VIEWER_WEBTHREAD_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBTHREAD_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_THREAD_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_THREAD_IMPL_H_
 
 #include <map>
 
 #include "base/memory/scoped_ptr.h"
 #include "base/threading/thread.h"
-#include "mojo/services/html_viewer/webscheduler_impl.h"
+#include "components/html_viewer/web_scheduler_impl.h"
 #include "third_party/WebKit/public/platform/WebThread.h"
 
 namespace html_viewer {
@@ -85,4 +85,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBTHREAD_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_THREAD_IMPL_H_
diff --git a/mojo/services/html_viewer/weburlloader_impl.cc b/components/html_viewer/web_url_loader_impl.cc
similarity index 78%
rename from mojo/services/html_viewer/weburlloader_impl.cc
rename to components/html_viewer/web_url_loader_impl.cc
index f57e3f4b..b4874b2f 100644
--- a/mojo/services/html_viewer/weburlloader_impl.cc
+++ b/components/html_viewer/web_url_loader_impl.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/services/html_viewer/weburlloader_impl.h"
+#include "components/html_viewer/web_url_loader_impl.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/thread_task_runner_handle.h"
+#include "components/html_viewer/blink_url_request_type_converters.h"
 #include "mojo/common/common_type_converters.h"
 #include "mojo/common/url_type_converters.h"
-#include "mojo/services/html_viewer/blink_url_request_type_converters.h"
 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
 #include "net/base/net_errors.h"
 #include "third_party/WebKit/public/platform/WebURLError.h"
@@ -18,6 +18,7 @@
 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
 #include "third_party/WebKit/public/platform/WebURLResponse.h"
 
+using blink::WebString;
 using mojo::URLResponsePtr;
 
 namespace html_viewer {
@@ -79,8 +80,12 @@
 WebURLRequestExtraData::~WebURLRequestExtraData() {
 }
 
-WebURLLoaderImpl::WebURLLoaderImpl(mojo::NetworkService* network_service)
-    : client_(NULL), weak_factory_(this) {
+WebURLLoaderImpl::WebURLLoaderImpl(mojo::NetworkService* network_service,
+                                   MockWebBlobRegistryImpl* web_blob_registry)
+    : client_(NULL),
+      web_blob_registry_(web_blob_registry),
+      referrer_policy_(blink::WebReferrerPolicyDefault),
+      weak_factory_(this) {
   network_service->CreateURLLoader(GetProxy(&url_loader_));
 }
 
@@ -102,6 +107,10 @@
 
   mojo::URLRequestPtr url_request = mojo::URLRequest::From(request);
   url_request->auto_follow_redirects = false;
+  referrer_policy_ = request.referrerPolicy();
+  GURL referrer_url(
+      request.httpHeaderField(WebString::fromUTF8("Referer")).latin1());
+  url_request->referrer = referrer_url.spec();
 
   if (request.extraData()) {
     WebURLRequestExtraData* extra_data =
@@ -112,12 +121,24 @@
                    weak_factory_.GetWeakPtr(),
                    request,
                    base::Passed(&extra_data->synthetic_response)));
-  } else {
-    url_loader_->Start(url_request.Pass(),
-                       base::Bind(&WebURLLoaderImpl::OnReceivedResponse,
-                                  weak_factory_.GetWeakPtr(),
-                                  request));
+    return;
   }
+
+  blink::WebString uuid;
+  if (web_blob_registry_->GetUUIDForURL(url_, &uuid)) {
+    blink::WebVector<blink::WebBlobData::Item*> items;
+    if (web_blob_registry_->GetBlobItems(uuid, &items)) {
+      // The blob data exists in our service, and we don't want to create a
+      // data pipe just to do a funny dance where at the end, we stuff data
+      // from memory into data pipes so we can read back the data.
+      OnReceiveWebBlobData(request, items);
+      return;
+    }
+  }
+
+  url_loader_->Start(url_request.Pass(),
+                     base::Bind(&WebURLLoaderImpl::OnReceivedResponse,
+                                weak_factory_.GetWeakPtr(), request));
 }
 
 void WebURLLoaderImpl::cancel() {
@@ -187,6 +208,9 @@
   new_request.setSkipServiceWorker(request.skipServiceWorker());
   new_request.setFetchRequestMode(request.fetchRequestMode());
   new_request.setFetchCredentialsMode(request.fetchCredentialsMode());
+  new_request.setHTTPReferrer(
+      WebString::fromUTF8(url_response->redirect_referrer),
+      referrer_policy_);
 
   std::string old_method = request.httpMethod().utf8();
   new_request.setHTTPMethod(
@@ -208,6 +232,34 @@
                  request));
 }
 
+void WebURLLoaderImpl::OnReceiveWebBlobData(
+    const blink::WebURLRequest& request,
+    const blink::WebVector<blink::WebBlobData::Item*>& items) {
+  blink::WebURLResponse result;
+  result.initialize();
+  result.setURL(url_);
+  result.setHTTPStatusCode(200);
+  result.setExpectedContentLength(-1);  // Not available.
+
+  base::WeakPtr<WebURLLoaderImpl> self(weak_factory_.GetWeakPtr());
+  client_->didReceiveResponse(this, result);
+
+  // We may have been deleted during didReceiveResponse.
+  if (!self)
+    return;
+
+  // Send a receive data for each blob item.
+  for (size_t i = 0; i < items.size(); ++i) {
+    client_->didReceiveData(this, items[i]->data.data(), items[i]->data.size(),
+                            -1);
+  }
+
+  // Send a closing finish.
+  double finish_time = base::Time::Now().ToDoubleT();
+  client_->didFinishLoading(
+      this, finish_time, blink::WebURLLoaderClient::kUnknownEncodedDataLength);
+}
+
 void WebURLLoaderImpl::ReadMore() {
   const void* buf;
   uint32_t buf_size;
diff --git a/mojo/services/html_viewer/weburlloader_impl.h b/components/html_viewer/web_url_loader_impl.h
similarity index 76%
rename from mojo/services/html_viewer/weburlloader_impl.h
rename to components/html_viewer/web_url_loader_impl.h
index 10f4040..4a92a8aa 100644
--- a/mojo/services/html_viewer/weburlloader_impl.h
+++ b/components/html_viewer/web_url_loader_impl.h
@@ -2,13 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_SERVICES_HTML_VIEWER_WEBURLLOADER_IMPL_H_
-#define MOJO_SERVICES_HTML_VIEWER_WEBURLLOADER_IMPL_H_
+#ifndef COMPONENTS_HTML_VIEWER_WEB_URL_LOADER_IMPL_H_
+#define COMPONENTS_HTML_VIEWER_WEB_URL_LOADER_IMPL_H_
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "components/html_viewer/mock_web_blob_registry_impl.h"
 #include "mojo/common/handle_watcher.h"
 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
+#include "third_party/WebKit/public/platform/WebBlobData.h"
+#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 #include "third_party/WebKit/public/platform/WebURLLoader.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
 
@@ -29,7 +32,8 @@
 
 class WebURLLoaderImpl : public blink::WebURLLoader {
  public:
-  explicit WebURLLoaderImpl(mojo::NetworkService* network_service);
+  explicit WebURLLoaderImpl(mojo::NetworkService* network_service,
+                            MockWebBlobRegistryImpl* web_blob_registry);
 
  private:
   virtual ~WebURLLoaderImpl();
@@ -49,12 +53,17 @@
   void OnReceivedError(mojo::URLResponsePtr response);
   void OnReceivedRedirect(const blink::WebURLRequest& request,
                           mojo::URLResponsePtr response);
+  void OnReceiveWebBlobData(
+      const blink::WebURLRequest& request,
+      const blink::WebVector<blink::WebBlobData::Item*>& items);
   void ReadMore();
   void WaitToReadMore();
   void OnResponseBodyStreamReady(MojoResult result);
 
   blink::WebURLLoaderClient* client_;
+  MockWebBlobRegistryImpl* web_blob_registry_;
   GURL url_;
+  blink::WebReferrerPolicy referrer_policy_;
   mojo::URLLoaderPtr url_loader_;
   mojo::ScopedDataPipeConsumerHandle response_body_stream_;
   mojo::common::HandleWatcher handle_watcher_;
@@ -66,4 +75,4 @@
 
 }  // namespace html_viewer
 
-#endif  // MOJO_SERVICES_HTML_VIEWER_WEBURLLOADER_IMPL_H_
+#endif  // COMPONENTS_HTML_VIEWER_WEB_URL_LOADER_IMPL_H_
diff --git a/components/metrics/proto/system_profile.proto b/components/metrics/proto/system_profile.proto
index 85340ad..ca277cb 100644
--- a/components/metrics/proto/system_profile.proto
+++ b/components/metrics/proto/system_profile.proto
@@ -77,7 +77,12 @@
 
   // Information on the user's operating system.
   message OS {
-    // The user's operating system.
+    // The user's operating system. This should be one of:
+    // - Android
+    // - Windows NT
+    // - Linux (includes ChromeOS)
+    // - iPhone OS
+    // - Mac OS X
     optional string name = 1;
 
     // The version of the OS.  The meaning of this field is OS-dependent.
diff --git a/components/nacl/browser/nacl_browser.cc b/components/nacl/browser/nacl_browser.cc
index f53b3e0..733e9d9 100644
--- a/components/nacl/browser/nacl_browser.cc
+++ b/components/nacl/browser/nacl_browser.cc
@@ -168,7 +168,7 @@
 }
 
 void NaClBrowser::EarlyStartup() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   InitIrtFilePath();
   InitValidationCacheFilePath();
 }
@@ -225,21 +225,21 @@
 }
 
 const base::File& NaClBrowser::IrtFile() const {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   CHECK_EQ(irt_state_, NaClResourceReady);
   CHECK(irt_file_.IsValid());
   return irt_file_;
 }
 
 void NaClBrowser::EnsureAllResourcesAvailable() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   EnsureIrtAvailable();
   EnsureValidationCacheAvailable();
 }
 
 // Load the IRT async.
 void NaClBrowser::EnsureIrtAvailable() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (IsOk() && irt_state_ == NaClResourceUninitialized) {
     irt_state_ = NaClResourceRequested;
     // TODO(ncbray) use blocking pool.
@@ -260,7 +260,7 @@
 
 void NaClBrowser::OnIrtOpened(scoped_ptr<base::FileProxy> file_proxy,
                               base::File::Error error_code) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   DCHECK_EQ(irt_state_, NaClResourceRequested);
   if (file_proxy->IsValid()) {
     irt_file_ = file_proxy->TakeFile();
@@ -322,7 +322,7 @@
 }
 
 void NaClBrowser::EnsureValidationCacheAvailable() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (IsOk() && validation_cache_state_ == NaClResourceUninitialized) {
     if (ValidationCacheIsEnabled()) {
       validation_cache_state_ = NaClResourceRequested;
@@ -347,7 +347,7 @@
 }
 
 void NaClBrowser::OnValidationCacheLoaded(const std::string *data) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   // Did the cache get cleared before the load completed?  If so, ignore the
   // incoming data.
   if (validation_cache_state_ == NaClResourceReady)
@@ -373,7 +373,7 @@
 }
 
 void NaClBrowser::CheckWaiting() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (!IsOk() || IsReady()) {
     // Queue the waiting tasks into the message loop.  This helps avoid
     // re-entrancy problems that could occur if the closure was invoked
@@ -404,7 +404,7 @@
 
 void NaClBrowser::PutFilePath(const base::FilePath& path, uint64* file_token_lo,
                               uint64* file_token_hi) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   while (true) {
     uint64 file_token[2] = {base::RandUint64(), base::RandUint64()};
     // A zero file_token indicates there is no file_token, if we get zero, ask
@@ -425,7 +425,7 @@
 
 bool NaClBrowser::GetFilePath(uint64 file_token_lo, uint64 file_token_hi,
                               base::FilePath* path) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   uint64 file_token[2] = {file_token_lo, file_token_hi};
   std::string key(reinterpret_cast<char*>(file_token), sizeof(file_token));
   PathCacheType::iterator iter = path_cache_.Peek(key);
@@ -441,7 +441,7 @@
 
 bool NaClBrowser::QueryKnownToValidate(const std::string& signature,
                                        bool off_the_record) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (off_the_record) {
     // If we're off the record, don't reorder the main cache.
     return validation_cache_.QueryKnownToValidate(signature, false) ||
@@ -457,7 +457,7 @@
 
 void NaClBrowser::SetKnownToValidate(const std::string& signature,
                                      bool off_the_record) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (off_the_record) {
     off_the_record_validation_cache_.SetKnownToValidate(signature);
   } else {
@@ -470,7 +470,7 @@
 }
 
 void NaClBrowser::ClearValidationCache(const base::Closure& callback) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   // Note: this method may be called before EnsureValidationCacheAvailable has
   // been invoked.  In other words, this method may be called before any NaCl
   // processes have been created.  This method must succeed and invoke the
@@ -522,7 +522,7 @@
 }
 
 void NaClBrowser::PersistValidationCache() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   // validation_cache_is_modified_ may be false if the cache was cleared while
   // this delayed task was pending.
   // validation_cache_file_path_ may be empty if something went wrong during
@@ -549,7 +549,7 @@
 }
 
 void NaClBrowser::OnProcessCrashed() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (crash_times_.size() == kMaxCrashesPerInterval) {
     crash_times_.pop_front();
   }
@@ -558,7 +558,7 @@
 }
 
 bool NaClBrowser::IsThrottled() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (crash_times_.size() != kMaxCrashesPerInterval) {
     return false;
   }
diff --git a/components/nacl/common/DEPS b/components/nacl/common/DEPS
index e13224d..3b9fcea 100644
--- a/components/nacl/common/DEPS
+++ b/components/nacl/common/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+native_client/src/public",
+  "+native_client/src/trusted/service_runtime/nacl_error_code.h",
 ]
diff --git a/components/nacl/common/nacl_renderer_messages.h b/components/nacl/common/nacl_renderer_messages.h
index e07a082..265af86 100644
--- a/components/nacl/common/nacl_renderer_messages.h
+++ b/components/nacl/common/nacl_renderer_messages.h
@@ -6,6 +6,7 @@
 
 // Multiply-included message file, no traditional include guard.
 #include "ipc/ipc_message_macros.h"
+#include "native_client/src/trusted/service_runtime/nacl_error_code.h"
 
 #define IPC_MESSAGE_START NaClHostMsgStart
 
@@ -13,3 +14,10 @@
 // NaCl to the renderer before the NaCl process exits very soon after.
 IPC_SYNC_MESSAGE_CONTROL1_0(NaClRendererMsg_ReportExitStatus,
                             int /* exit_status */)
+
+IPC_ENUM_TRAITS_MAX_VALUE(NaClErrorCode, NACL_ERROR_CODE_MAX)
+
+// This message must be synchronous to ensure that the load status is sent from
+// NaCl to the renderer before the NaCl process exits very soon after.
+IPC_SYNC_MESSAGE_CONTROL1_0(NaClRendererMsg_ReportLoadStatus,
+                            NaClErrorCode /* load_status */)
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc
index 4a58a1c..4cf4a3e 100644
--- a/components/nacl/loader/nacl_listener.cc
+++ b/components/nacl/loader/nacl_listener.cc
@@ -69,6 +69,12 @@
          copy_bytes);
 }
 
+void LoadStatusCallback(int load_status) {
+  g_listener->trusted_listener()->Send(
+      new NaClRendererMsg_ReportLoadStatus(
+          static_cast<NaClErrorCode>(load_status)));
+}
+
 #if defined(OS_MACOSX)
 
 // On Mac OS X, shm_open() works in the sandbox but does not give us
@@ -420,6 +426,7 @@
   args->debug_stub_server_port_selected_handler_func =
       DebugStubPortSelectedHandler;
 #endif
+  args->load_status_handler_func = LoadStatusCallback;
 #if defined(OS_LINUX)
   args->prereserved_sandbox_size = prereserved_sandbox_size_;
 #endif
diff --git a/components/nacl/loader/nacl_listener.h b/components/nacl/loader/nacl_listener.h
index 9e8d67b6..eccbc19 100644
--- a/components/nacl/loader/nacl_listener.h
+++ b/components/nacl/loader/nacl_listener.h
@@ -48,6 +48,10 @@
 
   void* crash_info_shmem_memory() const { return crash_info_shmem_->memory(); }
 
+  NaClTrustedListener* trusted_listener() const {
+    return trusted_listener_.get();
+  }
+
   typedef base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)>
       ResolveFileTokenCallback;
   void ResolveFileToken(uint64_t token_lo,
diff --git a/components/nacl/renderer/DEPS b/components/nacl/renderer/DEPS
index 889a36b7..483376be 100644
--- a/components/nacl/renderer/DEPS
+++ b/components/nacl/renderer/DEPS
@@ -1,6 +1,8 @@
 include_rules = [
   "+content/public/renderer",
   "+native_client/src/public/imc_types.h",  # for NaClHandle
+  # for NaClErrorCode
+  "+native_client/src/trusted/service_runtime/nacl_error_code.h",
   "+net",
   "+ppapi/c",
   "+ppapi/proxy",
diff --git a/components/nacl/renderer/plugin/service_runtime.cc b/components/nacl/renderer/plugin/service_runtime.cc
index 485792a..d697c69 100644
--- a/components/nacl/renderer/plugin/service_runtime.cc
+++ b/components/nacl/renderer/plugin/service_runtime.cc
@@ -88,6 +88,10 @@
     // the plugin.
     load_status = LOAD_OK;
   } else {
+    // We invoke start_module to unblock NaClWaitForStartModuleCommand in
+    // sel_main_chrome.c on the NaCl side, but the load_status is obtained by
+    // a different hook. Remove this once NaClWaitForStartModuleCommand is no
+    // longer needed.
     NaClSrpcResultCodes rpc_result =
         NaClSrpcInvokeBySignature(&command_channel_,
                                   "start_module::i",
@@ -103,23 +107,7 @@
   }
 
   NaClLog(4, "ServiceRuntime::StartModule (load_status=%d)\n", load_status);
-  if (main_service_runtime_) {
-    if (load_status < 0 || load_status > NACL_ERROR_CODE_MAX)
-      load_status = LOAD_STATUS_UNKNOWN;
-    GetNaClInterface()->ReportSelLdrStatus(pp_instance_,
-                                           load_status,
-                                           NACL_ERROR_CODE_MAX);
-  }
-
-  if (LOAD_OK != load_status) {
-    ErrorInfo error_info;
-    error_info.SetReport(
-        PP_NACL_ERROR_SEL_LDR_START_STATUS,
-        NaClErrorString(static_cast<NaClErrorCode>(load_status)));
-    ReportLoadError(error_info);
-    return false;
-  }
-  return true;
+  return LOAD_OK == load_status;
 }
 
 void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params,
@@ -208,8 +196,6 @@
   bool ok = StartNexeInternal();
   if (ok) {
     NaClLog(4, "ServiceRuntime::StartNexe (success)\n");
-  } else {
-    ReapLogs();
   }
   // This only matters if a background thread is waiting, but we signal in all
   // cases to simplify the code.
@@ -222,24 +208,6 @@
   return StartModule();
 }
 
-void ServiceRuntime::ReapLogs() {
-  // TODO(teravest): We should allow the NaCl process to crash itself when a
-  // module fails to start, and remove the call to RemoteLog() here. The
-  // reverse channel is no longer needed for crash reporting.
-  //
-  // The reasoning behind the current code behavior follows:
-  // On a load failure the NaCl process does not crash itself to
-  // avoid a race where the no-more-senders error on the reverse
-  // channel service thread might cause the crash-detection logic to
-  // kick in before the start_module RPC reply has been received. So
-  // we induce a NaCl process crash here.
-  RemoteLog(LOG_FATAL, "reap logs\n");
-
-  // TODO(teravest): Release subprocess_ here since it's no longer needed. It
-  // was previously kept around to collect crash log output from the bootstrap
-  // channel.
-}
-
 void ServiceRuntime::ReportLoadError(const ErrorInfo& error_info) {
   if (main_service_runtime_) {
     plugin_->ReportLoadError(error_info);
@@ -264,15 +232,6 @@
   }
 }
 
-bool ServiceRuntime::RemoteLog(int severity, const std::string& msg) {
-  NaClSrpcResultCodes rpc_result =
-      NaClSrpcInvokeBySignature(&command_channel_,
-                                "log:is:",
-                                severity,
-                                strdup(msg.c_str()));
-  return (NACL_SRPC_RESULT_OK == rpc_result);
-}
-
 void ServiceRuntime::Shutdown() {
   // Abandon callbacks, tell service threads to quit if they were
   // blocked waiting for main thread operations to finish.  Note that
diff --git a/components/nacl/renderer/plugin/service_runtime.h b/components/nacl/renderer/plugin/service_runtime.h
index 5fe941a1..f1991b62 100644
--- a/components/nacl/renderer/plugin/service_runtime.h
+++ b/components/nacl/renderer/plugin/service_runtime.h
@@ -85,7 +85,6 @@
   // Starts the application channel to the nexe.
   SrpcClient* SetupAppChannel();
 
-  bool RemoteLog(int severity, const std::string& msg);
   Plugin* plugin() const { return plugin_; }
   void Shutdown();
 
@@ -97,7 +96,6 @@
 
   bool SetupCommandChannel();
   bool StartModule();
-  void ReapLogs();
 
   void ReportLoadError(const ErrorInfo& error_info);
 
diff --git a/components/nacl/renderer/ppb_nacl_private.h b/components/nacl/renderer/ppb_nacl_private.h
index 7953461b..2683652 100644
--- a/components/nacl/renderer/ppb_nacl_private.h
+++ b/components/nacl/renderer/ppb_nacl_private.h
@@ -326,13 +326,6 @@
                        const char* url,
                        struct PP_NaClFileInfo* file_info,
                        struct PP_CompletionCallback callback);
-  /* Reports the status of sel_ldr for UMA reporting.
-   * |max_status| has to be provided because the implementation of this
-   * interface can't access the NaClErrorCode enum.
-   */
-  void (*ReportSelLdrStatus)(PP_Instance instance,
-                             int32_t load_status,
-                             int32_t max_status);
   /* Logs time taken by an operation to UMA histograms.
    * This function is safe to call on any thread.
    */
@@ -365,4 +358,3 @@
  */
 
 #endif  /* COMPONENTS_NACL_RENDERER_PPB_NACL_PRIVATE_H_ */
-
diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc
index c879e48..2f3cd58 100644
--- a/components/nacl/renderer/ppb_nacl_private_impl.cc
+++ b/components/nacl/renderer/ppb_nacl_private_impl.cc
@@ -14,6 +14,7 @@
 #include "base/containers/scoped_ptr_hash_map.h"
 #include "base/cpu.h"
 #include "base/files/file.h"
+#include "base/json/json_reader.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/rand_util.h"
@@ -61,8 +62,6 @@
 #include "third_party/WebKit/public/web/WebPluginContainer.h"
 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/web/WebURLLoaderOptions.h"
-#include "third_party/jsoncpp/source/include/json/reader.h"
-#include "third_party/jsoncpp/source/include/json/value.h"
 
 namespace nacl {
 namespace {
@@ -501,13 +500,13 @@
 
   // Create the trusted plugin channel.
   if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) {
-    bool report_exit_status = PP_ToBool(main_service_runtime);
+    bool is_helper_nexe = !PP_ToBool(main_service_runtime);
     scoped_ptr<TrustedPluginChannel> trusted_plugin_channel(
         new TrustedPluginChannel(
             load_manager,
             launch_result.trusted_ipc_channel_handle,
             content::RenderThread::Get()->GetShutdownEvent(),
-            report_exit_status));
+            is_helper_nexe));
     load_manager->set_trusted_plugin_channel(trusted_plugin_channel.Pass());
   } else {
     PostPPCompletionCallback(callback, PP_ERROR_FAILED);
@@ -1179,43 +1178,41 @@
   buffer.get()[rc] = 0;
 
   // Expect the JSON file to contain a top-level object (dictionary).
-  Json::Reader json_reader;
-  Json::Value json_data;
-  if (!json_reader.parse(buffer.get(), json_data)) {
+  base::JSONReader json_reader;
+  int json_read_error_code;
+  std::string json_read_error_msg;
+  base::Value* json_data = json_reader.ReadAndReturnError(
+      buffer.get(),
+      base::JSON_PARSE_RFC,
+      &json_read_error_code,
+      &json_read_error_msg);
+  if (json_data == NULL) {
     load_manager->ReportLoadError(
         PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
         std::string("Parsing resource info failed: JSON parse error: ") +
-            json_reader.getFormattedErrorMessages());
+            json_read_error_msg);
     return PP_FALSE;
   }
 
-  if (!json_data.isObject()) {
+  base::DictionaryValue* json_dict;
+  if (!json_data->GetAsDictionary(&json_dict)) {
     load_manager->ReportLoadError(
         PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
         "Parsing resource info failed: Malformed JSON dictionary");
     return PP_FALSE;
   }
 
-  if (json_data.isMember("pnacl-llc-name")) {
-    Json::Value json_name = json_data["pnacl-llc-name"];
-    if (json_name.isString()) {
-      *llc_tool_name = ppapi::StringVar::StringToPPVar(json_name.asString());
-    }
-  }
+  std::string pnacl_llc_name;
+  if (json_dict->GetString("pnacl-llc-name", &pnacl_llc_name))
+    *llc_tool_name = ppapi::StringVar::StringToPPVar(pnacl_llc_name);
 
-  if (json_data.isMember("pnacl-ld-name")) {
-    Json::Value json_name = json_data["pnacl-ld-name"];
-    if (json_name.isString()) {
-      *ld_tool_name = ppapi::StringVar::StringToPPVar(json_name.asString());
-    }
-  }
+  std::string pnacl_ld_name;
+  if (json_dict->GetString("pnacl-ld-name", &pnacl_ld_name))
+    *ld_tool_name = ppapi::StringVar::StringToPPVar(pnacl_ld_name);
 
-  if (json_data.isMember("pnacl-sz-name")) {
-    Json::Value json_name = json_data["pnacl-sz-name"];
-    if (json_name.isString()) {
-      *subzero_tool_name =
-          ppapi::StringVar::StringToPPVar(json_name.asString());
-    }
+  std::string pnacl_sz_name;
+  if (json_dict->GetString("pnacl-sz-name", &pnacl_sz_name)) {
+    *subzero_tool_name = ppapi::StringVar::StringToPPVar(pnacl_sz_name);
   } else {
     // TODO(jvoung): remove fallback after one chrome release
     // or when we bump the kMinPnaclVersion.
@@ -1487,22 +1484,6 @@
   file_downloader->Load(url_request);
 }
 
-void ReportSelLdrStatus(PP_Instance instance,
-                        int32_t load_status,
-                        int32_t max_status) {
-  HistogramEnumerate("NaCl.LoadStatus.SelLdr", load_status, max_status);
-  NexeLoadManager* load_manager = GetNexeLoadManager(instance);
-  DCHECK(load_manager);
-  if (!load_manager)
-    return;
-
-  // Gather data to see if being installed changes load outcomes.
-  const char* name = load_manager->is_installed() ?
-      "NaCl.LoadStatus.SelLdr.InstalledApp" :
-      "NaCl.LoadStatus.SelLdr.NotInstalledApp";
-  HistogramEnumerate(name, load_status, max_status);
-}
-
 void LogTranslateTime(const char* histogram_name,
                       int64_t time_in_us) {
   ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
@@ -1720,7 +1701,6 @@
   &GetPNaClResourceInfo,
   &GetCpuFeatureAttrs,
   &DownloadNexe,
-  &ReportSelLdrStatus,
   &LogTranslateTime,
   &LogBytesCompiledVsDowloaded,
   &SetPNaClStartTime,
diff --git a/components/nacl/renderer/trusted_plugin_channel.cc b/components/nacl/renderer/trusted_plugin_channel.cc
index 729644cb..1ba39fe 100644
--- a/components/nacl/renderer/trusted_plugin_channel.cc
+++ b/components/nacl/renderer/trusted_plugin_channel.cc
@@ -6,6 +6,7 @@
 
 #include "base/callback_helpers.h"
 #include "components/nacl/common/nacl_renderer_messages.h"
+#include "components/nacl/renderer/histogram.h"
 #include "components/nacl/renderer/nexe_load_manager.h"
 #include "content/public/renderer/render_thread.h"
 #include "ipc/ipc_sync_channel.h"
@@ -18,9 +19,9 @@
     NexeLoadManager* nexe_load_manager,
     const IPC::ChannelHandle& handle,
     base::WaitableEvent* shutdown_event,
-    bool report_exit_status)
+    bool is_helper_nexe)
     : nexe_load_manager_(nexe_load_manager),
-      report_exit_status_(report_exit_status) {
+      is_helper_nexe_(is_helper_nexe) {
   channel_ = IPC::SyncChannel::Create(
       handle,
       IPC::Channel::MODE_CLIENT,
@@ -41,19 +42,41 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(TrustedPluginChannel, msg)
     IPC_MESSAGE_HANDLER(NaClRendererMsg_ReportExitStatus, OnReportExitStatus);
+    IPC_MESSAGE_HANDLER(NaClRendererMsg_ReportLoadStatus, OnReportLoadStatus);
     IPC_MESSAGE_UNHANDLED(handled = false);
   IPC_END_MESSAGE_MAP()
   return handled;
 }
 
 void TrustedPluginChannel::OnChannelError() {
-  if (report_exit_status_)
+  if (!is_helper_nexe_)
     nexe_load_manager_->NexeDidCrash();
 }
 
 void TrustedPluginChannel::OnReportExitStatus(int exit_status) {
-  if (report_exit_status_)
+  if (!is_helper_nexe_)
     nexe_load_manager_->set_exit_status(exit_status);
 }
 
+void TrustedPluginChannel::OnReportLoadStatus(NaClErrorCode load_status) {
+  if (load_status < 0 || load_status > NACL_ERROR_CODE_MAX) {
+    load_status = LOAD_STATUS_UNKNOWN;
+  }
+  // For now, we only report UMA for non-helper nexes
+  // (don't report for the PNaCl translators nexes).
+  if (!is_helper_nexe_) {
+    HistogramEnumerate("NaCl.LoadStatus.SelLdr", load_status,
+                       NACL_ERROR_CODE_MAX);
+    // Gather data to see if being installed changes load outcomes.
+    const char* name = nexe_load_manager_->is_installed()
+                           ? "NaCl.LoadStatus.SelLdr.InstalledApp"
+                           : "NaCl.LoadStatus.SelLdr.NotInstalledApp";
+    HistogramEnumerate(name, load_status, NACL_ERROR_CODE_MAX);
+  }
+  if (load_status != LOAD_OK) {
+    nexe_load_manager_->ReportLoadError(PP_NACL_ERROR_SEL_LDR_START_STATUS,
+                                        NaClErrorString(load_status));
+  }
+}
+
 }  // namespace nacl
diff --git a/components/nacl/renderer/trusted_plugin_channel.h b/components/nacl/renderer/trusted_plugin_channel.h
index efeb5e8..d657d53 100644
--- a/components/nacl/renderer/trusted_plugin_channel.h
+++ b/components/nacl/renderer/trusted_plugin_channel.h
@@ -8,6 +8,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "ipc/ipc_listener.h"
+#include "native_client/src/trusted/service_runtime/nacl_error_code.h"
 #include "ppapi/c/pp_instance.h"
 
 namespace base {
@@ -28,7 +29,7 @@
   TrustedPluginChannel(NexeLoadManager* nexe_load_manager,
                        const IPC::ChannelHandle& handle,
                        base::WaitableEvent* shutdown_event,
-                       bool report_exit_status);
+                       bool is_helper_nexe);
   ~TrustedPluginChannel() override;
 
   bool Send(IPC::Message* message);
@@ -38,13 +39,14 @@
   void OnChannelError() override;
 
   void OnReportExitStatus(int exit_status);
+  void OnReportLoadStatus(NaClErrorCode load_status);
 
  private:
   // Non-owning pointer. This is safe because the TrustedPluginChannel is owned
   // by the NexeLoadManager pointed to here.
   NexeLoadManager* nexe_load_manager_;
   scoped_ptr<IPC::SyncChannel> channel_;
-  bool report_exit_status_;
+  bool is_helper_nexe_;
 
   DISALLOW_COPY_AND_ASSIGN(TrustedPluginChannel);
 };
diff --git a/components/nacl_nonsfi.gyp b/components/nacl_nonsfi.gyp
index 867bce0..3df9c453 100644
--- a/components/nacl_nonsfi.gyp
+++ b/components/nacl_nonsfi.gyp
@@ -140,7 +140,6 @@
             '../native_client/src/nonsfi/irt/irt.gyp:nacl_sys_private',
             '../native_client/src/nonsfi/loader/loader.gyp:elf_loader',
             '../native_client/src/untrusted/nacl/nacl.gyp:nacl_lib_newlib',
-            '../native_client/tools.gyp:prep_toolchain',
             '../ppapi/ppapi_proxy_nacl.gyp:ppapi_proxy_nacl',
             '../sandbox/sandbox_nacl_nonsfi.gyp:sandbox_nacl_nonsfi',
           ],
diff --git a/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc b/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc
index 3640e8f..8855f42 100644
--- a/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc
+++ b/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc
@@ -119,7 +119,7 @@
                      url,
                      net::DEFAULT_PRIORITY,
                      NULL /* delegate */)) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     if (render_process_id != MSG_ROUTING_NONE &&
         render_frame_id != MSG_ROUTING_NONE) {
       content::ResourceRequestInfo::AllocateForTesting(
@@ -150,13 +150,13 @@
   }
 
   void ThrottleWillStartRequest(bool* defer) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     throttle_->WillStartRequest(defer);
   }
 
   void ThrottleWillRedirectRequest(const net::RedirectInfo& redirect_info,
                                    bool* defer) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     throttle_->WillRedirectRequest(redirect_info, defer);
   }
 
@@ -211,7 +211,7 @@
       int render_process_id,
       int render_frame_id,
       bool* defer) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     TestIOThreadState* io_thread_state =
         new TestIOThreadState(url, render_process_id, render_frame_id,
                               request_method, redirect_mode,
diff --git a/components/omnibox/autocomplete_match.h b/components/omnibox/autocomplete_match.h
index 93c5097..8fd50ac 100644
--- a/components/omnibox/autocomplete_match.h
+++ b/components/omnibox/autocomplete_match.h
@@ -340,6 +340,11 @@
   // Set with a keyword provider match if this match can show a keyword hint.
   // For example, if this is a SearchProvider match for "www.amazon.com",
   // |associated_keyword| could be a KeywordProvider match for "amazon.com".
+  //
+  // When this is set, the popup will show a ">" symbol at the right edge of the
+  // line for this match, and tab/shift-tab will toggle in and out of keyword
+  // mode without disturbing the rest of the popup.  See also
+  // OmniboxPopupModel::SetSelectedLineState().
   scoped_ptr<AutocompleteMatch> associated_keyword;
 
   // The keyword of the TemplateURL the match originated from.  This is nonempty
diff --git a/components/pairing/bluetooth_controller_pairing_controller.cc b/components/pairing/bluetooth_controller_pairing_controller.cc
index 1d8e026..476b205 100644
--- a/components/pairing/bluetooth_controller_pairing_controller.cc
+++ b/components/pairing/bluetooth_controller_pairing_controller.cc
@@ -417,6 +417,11 @@
   ChangeStage(STAGE_HOST_ENROLLMENT_ERROR);
 }
 
+void BluetoothControllerPairingController::OnAddNetworkMessage(
+    const pairing_api::AddNetwork& message) {
+  NOTREACHED();
+}
+
 void BluetoothControllerPairingController::DeviceAdded(
     device::BluetoothAdapter* adapter,
     device::BluetoothDevice* device) {
diff --git a/components/pairing/bluetooth_controller_pairing_controller.h b/components/pairing/bluetooth_controller_pairing_controller.h
index c4a3258d..ab67aed 100644
--- a/components/pairing/bluetooth_controller_pairing_controller.h
+++ b/components/pairing/bluetooth_controller_pairing_controller.h
@@ -83,6 +83,7 @@
   void OnCompleteSetupMessage(
       const pairing_api::CompleteSetup& message) override;
   void OnErrorMessage(const pairing_api::Error& message) override;
+  void OnAddNetworkMessage(const pairing_api::AddNetwork& message) override;
 
   // BluetoothAdapter::Observer:
   void DeviceAdded(device::BluetoothAdapter* adapter,
diff --git a/components/pairing/bluetooth_host_pairing_controller.cc b/components/pairing/bluetooth_host_pairing_controller.cc
index 5ffd2f5..580d92f0 100644
--- a/components/pairing/bluetooth_host_pairing_controller.cc
+++ b/components/pairing/bluetooth_host_pairing_controller.cc
@@ -307,11 +307,12 @@
 void BluetoothHostPairingController::OnConfigureHostMessage(
     const pairing_api::ConfigureHost& message) {
   FOR_EACH_OBSERVER(Observer, observers_,
-                    ConfigureHost(message.parameters().accepted_eula(),
-                                  message.parameters().lang(),
-                                  message.parameters().timezone(),
-                                  message.parameters().send_reports(),
-                                  message.parameters().keyboard_layout()));
+                    ConfigureHostRequested(
+                        message.parameters().accepted_eula(),
+                        message.parameters().lang(),
+                        message.parameters().timezone(),
+                        message.parameters().send_reports(),
+                        message.parameters().keyboard_layout()));
 }
 
 void BluetoothHostPairingController::OnPairDevicesMessage(
@@ -319,7 +320,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   ChangeStage(STAGE_ENROLLING);
   FOR_EACH_OBSERVER(Observer, observers_,
-                    EnrollHost(message.parameters().admin_access_token()));
+                    EnrollHostRequested(
+                        message.parameters().admin_access_token()));
 }
 
 void BluetoothHostPairingController::OnCompleteSetupMessage(
@@ -339,6 +341,13 @@
   NOTREACHED();
 }
 
+void BluetoothHostPairingController::OnAddNetworkMessage(
+    const pairing_api::AddNetwork& message) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  FOR_EACH_OBSERVER(Observer, observers_,
+                    AddNetworkRequested(message.parameters().onc_spec()));
+}
+
 void BluetoothHostPairingController::AdapterPresentChanged(
     device::BluetoothAdapter* adapter,
     bool present) {
diff --git a/components/pairing/bluetooth_host_pairing_controller.h b/components/pairing/bluetooth_host_pairing_controller.h
index b99af24d..20ba5066 100644
--- a/components/pairing/bluetooth_host_pairing_controller.h
+++ b/components/pairing/bluetooth_host_pairing_controller.h
@@ -80,6 +80,7 @@
   void OnCompleteSetupMessage(
       const pairing_api::CompleteSetup& message) override;
   void OnErrorMessage(const pairing_api::Error& message) override;
+  void OnAddNetworkMessage(const pairing_api::AddNetwork& message) override;
 
   // BluetoothAdapter::Observer:
   void AdapterPresentChanged(device::BluetoothAdapter* adapter,
diff --git a/components/pairing/fake_host_pairing_controller.cc b/components/pairing/fake_host_pairing_controller.cc
index e6d1e76..25250d02 100644
--- a/components/pairing/fake_host_pairing_controller.cc
+++ b/components/pairing/fake_host_pairing_controller.cc
@@ -169,15 +169,4 @@
   }
 }
 
-void FakeHostPairingController::ConfigureHost(
-    bool accepted_eula,
-    const std::string& lang,
-    const std::string& timezone,
-    bool send_reports,
-    const std::string& keyboard_layout) {
-}
-
-void FakeHostPairingController::EnrollHost(const std::string& auth_token) {
-}
-
 }  // namespace pairing_chromeos
diff --git a/components/pairing/fake_host_pairing_controller.h b/components/pairing/fake_host_pairing_controller.h
index 8ef2f4b..17d68840 100644
--- a/components/pairing/fake_host_pairing_controller.h
+++ b/components/pairing/fake_host_pairing_controller.h
@@ -50,12 +50,6 @@
 
   // HostPairingController::Observer:
   void PairingStageChanged(Stage new_stage) override;
-  void ConfigureHost(bool accepted_eula,
-                     const std::string& lang,
-                     const std::string& timezone,
-                     bool send_reports,
-                     const std::string& keyboard_layout) override;
-  void EnrollHost(const std::string& auth_token) override;
 
   ObserverList<Observer> observers_;
   Stage current_stage_;
diff --git a/components/pairing/host_pairing_controller.h b/components/pairing/host_pairing_controller.h
index 7d79c4f..731707a 100644
--- a/components/pairing/host_pairing_controller.h
+++ b/components/pairing/host_pairing_controller.h
@@ -49,14 +49,17 @@
     virtual void PairingStageChanged(Stage new_stage) = 0;
 
     // Called when the controller has sent a configuration to apply.
-    virtual void ConfigureHost(bool accepted_eula,
-                               const std::string& lang,
-                               const std::string& timezone,
-                               bool send_reports,
-                               const std::string& keyboard_layout) = 0;
+    virtual void ConfigureHostRequested(bool accepted_eula,
+                                        const std::string& lang,
+                                        const std::string& timezone,
+                                        bool send_reports,
+                                        const std::string& keyboard_layout) {}
+
+    // Called when the controller has sent a network to add.
+    virtual void AddNetworkRequested(const std::string& onc_spec) {}
 
     // Called when the controller has provided an |auth_token| for enrollment.
-    virtual void EnrollHost(const std::string& auth_token) = 0;
+    virtual void EnrollHostRequested(const std::string& auth_token) {}
 
    private:
     DISALLOW_COPY_AND_ASSIGN(Observer);
diff --git a/components/pairing/pairing_api.proto b/components/pairing/pairing_api.proto
index 0d8e6680..856feae6 100644
--- a/components/pairing/pairing_api.proto
+++ b/components/pairing/pairing_api.proto
@@ -86,3 +86,12 @@
   optional int32 api_version = 1;
   optional ErrorParameters parameters = 2;
 }
+
+message AddNetworkParameters {
+  optional string onc_spec = 1;
+}
+
+message AddNetwork {
+  optional int32 api_version = 1;
+  optional AddNetworkParameters parameters = 2;
+}
diff --git a/components/pairing/proto_decoder.cc b/components/pairing/proto_decoder.cc
index 96b3c24f..f8e42a4b 100644
--- a/components/pairing/proto_decoder.cc
+++ b/components/pairing/proto_decoder.cc
@@ -15,6 +15,7 @@
   MESSAGE_PAIR_DEVICES,
   MESSAGE_COMPLETE_SETUP,
   MESSAGE_ERROR,
+  MESSAGE_ADD_NETWORK,
   NUM_MESSAGES,
 };
 }
@@ -105,9 +106,15 @@
         observer_->OnErrorMessage(message);
       }
       break;
+    case MESSAGE_ADD_NETWORK: {
+        pairing_api::AddNetwork message;
+        message.ParseFromArray(&buffer[0], buffer.size());
+        observer_->OnAddNetworkMessage(message);
+      }
+      break;
 
     default:
-      NOTREACHED();
+      LOG(WARNING) << "Skipping unknown message type: " << next_message_type_;
       break;
   }
 
diff --git a/components/pairing/proto_decoder.h b/components/pairing/proto_decoder.h
index e36eb7f..826c4bb0 100644
--- a/components/pairing/proto_decoder.h
+++ b/components/pairing/proto_decoder.h
@@ -18,6 +18,7 @@
 }
 
 namespace pairing_api {
+class AddNetwork;
 class CompleteSetup;
 class ConfigureHost;
 class Error;
@@ -47,6 +48,8 @@
         const pairing_api::CompleteSetup& message) = 0;
     virtual void OnErrorMessage(
         const pairing_api::Error& message) = 0;
+    virtual void OnAddNetworkMessage(
+        const pairing_api::AddNetwork& message) = 0;
 
    protected:
     Observer() {}
diff --git a/components/pairing/shark_connection_listener.cc b/components/pairing/shark_connection_listener.cc
index ce63aa0..a6bc655f 100644
--- a/components/pairing/shark_connection_listener.cc
+++ b/components/pairing/shark_connection_listener.cc
@@ -30,17 +30,4 @@
   }
 }
 
-void SharkConnectionListener::ConfigureHost(
-    bool accepted_eula,
-    const std::string& lang,
-    const std::string& timezone,
-    bool send_reports,
-    const std::string& keyboard_layout) {
-  NOTREACHED();
-}
-
-void SharkConnectionListener::EnrollHost(const std::string& auth_token) {
-  NOTREACHED();
-}
-
 }  // namespace pairing_chromeos
diff --git a/components/pairing/shark_connection_listener.h b/components/pairing/shark_connection_listener.h
index 98a7829..c0b3836b 100644
--- a/components/pairing/shark_connection_listener.h
+++ b/components/pairing/shark_connection_listener.h
@@ -30,12 +30,6 @@
 
   // HostPairingController::Observer overrides:
   void PairingStageChanged(Stage new_stage) override;
-  void ConfigureHost(bool accepted_eula,
-                     const std::string& lang,
-                     const std::string& timezone,
-                     bool send_reports,
-                     const std::string& keyboard_layout) override;
-  void EnrollHost(const std::string& auth_token) override;
 
   OnConnectedCallback callback_;
   scoped_ptr<HostPairingController> controller_;
diff --git a/components/password_manager/core/browser/affiliated_match_helper.cc b/components/password_manager/core/browser/affiliated_match_helper.cc
index b89d44e..6acfb59f 100644
--- a/components/password_manager/core/browser/affiliated_match_helper.cc
+++ b/components/password_manager/core/browser/affiliated_match_helper.cc
@@ -6,6 +6,8 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/command_line.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "components/autofill/core/common/password_form.h"
@@ -15,6 +17,34 @@
 
 namespace {
 
+// Dummy Android facet URIs for which affiliations will be fetched as part of an
+// experiment to exercise the AffiliationService code in the wild, before users
+// would get a chance to have real Android credentials saved.
+// Note: although somewhat redundant, the URLs are listed explicitly so that
+// they are easy to find in code search if someone wonders why they are fetched.
+const char* kDummyAndroidFacetURIs[] = {
+    "android://oEOFeXmqYvBlkpl3gJlItdIzb59KFnmFGuc1eHFQcIKpEWQuV2X4L7GYkRtdqTi_"
+    "g9YvgKFAXew3rMDjeAkWVA==@com.example.one",
+    "android://oEOFeXmqYvBlkpl3gJlItdIzb59KFnmFGuc1eHFQcIKpEWQuV2X4L7GYkRtdqTi_"
+    "g9YvgKFAXew3rMDjeAkWVA==@com.example.two",
+    "android://oEOFeXmqYvBlkpl3gJlItdIzb59KFnmFGuc1eHFQcIKpEWQuV2X4L7GYkRtdqTi_"
+    "g9YvgKFAXew3rMDjeAkWVA==@com.example.twoprime",
+    "android://oEOFeXmqYvBlkpl3gJlItdIzb59KFnmFGuc1eHFQcIKpEWQuV2X4L7GYkRtdqTi_"
+    "g9YvgKFAXew3rMDjeAkWVA==@com.example.three",
+    "android://oEOFeXmqYvBlkpl3gJlItdIzb59KFnmFGuc1eHFQcIKpEWQuV2X4L7GYkRtdqTi_"
+    "g9YvgKFAXew3rMDjeAkWVA==@com.example.four",
+    "android://oEOFeXmqYvBlkpl3gJlItdIzb59KFnmFGuc1eHFQcIKpEWQuV2X4L7GYkRtdqTi_"
+    "g9YvgKFAXew3rMDjeAkWVA==@com.example.fourprime"};
+
+// Dummy Web facet URIs for the same purpose. The URIs with the same numbers are
+// in the same equivalence class.
+const char* kDummyWebFacetURIs[] = {"https://one.example.com",
+                                    "https://two.example.com",
+                                    "https://three.example.com",
+                                    "https://threeprime.example.com",
+                                    "https://four.example.com",
+                                    "https://fourprime.example.com"};
+
 // Returns whether or not |form| represents a credential for an Android
 // application, and if so, returns the |facet_uri| of that application.
 bool IsAndroidApplicationCredential(const autofill::PasswordForm& form,
@@ -58,19 +88,47 @@
 void AffiliatedMatchHelper::GetAffiliatedAndroidRealms(
     const autofill::PasswordForm& observed_form,
     const AffiliatedRealmsCallback& result_callback) {
-  FacetURI facet_uri(
-      FacetURI::FromPotentiallyInvalidSpec(observed_form.signon_realm));
-  if (observed_form.scheme == autofill::PasswordForm::SCHEME_HTML &&
-      observed_form.ssl_valid && facet_uri.IsValidWebFacetURI()) {
+  if (IsValidWebCredential(observed_form)) {
+    FacetURI facet_uri(
+        FacetURI::FromPotentiallyInvalidSpec(observed_form.signon_realm));
     affiliation_service_->GetAffiliations(
         facet_uri, AffiliationService::StrategyOnCacheMiss::FAIL,
-        base::Bind(&AffiliatedMatchHelper::OnGetAffiliationsResults,
+        base::Bind(&AffiliatedMatchHelper::CompleteGetAffiliatedAndroidRealms,
                    weak_ptr_factory_.GetWeakPtr(), facet_uri, result_callback));
   } else {
     result_callback.Run(std::vector<std::string>());
   }
 }
 
+void AffiliatedMatchHelper::GetAffiliatedWebRealms(
+    const autofill::PasswordForm& android_form,
+    const AffiliatedRealmsCallback& result_callback) {
+  if (IsValidAndroidCredential(android_form)) {
+    affiliation_service_->GetAffiliations(
+        FacetURI::FromPotentiallyInvalidSpec(android_form.signon_realm),
+        AffiliationService::StrategyOnCacheMiss::FETCH_OVER_NETWORK,
+        base::Bind(&AffiliatedMatchHelper::CompleteGetAffiliatedWebRealms,
+                   weak_ptr_factory_.GetWeakPtr(), result_callback));
+  } else {
+    result_callback.Run(std::vector<std::string>());
+  }
+}
+
+// static
+bool AffiliatedMatchHelper::IsValidAndroidCredential(
+    const autofill::PasswordForm& form) {
+  return form.scheme == autofill::PasswordForm::SCHEME_HTML &&
+         IsValidAndroidFacetURI(form.signon_realm);
+}
+
+// static
+bool AffiliatedMatchHelper::IsValidWebCredential(
+    const autofill::PasswordForm& form) {
+  FacetURI facet_uri(FacetURI::FromPotentiallyInvalidSpec(form.signon_realm));
+  return form.scheme == autofill::PasswordForm::SCHEME_HTML && form.ssl_valid &&
+         facet_uri.IsValidWebFacetURI();
+}
+
 // static
 ScopedVector<autofill::PasswordForm>
 AffiliatedMatchHelper::TransformAffiliatedAndroidCredentials(
@@ -97,7 +155,7 @@
   password_store_->GetAutofillableLogins(this);
 }
 
-void AffiliatedMatchHelper::OnGetAffiliationsResults(
+void AffiliatedMatchHelper::CompleteGetAffiliatedAndroidRealms(
     const FacetURI& original_facet_uri,
     const AffiliatedRealmsCallback& result_callback,
     const AffiliatedFacets& results,
@@ -114,6 +172,44 @@
   result_callback.Run(affiliated_realms);
 }
 
+void AffiliatedMatchHelper::CompleteGetAffiliatedWebRealms(
+    const AffiliatedRealmsCallback& result_callback,
+    const AffiliatedFacets& results,
+    bool success) {
+  std::vector<std::string> affiliated_realms;
+  if (success) {
+    for (const FacetURI& affiliated_facet : results) {
+      if (affiliated_facet.IsValidWebFacetURI())
+        // Facet URIs have no trailing slash, whereas realms do.
+        affiliated_realms.push_back(affiliated_facet.canonical_spec() + "/");
+    }
+  }
+  result_callback.Run(affiliated_realms);
+}
+
+void AffiliatedMatchHelper::VerifyAffiliationsForDummyFacets(
+    VerificationTiming timing) {
+  DCHECK(affiliation_service_);
+  for (const char* web_facet_uri : kDummyWebFacetURIs) {
+    // If affiliation for the Android facets has successfully been prefetched,
+    // then cache-restricted queries into affiliated Web facets should succeed.
+    affiliation_service_->GetAffiliations(
+        FacetURI::FromCanonicalSpec(web_facet_uri),
+        AffiliationService::StrategyOnCacheMiss::FAIL,
+        base::Bind(&OnRetrievedAffiliationResultsForDummyWebFacets, timing));
+  }
+}
+
+void AffiliatedMatchHelper::ScheduleVerifyAffiliationsForDummyFacets(
+    base::Timer* timer,
+    base::TimeDelta delay,
+    VerificationTiming timing) {
+  timer->Start(
+      FROM_HERE, delay,
+      base::Bind(&AffiliatedMatchHelper::VerifyAffiliationsForDummyFacets,
+                 base::Unretained(this), timing));
+}
+
 void AffiliatedMatchHelper::OnLoginsChanged(
     const PasswordStoreChangeList& changes) {
   for (const PasswordStoreChange& change : changes) {
@@ -135,6 +231,51 @@
     if (IsAndroidApplicationCredential(*form, &facet_uri))
       affiliation_service_->Prefetch(facet_uri, base::Time::Max());
   }
+
+  // If the respective experiment is enabled, test prefetching affiliation data
+  // for dummy Android facet URIs to discover potenial issues in the wild, even
+  // before users would get a chance to have real Android credentials saved.
+  if (password_manager::IsAffiliationRequestsForDummyFacetsEnabled(
+          *base::CommandLine::ForCurrentProcess())) {
+    for (const char* android_facet_uri : kDummyAndroidFacetURIs) {
+      affiliation_service_->Prefetch(
+          FacetURI::FromCanonicalSpec(android_facet_uri), base::Time::Max());
+    }
+    ScheduleVerifyAffiliationsForDummyFacets(&on_startup_verification_timer_,
+                                             base::TimeDelta::FromMinutes(1),
+                                             VerificationTiming::ON_STARTUP);
+    ScheduleVerifyAffiliationsForDummyFacets(&repeated_verification_timer_,
+                                             base::TimeDelta::FromHours(1),
+                                             VerificationTiming::PERIODIC);
+  }
+}
+
+// static
+void AffiliatedMatchHelper::OnRetrievedAffiliationResultsForDummyWebFacets(
+    VerificationTiming timing,
+    const AffiliatedFacets& results,
+    bool success) {
+  if (timing == AffiliatedMatchHelper::VerificationTiming::ON_STARTUP) {
+    UMA_HISTOGRAM_BOOLEAN(
+        "PasswordManager.AffiliationDummyData.RequestSuccess.OnStartup",
+        success);
+    if (success) {
+      UMA_HISTOGRAM_COUNTS_100(
+          "PasswordManager.AffiliationDummyData.RequestResultCount.OnStartup",
+          results.size());
+    }
+  } else if (timing == AffiliatedMatchHelper::VerificationTiming::PERIODIC) {
+    UMA_HISTOGRAM_BOOLEAN(
+        "PasswordManager.AffiliationDummyData.RequestSuccess.Periodic",
+        success);
+    if (success) {
+      UMA_HISTOGRAM_COUNTS_100(
+          "PasswordManager.AffiliationDummyData.RequestResultCount.Periodic",
+          results.size());
+    }
+  } else {
+    NOTREACHED();
+  }
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/affiliated_match_helper.h b/components/password_manager/core/browser/affiliated_match_helper.h
index 6fa7654..b3ba8860 100644
--- a/components/password_manager/core/browser/affiliated_match_helper.h
+++ b/components/password_manager/core/browser/affiliated_match_helper.h
@@ -13,6 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
+#include "base/timer/timer.h"
 #include "components/password_manager/core/browser/affiliation_utils.h"
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
@@ -68,6 +69,24 @@
       const autofill::PasswordForm& observed_form,
       const AffiliatedRealmsCallback& result_callback);
 
+  // Retrieves realms of web sites affiliated with the Android application that
+  // |android_form| belongs to and invokes |result_callback| on the same thread;
+  // or yields the empty list if  |android_form| is not an Android credential.
+  // NOTE: This will issue an on-demand network request against the Affiliation
+  // API if affiliations of the Android application are not cached. However, as
+  // long as the |android_form| is from the PasswordStore, this should rarely
+  // happen as affiliation information for those applications are prefetched.
+  virtual void GetAffiliatedWebRealms(
+      const autofill::PasswordForm& android_form,
+      const AffiliatedRealmsCallback& result_callback);
+
+  // Returns whether or not |form| represents an Android credential.
+  static bool IsValidAndroidCredential(const autofill::PasswordForm& form);
+
+  // Returns whether or not |form| represents a valid Web credential for the
+  // purposes of affiliation-based matching.
+  static bool IsValidWebCredential(const autofill::PasswordForm& form);
+
   // Consumes a list of |android_credentials| corresponding to applications that
   // are affiliated with the realm of |observed_form|, and transforms them so
   // as to make them fillable into |observed_form|. This can be called from any
@@ -90,15 +109,50 @@
   static const int64 kInitializationDelayOnStartupInSeconds = 8;
 
  private:
+  // Indicates the time at which verifying that affiliation information has been
+  // correctly prefetched for dummy Android applications takes place.
+  enum class VerificationTiming { ON_STARTUP, PERIODIC };
+
   // Reads all autofillable credentials from the password store and starts
   // observing the store for future changes.
   void DoDeferredInitialization();
 
-  // AffiliationService callback:
-  void OnGetAffiliationsResults(const FacetURI& original_facet_uri,
-                                const AffiliatedRealmsCallback& result_callback,
-                                const AffiliatedFacets& results,
-                                bool success);
+  // Called back by AffiliationService to supply the list of facets affiliated
+  // with |original_facet_uri| so that a GetAffiliatedAndroidRealms() call can
+  // be completed.
+  void CompleteGetAffiliatedAndroidRealms(
+      const FacetURI& original_facet_uri,
+      const AffiliatedRealmsCallback& result_callback,
+      const AffiliatedFacets& results,
+      bool success);
+
+  // Called back by AffiliationService to supply the list of facets affiliated
+  // with the Android application that GetAffiliatedWebRealms() was called with,
+  // so that the call can be completed.
+  void CompleteGetAffiliatedWebRealms(
+      const AffiliatedRealmsCallback& result_callback,
+      const AffiliatedFacets& results,
+      bool success);
+
+  // Called either shortly after startup or periodically in the steady state (as
+  // indicated by |timing|) to verify that affiliation information has been
+  // correctly prefetched for the dummy Android applications. Will record UMA
+  // histograms using a appropriate suffix based on |timing|.
+  void VerifyAffiliationsForDummyFacets(VerificationTiming timing);
+
+  // Sets up the given |timer| to call VerifyAffiliationsForDummyFacets() with
+  // the specified |delay|, with the given |timing| designation.
+  void ScheduleVerifyAffiliationsForDummyFacets(base::Timer* timer,
+                                                base::TimeDelta delay,
+                                                VerificationTiming timing);
+
+  // Called back by the AffiliationService in response to requesting affiliation
+  // information for the dummy Web facets. The |timing| indicates if the check
+  // was performed shortly after startup or periodically in the steady state.
+  static void OnRetrievedAffiliationResultsForDummyWebFacets(
+      VerificationTiming timing,
+      const AffiliatedFacets& results,
+      bool success);
 
   // PasswordStore::Observer:
   void OnLoginsChanged(const PasswordStoreChangeList& changes) override;
@@ -113,6 +167,10 @@
   // Being the sole consumer of AffiliationService, |this| owns the service.
   scoped_ptr<AffiliationService> affiliation_service_;
 
+  // Timers used to schedule VerifyAffiliationsPrefetchedForDummyFacets().
+  base::OneShotTimer<AffiliatedMatchHelper> on_startup_verification_timer_;
+  base::RepeatingTimer<AffiliatedMatchHelper> repeated_verification_timer_;
+
   base::WeakPtrFactory<AffiliatedMatchHelper> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AffiliatedMatchHelper);
diff --git a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
index 6f5dc3d0..6ff95ece 100644
--- a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
+++ b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
@@ -164,6 +164,11 @@
     base::RunLoop().RunUntilIdle();
   }
 
+  void UpdateLogin(const autofill::PasswordForm& form) {
+    password_store_->UpdateLogin(form);
+    base::RunLoop().RunUntilIdle();
+  }
+
   void RemoveLogin(const autofill::PasswordForm& form) {
     password_store_->RemoveLogin(form);
     base::RunLoop().RunUntilIdle();
@@ -227,6 +232,18 @@
     return last_result_;
   }
 
+  std::vector<std::string> GetAffiliatedWebRealms(
+      const autofill::PasswordForm& android_form) {
+    expecting_result_callback_ = true;
+    match_helper()->GetAffiliatedWebRealms(
+        android_form,
+        base::Bind(&AffiliatedMatchHelperTest::OnAffiliatedRealmsCallback,
+                   base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
+    EXPECT_FALSE(expecting_result_callback_);
+    return last_result_;
+  }
+
   void DestroyMatchHelper() { match_helper_.reset(); }
 
   base::TestSimpleTaskRunner* waiting_task_runner() {
@@ -354,6 +371,51 @@
               testing::IsEmpty());
 }
 
+// GetAffiliatedWebRealms* tests verify that GetAffiliatedWebRealms() returns
+// the realms of web sites affiliated with the given Android application, but
+// only web sites, and only if an Android application is queried.
+
+TEST_F(AffiliatedMatchHelperTest, GetAffiliatedWebRealmsYieldsResults) {
+  mock_affiliation_service()->ExpectCallToGetAffiliationsAndSucceedWithResult(
+      FacetURI::FromCanonicalSpec(kTestAndroidFacetURIAlpha3),
+      StrategyOnCacheMiss::FETCH_OVER_NETWORK, GetTestEquivalenceClassAlpha());
+  autofill::PasswordForm android_form(
+      GetTestAndroidCredentials(kTestAndroidRealmAlpha3));
+  EXPECT_THAT(
+      GetAffiliatedWebRealms(android_form),
+      testing::UnorderedElementsAre(kTestWebRealmAlpha1, kTestWebRealmAlpha2));
+}
+
+TEST_F(AffiliatedMatchHelperTest, GetAffiliatedWebRealmsYieldsOnlyWebsites) {
+  mock_affiliation_service()->ExpectCallToGetAffiliationsAndSucceedWithResult(
+      FacetURI::FromCanonicalSpec(kTestAndroidFacetURIBeta2),
+      StrategyOnCacheMiss::FETCH_OVER_NETWORK, GetTestEquivalenceClassBeta());
+  autofill::PasswordForm android_form(
+      GetTestAndroidCredentials(kTestAndroidRealmBeta2));
+  // This verifies that |kTestAndroidRealmBeta3| is not returned.
+  EXPECT_THAT(GetAffiliatedWebRealms(android_form),
+              testing::UnorderedElementsAre(kTestWebRealmBeta1));
+}
+
+TEST_F(AffiliatedMatchHelperTest,
+       GetAffiliatedWebRealmsYieldsEmptyResultsForWebKeyedForms) {
+  autofill::PasswordForm web_form(
+      GetTestObservedWebForm(kTestWebRealmBeta1, nullptr));
+  EXPECT_THAT(GetAffiliatedWebRealms(web_form), testing::IsEmpty());
+}
+
+// Note: IsValidWebCredential() is tested as part of GetAffiliatedAndroidRealms
+// tests above.
+TEST_F(AffiliatedMatchHelperTest, IsValidAndroidCredential) {
+  autofill::PasswordForm web_credential(
+      GetTestObservedWebForm(kTestWebRealmBeta1, nullptr));
+  EXPECT_FALSE(AffiliatedMatchHelper::IsValidAndroidCredential(web_credential));
+  autofill::PasswordForm android_credential(
+      GetTestAndroidCredentials(kTestAndroidRealmBeta2));
+  EXPECT_TRUE(
+      AffiliatedMatchHelper::IsValidAndroidCredential(android_credential));
+}
+
 // Verifies that affiliations for Android applications with pre-existing
 // credentials on start-up are prefetched.
 TEST_F(AffiliatedMatchHelperTest,
diff --git a/components/password_manager/core/browser/affiliation_backend.cc b/components/password_manager/core/browser/affiliation_backend.cc
index fe7e31d..48301dbf 100644
--- a/components/password_manager/core/browser/affiliation_backend.cc
+++ b/components/password_manager/core/browser/affiliation_backend.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/location.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/clock.h"
@@ -30,6 +31,7 @@
       task_runner_(task_runner),
       clock_(time_source.Pass()),
       tick_clock_(time_tick_source.Pass()),
+      construction_time_(clock_->Now()),
       weak_ptr_factory_(this) {
   DCHECK_LT(base::Time(), clock_->Now());
 }
@@ -225,9 +227,28 @@
   fetcher_.reset(AffiliationFetcher::Create(request_context_getter_.get(),
                                             requested_facet_uris, this));
   fetcher_->StartRequest();
+  ReportStatistics(requested_facet_uris.size());
   return true;
 }
 
+void AffiliationBackend::ReportStatistics(size_t requested_facet_uri_count) {
+  UMA_HISTOGRAM_COUNTS_100("PasswordManager.AffiliationBackend.FetchSize",
+                           requested_facet_uri_count);
+
+  if (last_request_time_.is_null()) {
+    base::TimeDelta delay = clock_->Now() - construction_time_;
+    UMA_HISTOGRAM_CUSTOM_TIMES(
+        "PasswordManager.AffiliationBackend.FirstFetchDelay", delay,
+        base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(3), 50);
+  } else {
+    base::TimeDelta delay = clock_->Now() - last_request_time_;
+    UMA_HISTOGRAM_CUSTOM_TIMES(
+        "PasswordManager.AffiliationBackend.SubsequentFetchDelay", delay,
+        base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(3), 50);
+  }
+  last_request_time_ = clock_->Now();
+}
+
 void AffiliationBackend::SetThrottlerForTesting(
     scoped_ptr<AffiliationFetchThrottler> throttler) {
   throttler_ = throttler.Pass();
diff --git a/components/password_manager/core/browser/affiliation_backend.h b/components/password_manager/core/browser/affiliation_backend.h
index 88dce8d..334dd264 100644
--- a/components/password_manager/core/browser/affiliation_backend.h
+++ b/components/password_manager/core/browser/affiliation_backend.h
@@ -110,6 +110,10 @@
   // Returns the number of in-memory FacetManagers. Used only for testing.
   size_t facet_manager_count_for_testing() { return facet_managers_.size(); }
 
+  // Reports the |requested_facet_uri_count| in a single fetch; and the elapsed
+  // time before the first fetch, and in-between subsequent fetches.
+  void ReportStatistics(size_t requested_facet_uri_count);
+
   // To be called after Initialize() to use |throttler| instead of the default
   // one. Used only for testing.
   void SetThrottlerForTesting(scoped_ptr<AffiliationFetchThrottler> throttler);
@@ -127,6 +131,9 @@
   scoped_ptr<AffiliationFetcher> fetcher_;
   scoped_ptr<AffiliationFetchThrottler> throttler_;
 
+  base::Time construction_time_;
+  base::Time last_request_time_;
+
   // Contains a FacetManager for each facet URI that need ongoing attention. To
   // save memory, managers are discarded as soon as they become redundant.
   base::ScopedPtrHashMap<FacetURI, FacetManager> facet_managers_;
diff --git a/components/password_manager/core/browser/affiliation_fetcher.cc b/components/password_manager/core/browser/affiliation_fetcher.cc
index 9e6bfd0..53069fa 100644
--- a/components/password_manager/core/browser/affiliation_fetcher.cc
+++ b/components/password_manager/core/browser/affiliation_fetcher.cc
@@ -4,6 +4,8 @@
 
 #include "components/password_manager/core/browser/affiliation_fetcher.h"
 
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
 #include "components/password_manager/core/browser/affiliation_api.pb.h"
 #include "components/password_manager/core/browser/affiliation_utils.h"
 #include "components/password_manager/core/browser/test_affiliation_fetcher_factory.h"
@@ -17,6 +19,37 @@
 
 namespace password_manager {
 
+namespace {
+
+// Enumeration listing the possible outcomes of fetching affiliation information
+// from the Affiliation API. This is used in UMA histograms, so do not change
+// existing values, only add new values at the end.
+enum AffiliationFetchResult {
+  AFFILIATION_FETCH_RESULT_SUCCESS,
+  AFFILIATION_FETCH_RESULT_FAILURE,
+  AFFILIATION_FETCH_RESULT_MALFORMED,
+  AFFILIATION_FETCH_RESULT_MAX
+};
+
+// Records the given fetch |result| into the respective UMA histogram, as well
+// as the response and error codes of |fetcher| if it is non-null.
+void ReportStatistics(AffiliationFetchResult result,
+                      const net::URLFetcher* fetcher) {
+  UMA_HISTOGRAM_ENUMERATION("PasswordManager.AffiliationFetcher.FetchResult",
+                            result, AFFILIATION_FETCH_RESULT_MAX);
+  if (fetcher) {
+    UMA_HISTOGRAM_SPARSE_SLOWLY(
+        "PasswordManager.AffiliationFetcher.FetchHttpResponseCode",
+        fetcher->GetResponseCode());
+    // Network error codes are negative. See: src/net/base/net_error_list.h.
+    UMA_HISTOGRAM_SPARSE_SLOWLY(
+        "PasswordManager.AffiliationFetcher.FetchErrorCode",
+        -fetcher->GetStatus().error());
+  }
+}
+
+}  // namespace
+
 static TestAffiliationFetcherFactory* g_testing_factory = nullptr;
 
 AffiliationFetcher::AffiliationFetcher(
@@ -161,15 +194,21 @@
 void AffiliationFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
   DCHECK_EQ(source, fetcher_.get());
 
-  scoped_ptr<AffiliationFetcherDelegate::Result> result(
+  // Note that invoking the |delegate_| may destroy |this| synchronously, so the
+  // invocation must happen last.
+  scoped_ptr<AffiliationFetcherDelegate::Result> result_data(
       new AffiliationFetcherDelegate::Result);
   if (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
       fetcher_->GetResponseCode() == net::HTTP_OK) {
-    if (ParseResponse(result.get()))
-      delegate_->OnFetchSucceeded(result.Pass());
-    else
+    if (ParseResponse(result_data.get())) {
+      ReportStatistics(AFFILIATION_FETCH_RESULT_SUCCESS, nullptr);
+      delegate_->OnFetchSucceeded(result_data.Pass());
+    } else {
+      ReportStatistics(AFFILIATION_FETCH_RESULT_MALFORMED, nullptr);
       delegate_->OnMalformedResponse();
+    }
   } else {
+    ReportStatistics(AFFILIATION_FETCH_RESULT_FAILURE, fetcher_.get());
     delegate_->OnFetchFailed();
   }
 }
diff --git a/components/password_manager/core/browser/affiliation_utils.cc b/components/password_manager/core/browser/affiliation_utils.cc
index ee1d9b06..fa911ff 100644
--- a/components/password_manager/core/browser/affiliation_utils.cc
+++ b/components/password_manager/core/browser/affiliation_utils.cc
@@ -13,6 +13,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "components/password_manager/core/common/password_manager_switches.h"
+#include "components/variations/variations_associated_data.h"
 #include "net/base/escape.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_canon_stdstring.h"
@@ -25,6 +26,9 @@
 // The scheme used for identifying Android applications.
 const char kAndroidAppScheme[] = "android";
 
+// The name of the field trial controlling affiliation-based matching.
+const char kFieldTrialName[] = "AffiliationBasedMatching";
+
 // Returns a StringPiece corresponding to |component| in |uri|, or the empty
 // string in case there is no such component.
 base::StringPiece ComponentString(const std::string& uri,
@@ -292,7 +296,7 @@
   // Note: It is important to always query the field trial state, to ensure that
   // UMA reports the correct group.
   const std::string group_name =
-      base::FieldTrialList::FindFullName("AffiliationBasedMatching");
+      base::FieldTrialList::FindFullName(kFieldTrialName);
 
   if (command_line.HasSwitch(switches::kDisableAffiliationBasedMatching))
     return false;
@@ -301,6 +305,32 @@
   return StartsWithASCII(group_name, "Enabled", /*case_sensitive=*/false);
 }
 
+bool IsPropagatingPasswordChangesToWebCredentialsEnabled(
+    const base::CommandLine& command_line) {
+  // Note: It is important to always query the variation param first, which, in
+  // turn, queries the field trial state, which ensures that UMA reports the
+  // correct group if it is forced by a command line flag.
+  const std::string update_enabled = variations::GetVariationParamValue(
+      kFieldTrialName, "propagate_password_changes_to_web");
+
+  if (command_line.HasSwitch(switches::kDisableAffiliationBasedMatching))
+    return false;
+  if (command_line.HasSwitch(switches::kEnableAffiliationBasedMatching))
+    return true;
+  return LowerCaseEqualsASCII(update_enabled, "enabled");
+}
+
+bool IsAffiliationRequestsForDummyFacetsEnabled(
+    const base::CommandLine& command_line) {
+  const std::string synthesizing_enabled = variations::GetVariationParamValue(
+      kFieldTrialName, "affiliation_requests_for_dummy_facets");
+  if (command_line.HasSwitch(switches::kDisableAffiliationBasedMatching))
+    return false;
+  if (command_line.HasSwitch(switches::kEnableAffiliationBasedMatching))
+    return true;
+  return LowerCaseEqualsASCII(synthesizing_enabled, "enabled");
+}
+
 bool IsValidAndroidFacetURI(const std::string& url) {
   FacetURI facet = FacetURI::FromPotentiallyInvalidSpec(url);
   return facet.IsValidAndroidFacetURI();
diff --git a/components/password_manager/core/browser/affiliation_utils.h b/components/password_manager/core/browser/affiliation_utils.h
index 1f56c4e8..b5b9546 100644
--- a/components/password_manager/core/browser/affiliation_utils.h
+++ b/components/password_manager/core/browser/affiliation_utils.h
@@ -177,6 +177,22 @@
 // takes precedence.
 bool IsAffiliationBasedMatchingEnabled(const base::CommandLine& command_line);
 
+// Returns whether or not propagating password changes to affiliated saved web
+// credentials is enabled via variation parameters. This allows disabling only
+// the sub-feature while leaving the rest of the affiliation-based matching
+// enabled. If the main feature is forced enabled/disabled via the command line,
+// the sub-feature will be force enabled/disabled correspondingly.
+bool IsPropagatingPasswordChangesToWebCredentialsEnabled(
+    const base::CommandLine& command_line);
+
+// Returns whether or not affiliation requests for dummy facets should be
+// triggered as part of an experiment to exercise AffiliationService code before
+// users would get a chance to have any real Android-based credentials. If the
+// main feature is forced enabled/disabled via the command line, the experiment
+// is force enabled/disabled correspondingly.
+bool IsAffiliationRequestsForDummyFacetsEnabled(
+    const base::CommandLine& command_line);
+
 // For logging use only.
 std::ostream& operator<<(std::ostream& os, const FacetURI& facet_uri);
 
diff --git a/components/password_manager/core/browser/affiliation_utils_unittest.cc b/components/password_manager/core/browser/affiliation_utils_unittest.cc
index 16ed69c..73240bc3 100644
--- a/components/password_manager/core/browser/affiliation_utils_unittest.cc
+++ b/components/password_manager/core/browser/affiliation_utils_unittest.cc
@@ -7,12 +7,14 @@
 #include "base/command_line.h"
 #include "base/metrics/field_trial.h"
 #include "components/password_manager/core/common/password_manager_switches.h"
+#include "components/variations/variations_associated_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/url_constants.h"
 
 namespace password_manager {
 
 namespace {
+const char kFieldTrialName[] = "AffiliationBasedMatching";
 const char kTestFacetURI1[] = "https://alpha.example.com/";
 const char kTestFacetURI2[] = "https://beta.example.com/";
 const char kTestFacetURI3[] = "https://gamma.example.com/";
@@ -196,8 +198,6 @@
 }
 
 TEST(AffiliationUtilsTest, IsAffiliationBasedMatchingEnabled) {
-  const char kFieldTrialName[] = "AffiliationBasedMatching";
-
   struct {
     const char* field_trial_group;
     const char* command_line_switch;
@@ -235,4 +235,92 @@
   }
 }
 
+TEST(AffiliationUtilsTest,
+     IsPropagatingPasswordChangesToWebCredentialsEnabled) {
+  const char kExperimentName[] = "DoesNotMatter";
+
+  struct {
+    const char* variation_param;
+    const char* command_line_switch;
+    bool expected_enabled;
+  } kTestCases[] = {
+      {"", "", false},
+      {"", switches::kEnableAffiliationBasedMatching, true},
+      {"", switches::kDisableAffiliationBasedMatching, false},
+      {"garbage value", "", false},
+      {"disabled", "", false},
+      {"Disabled", "", false},
+      {"Disabled", switches::kDisableAffiliationBasedMatching, false},
+      {"Disabled", switches::kEnableAffiliationBasedMatching, true},
+      {"enabled", "", true},
+      {"Enabled", "", true},
+      {"Enabled", switches::kDisableAffiliationBasedMatching, false},
+      {"Enabled", switches::kEnableAffiliationBasedMatching, true}};
+
+  for (const auto& test_case : kTestCases) {
+    SCOPED_TRACE(testing::Message("Command line = ")
+                 << test_case.command_line_switch);
+    SCOPED_TRACE(testing::Message("Variation param = ")
+                 << test_case.variation_param);
+
+    variations::testing::ClearAllVariationParams();
+    base::FieldTrialList field_trials(nullptr);
+    base::FieldTrialList::CreateFieldTrial(kFieldTrialName, kExperimentName);
+    std::map<std::string, std::string> variation_params;
+    variation_params["propagate_password_changes_to_web"] =
+        test_case.variation_param;
+    ASSERT_TRUE(variations::AssociateVariationParams(
+        kFieldTrialName, kExperimentName, variation_params));
+
+    base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
+    command_line.AppendSwitch(test_case.command_line_switch);
+    EXPECT_EQ(
+        test_case.expected_enabled,
+        IsPropagatingPasswordChangesToWebCredentialsEnabled(command_line));
+  }
+}
+
+TEST(AffiliationUtilsTest, IsAffiliationRequestsForDummyFacetsEnabled) {
+  const char kExperimentName[] = "DoesNotMatter";
+
+  struct {
+    const char* variation_param;
+    const char* command_line_switch;
+    bool expected_enabled;
+  } kTestCases[] = {
+      {"", "", false},
+      {"", switches::kEnableAffiliationBasedMatching, true},
+      {"", switches::kDisableAffiliationBasedMatching, false},
+      {"garbage value", "", false},
+      {"disabled", "", false},
+      {"Disabled", "", false},
+      {"Disabled", switches::kDisableAffiliationBasedMatching, false},
+      {"Disabled", switches::kEnableAffiliationBasedMatching, true},
+      {"enabled", "", true},
+      {"Enabled", "", true},
+      {"Enabled", switches::kDisableAffiliationBasedMatching, false},
+      {"Enabled", switches::kEnableAffiliationBasedMatching, true}};
+
+  for (const auto& test_case : kTestCases) {
+    SCOPED_TRACE(testing::Message("Command line = ")
+                 << test_case.command_line_switch);
+    SCOPED_TRACE(testing::Message("Variation param = ")
+                 << test_case.variation_param);
+
+    variations::testing::ClearAllVariationParams();
+    base::FieldTrialList field_trials(nullptr);
+    base::FieldTrialList::CreateFieldTrial(kFieldTrialName, kExperimentName);
+    std::map<std::string, std::string> variation_params;
+    variation_params["affiliation_requests_for_dummy_facets"] =
+        test_case.variation_param;
+    ASSERT_TRUE(variations::AssociateVariationParams(
+        kFieldTrialName, kExperimentName, variation_params));
+
+    base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
+    command_line.AppendSwitch(test_case.command_line_switch);
+    EXPECT_EQ(test_case.expected_enabled,
+              IsAffiliationRequestsForDummyFacetsEnabled(command_line));
+  }
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_generation_manager_unittest.cc b/components/password_manager/core/browser/password_generation_manager_unittest.cc
index d01d5f5..eda8962 100644
--- a/components/password_manager/core/browser/password_generation_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_generation_manager_unittest.cc
@@ -186,7 +186,7 @@
       "<field autofilltype=\"76\" />"
       "<field autofilltype=\"75\" />"
       "</autofillqueryresponse>";
-  autofill::FormStructure::ParseQueryResponse(kServerResponse, forms);
+  autofill::FormStructure::ParseQueryResponse(kServerResponse, forms, NULL);
 
   DetectAccountCreationForms(forms);
   EXPECT_EQ(1u, GetTestDriver()->GetFoundAccountCreationForms().size());
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index f4cd0658..5b13a3c 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -65,6 +65,7 @@
     : main_thread_runner_(main_thread_runner),
       db_thread_runner_(db_thread_runner),
       observers_(new ObserverListThreadSafe<Observer>()),
+      is_propagating_password_changes_to_web_credentials_enabled_(false),
       shutdown_called_(false) {
 }
 
@@ -218,6 +219,36 @@
                        num_deletions);
 }
 
+PasswordStoreChangeList PasswordStore::AddLoginSync(const PasswordForm& form) {
+  // There is no good way to check if the password is actually up-to-date, or
+  // at least to check if it was actually changed. Assume it is.
+  if (AffiliatedMatchHelper::IsValidAndroidCredential(form))
+    ScheduleFindAndUpdateAffiliatedWebLogins(form);
+  return AddLoginImpl(form);
+}
+
+PasswordStoreChangeList PasswordStore::UpdateLoginSync(
+    const PasswordForm& form) {
+  if (AffiliatedMatchHelper::IsValidAndroidCredential(form)) {
+    // Ideally, a |form| would not be updated in any way unless it was ensured
+    // that it, as a whole, can be used for a successful login. This, sadly, can
+    // not be guaranteed. It might be that |form| just contains updates to some
+    // meta-attribute, while it still has an out-of-date password. If such a
+    // password were to be propagated to affiliated credentials in that case, it
+    // may very well overwrite the actual, up-to-date password. Try to mitigate
+    // this risk by ignoring updates unless they actually update the password.
+    scoped_ptr<PasswordForm> old_form(GetLoginImpl(form));
+    if (old_form && form.password_value != old_form->password_value)
+      ScheduleFindAndUpdateAffiliatedWebLogins(form);
+  }
+  return UpdateLoginImpl(form);
+}
+
+PasswordStoreChangeList PasswordStore::RemoveLoginSync(
+    const PasswordForm& form) {
+  return RemoveLoginImpl(form);
+}
+
 void PasswordStore::NotifyLoginsChanged(
     const PasswordStoreChangeList& changes) {
   DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
@@ -301,6 +332,134 @@
                           additional_android_realms));
 }
 
+scoped_ptr<PasswordForm> PasswordStore::GetLoginImpl(
+    const PasswordForm& primary_key) {
+  DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
+  ScopedVector<PasswordForm> candidates(
+      FillMatchingLogins(primary_key, DISALLOW_PROMPT));
+  for (PasswordForm*& candidate : candidates) {
+    if (candidate->signon_realm == primary_key.signon_realm &&
+        candidate->username_element == primary_key.username_element &&
+        candidate->username_value == primary_key.username_value &&
+        candidate->password_element == primary_key.password_element &&
+        candidate->origin == primary_key.origin &&
+        !candidate->IsPublicSuffixMatch()) {
+      scoped_ptr<PasswordForm> result(candidate);
+      candidate = nullptr;
+      return result.Pass();
+    }
+  }
+  return make_scoped_ptr<PasswordForm>(nullptr);
+}
+
+void PasswordStore::FindAndUpdateAffiliatedWebLogins(
+    const PasswordForm& added_or_updated_android_form) {
+  if (!affiliated_match_helper_ ||
+      !is_propagating_password_changes_to_web_credentials_enabled_) {
+    return;
+  }
+  affiliated_match_helper_->GetAffiliatedWebRealms(
+      added_or_updated_android_form,
+      base::Bind(&PasswordStore::ScheduleUpdateAffiliatedWebLoginsImpl, this,
+                 added_or_updated_android_form));
+}
+
+void PasswordStore::ScheduleFindAndUpdateAffiliatedWebLogins(
+    const PasswordForm& added_or_updated_android_form) {
+  main_thread_runner_->PostTask(
+      FROM_HERE, base::Bind(&PasswordStore::FindAndUpdateAffiliatedWebLogins,
+                            this, added_or_updated_android_form));
+}
+
+void PasswordStore::UpdateAffiliatedWebLoginsImpl(
+    const PasswordForm& updated_android_form,
+    const std::vector<std::string>& affiliated_web_realms) {
+  DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
+  PasswordStoreChangeList all_changes;
+  for (const std::string& affiliated_web_realm : affiliated_web_realms) {
+    PasswordForm web_form_template;
+    web_form_template.scheme = PasswordForm::SCHEME_HTML;
+    web_form_template.signon_realm = affiliated_web_realm;
+    ScopedVector<PasswordForm> web_logins(
+        FillMatchingLogins(web_form_template, DISALLOW_PROMPT));
+    for (PasswordForm* web_login : web_logins) {
+      // Do not update HTTP logins, logins saved under insecure conditions, and
+      // non-HTML login forms; PSL matches; logins with a different username;
+      // and logins with the same password (to avoid generating no-op updates).
+      if (!AffiliatedMatchHelper::IsValidWebCredential(*web_login) ||
+          web_login->IsPublicSuffixMatch() ||
+          web_login->username_value != updated_android_form.username_value ||
+          web_login->password_value == updated_android_form.password_value)
+        continue;
+
+      // If the |web_login| was updated in the same or a later chunk of Sync
+      // changes, assume that it is more recent and do not update it. Note that
+      // this check is far from perfect conflict resolution and mostly prevents
+      // long-dormant Sync clients doing damage when they wake up in the face
+      // of the following list of changes:
+      //
+      //   Time   Source     Change
+      //   ====   ======     ======
+      //   #1     Android    android_login.password_value = "A"
+      //   #2     Client A   web_login.password_value = "A" (propagation)
+      //   #3     Client A   web_login.password_value = "B" (manual overwrite)
+      //
+      // When long-dormant Sync client B wakes up, it will only get a distilled
+      // subset of not-yet-obsoleted changes {1, 3}. In this case, client B must
+      // not propagate password "A" to |web_login|. This is prevented as change
+      // #3 will arrive either in the same/later chunk of sync changes, so the
+      // |date_synced| of |web_login| value will be greater or equal.
+      //
+      // Note that this solution has several shortcomings:
+      //
+      //   (1) It will not prevent local changes to |web_login| from being
+      //       overwritten if they were made shortly after start-up, before
+      //       Sync changes are applied. This should be tolerable.
+      //
+      //   (2) It assumes that all Sync clients are fully capable of propagating
+      //       changes to web credentials on their own. If client C runs an
+      //       older version of Chrome and updates the password for |web_login|
+      //       around the time when the |android_login| is updated, the updated
+      //       password will not be propagated by client B to |web_login| when
+      //       it wakes up, regardless of the temporal order of the original
+      //       changes, as client B will see both credentials having the same
+      //       |data_synced|.
+      //
+      //   (2a) Above could be mitigated by looking not only at |data_synced|,
+      //        but also at the actual order of Sync changes.
+      //
+      //   (2b) However, (2a) is still not workable, as a Sync change is made
+      //        when any attribute of the credential is updated, not only the
+      //        password. Hence it is not possible for client B to distinguish
+      //        between two following two event orders:
+      //
+      //    #1     Android    android_login.password_value = "A"
+      //    #2     Client C   web_login.password_value = "B" (manual overwrite)
+      //    #3     Android    android_login.random_attribute = "..."
+      //
+      //    #1     Client C   web_login.password_value = "B" (manual overwrite)
+      //    #2     Android    android_login.password_value = "A"
+      //
+      //        And so it must assume that it is unsafe to update |web_login|.
+      if (web_login->date_synced >= updated_android_form.date_synced)
+        continue;
+
+      web_login->password_value = updated_android_form.password_value;
+
+      PasswordStoreChangeList changes = UpdateLoginImpl(*web_login);
+      all_changes.insert(all_changes.end(), changes.begin(), changes.end());
+    }
+  }
+  NotifyLoginsChanged(all_changes);
+}
+
+void PasswordStore::ScheduleUpdateAffiliatedWebLoginsImpl(
+    const PasswordForm& updated_android_form,
+    const std::vector<std::string>& affiliated_web_realms) {
+  ScheduleTask(base::Bind(&PasswordStore::UpdateAffiliatedWebLoginsImpl, this,
+                          updated_android_form, affiliated_web_realms));
+}
+
 void PasswordStore::InitSyncableService(
     const syncer::SyncableService::StartSyncFlare& flare) {
   DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h
index 852a51e..74ff469 100644
--- a/components/password_manager/core/browser/password_store.h
+++ b/components/password_manager/core/browser/password_store.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_
 
 #include "base/callback.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
@@ -74,6 +75,12 @@
   // initialized if it is non-null.
   void SetAffiliatedMatchHelper(scoped_ptr<AffiliatedMatchHelper> helper);
 
+  // Toggles whether or not to propagate password changes in Android credentials
+  // to the affiliated Web credentials.
+  void enable_propagating_password_changes_to_web_credentials(bool enabled) {
+    is_propagating_password_changes_to_web_credentials_enabled_ = enabled;
+  }
+
   // Returns whether or not an affiliation-based match helper is set.
   bool HasAffiliatedMatchHelper() const;
 
@@ -181,16 +188,6 @@
   virtual void ReportMetricsImpl(const std::string& sync_username,
                                  bool custom_passphrase_sync_enabled) = 0;
 
-  // Bring PasswordStoreSync methods to the scope of PasswordStore. Otherwise,
-  // base::Bind can't be used with them because it fails to cast PasswordStore
-  // to PasswordStoreSync.
-  PasswordStoreChangeList AddLoginImpl(
-      const autofill::PasswordForm& form) override = 0;
-  PasswordStoreChangeList UpdateLoginImpl(
-      const autofill::PasswordForm& form) override = 0;
-  PasswordStoreChangeList RemoveLoginImpl(
-      const autofill::PasswordForm& form) override = 0;
-
   // Synchronous implementation to remove the given logins.
   virtual PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl(
       base::Time delete_begin,
@@ -211,6 +208,20 @@
                              AuthorizationPromptPolicy prompt_policy,
                              scoped_ptr<GetLoginsRequest> request);
 
+  // Synchronous implementation provided by subclasses to add the given login.
+  virtual PasswordStoreChangeList AddLoginImpl(
+      const autofill::PasswordForm& form) = 0;
+
+  // Synchronous implementation provided by subclasses to update the given
+  // login.
+  virtual PasswordStoreChangeList UpdateLoginImpl(
+      const autofill::PasswordForm& form) = 0;
+
+  // Synchronous implementation provided by subclasses to remove the given
+  // login.
+  virtual PasswordStoreChangeList RemoveLoginImpl(
+      const autofill::PasswordForm& form) = 0;
+
   // Finds and returns all PasswordForms with the same signon_realm as |form|,
   // or with a signon_realm that is a PSL-match to that of |form|.
   virtual ScopedVector<autofill::PasswordForm> FillMatchingLogins(
@@ -232,6 +243,13 @@
   void LogStatsForBulkDeletionDuringRollback(int num_deletions);
 
   // PasswordStoreSync:
+  PasswordStoreChangeList AddLoginSync(
+      const autofill::PasswordForm& form) override;
+  PasswordStoreChangeList UpdateLoginSync(
+      const autofill::PasswordForm& form) override;
+  PasswordStoreChangeList RemoveLoginSync(
+      const autofill::PasswordForm& form) override;
+
   // Called by WrapModificationTask() once the underlying data-modifying
   // operation has been performed. Notifies observers that password store data
   // may have been changed.
@@ -245,6 +263,10 @@
   scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner_;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, GetLoginImpl);
+  FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest,
+                           UpdatePasswordsStoredForAffiliatedWebsites);
+
   // Schedule the given |func| to be run in the PasswordStore's own thread with
   // responses delivered to |consumer| on the current thread.
   void Schedule(void (PasswordStore::*func)(scoped_ptr<GetLoginsRequest>),
@@ -286,6 +308,38 @@
       scoped_ptr<GetLoginsRequest> request,
       const std::vector<std::string>& additional_android_realms);
 
+  // Retrieves the currently stored form, if any, with the same primary key as
+  // |form|, that is, with the same signon_realm, origin, username_element,
+  // username_value and password_element attributes. To be called on the
+  // background thread.
+  scoped_ptr<autofill::PasswordForm> GetLoginImpl(
+      const autofill::PasswordForm& primary_key);
+
+  // Called when a password is added or updated for an Android application, and
+  // triggers finding web sites affiliated with the Android application and
+  // propagating the new password to credentials for those web sites, if any.
+  // Called on the main thread.
+  void FindAndUpdateAffiliatedWebLogins(
+      const autofill::PasswordForm& added_or_updated_android_form);
+
+  // Posts FindAndUpdateAffiliatedWebLogins() to the main thread. Should be
+  // called from the background thread.
+  void ScheduleFindAndUpdateAffiliatedWebLogins(
+      const autofill::PasswordForm& added_or_updated_android_form);
+
+  // Called when a password is added or updated for an Android application, and
+  // propagates these changes to credentials stored for |affiliated_web_realms|
+  // under the same username, if there are any. Called on the background thread.
+  void UpdateAffiliatedWebLoginsImpl(
+      const autofill::PasswordForm& updated_android_form,
+      const std::vector<std::string>& affiliated_web_realms);
+
+  // Schedules UpdateAffiliatedWebLoginsImpl() to run on the background thread.
+  // Should be called from the main thread.
+  void ScheduleUpdateAffiliatedWebLoginsImpl(
+      const autofill::PasswordForm& updated_android_form,
+      const std::vector<std::string>& affiliated_web_realms);
+
   // Creates PasswordSyncableService instance on the background thread.
   void InitSyncableService(
       const syncer::SyncableService::StartSyncFlare& flare);
@@ -298,6 +352,7 @@
 
   scoped_ptr<PasswordSyncableService> syncable_service_;
   scoped_ptr<AffiliatedMatchHelper> affiliated_match_helper_;
+  bool is_propagating_password_changes_to_web_credentials_enabled_;
 
   bool shutdown_called_;
 
diff --git a/components/password_manager/core/browser/password_store_sync.h b/components/password_manager/core/browser/password_store_sync.h
index 731d338..296e71167 100644
--- a/components/password_manager/core/browser/password_store_sync.h
+++ b/components/password_manager/core/browser/password_store_sync.h
@@ -28,15 +28,15 @@
       WARN_UNUSED_RESULT = 0;
 
   // Synchronous implementation to add the given login.
-  virtual PasswordStoreChangeList AddLoginImpl(
+  virtual PasswordStoreChangeList AddLoginSync(
       const autofill::PasswordForm& form) = 0;
 
   // Synchronous implementation to update the given login.
-  virtual PasswordStoreChangeList UpdateLoginImpl(
+  virtual PasswordStoreChangeList UpdateLoginSync(
       const autofill::PasswordForm& form) = 0;
 
   // Synchronous implementation to remove the given login.
-  virtual PasswordStoreChangeList RemoveLoginImpl(
+  virtual PasswordStoreChangeList RemoveLoginSync(
       const autofill::PasswordForm& form) = 0;
 
   // Notifies observers that password store data may have been changed.
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc
index f5e2a14..6d1a350 100644
--- a/components/password_manager/core/browser/password_store_unittest.cc
+++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -12,7 +12,9 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/password_manager/core/browser/affiliated_match_helper.h"
 #include "components/password_manager/core/browser/affiliation_service.h"
@@ -36,6 +38,18 @@
 const char kTestWebOrigin1[] = "https://one.example.com/origin";
 const char kTestWebRealm2[] = "https://two.example.com/";
 const char kTestWebOrigin2[] = "https://two.example.com/origin";
+const char kTestWebRealm3[] = "https://three.example.com/";
+const char kTestWebOrigin3[] = "https://three.example.com/origin";
+const char kTestWebRealm4[] = "https://four.example.com/";
+const char kTestWebOrigin4[] = "https://four.example.com/origin";
+const char kTestWebRealm5[] = "https://five.example.com/";
+const char kTestWebOrigin5[] = "https://five.example.com/origin";
+const char kTestPSLMatchingWebRealm[] = "https://psl.example.com/";
+const char kTestPSLMatchingWebOrigin[] = "https://psl.example.com/origin";
+const char kTestUnrelatedWebRealm[] = "https://notexample.com/";
+const char kTestUnrelatedWebOrigin[] = "https:/notexample.com/origin";
+const char kTestInsecureWebRealm[] = "http://one.example.com/";
+const char kTestInsecureWebOrigin[] = "http://one.example.com/origin";
 const char kTestAndroidRealm1[] = "android://hash@com.example.android/";
 const char kTestAndroidRealm2[] = "android://hash@com.example.two.android/";
 const char kTestAndroidRealm3[] = "android://hash@com.example.three.android/";
@@ -53,6 +67,13 @@
   }
 };
 
+class MockPasswordStoreObserver
+    : public password_manager::PasswordStore::Observer {
+ public:
+  MOCK_METHOD1(OnLoginsChanged,
+               void(const password_manager::PasswordStoreChangeList& changes));
+};
+
 class MockAffiliatedMatchHelper : public AffiliatedMatchHelper {
  public:
   MockAffiliatedMatchHelper()
@@ -70,9 +91,21 @@
         .WillOnce(testing::Return(results_to_return));
   }
 
+  // Expects GetAffiliatedWebRealms() to be called with the
+  // |expected_android_form|, and will cause the result callback supplied to
+  // GetAffiliatedWebRealms() to be invoked with |results_to_return|.
+  void ExpectCallToGetAffiliatedWebRealms(
+      const autofill::PasswordForm& expected_android_form,
+      const std::vector<std::string>& results_to_return) {
+    EXPECT_CALL(*this, OnGetAffiliatedWebRealmsCalled(expected_android_form))
+        .WillOnce(testing::Return(results_to_return));
+  }
+
  private:
   MOCK_METHOD1(OnGetAffiliatedAndroidRealmsCalled,
                std::vector<std::string>(const PasswordForm&));
+  MOCK_METHOD1(OnGetAffiliatedWebRealmsCalled,
+               std::vector<std::string>(const PasswordForm&));
 
   void GetAffiliatedAndroidRealms(
       const autofill::PasswordForm& observed_form,
@@ -82,6 +115,14 @@
     result_callback.Run(affiliated_android_realms);
   }
 
+  void GetAffiliatedWebRealms(
+      const autofill::PasswordForm& android_form,
+      const AffiliatedRealmsCallback& result_callback) override {
+    std::vector<std::string> affiliated_web_realms =
+        OnGetAffiliatedWebRealmsCalled(android_form);
+    result_callback.Run(affiliated_web_realms);
+  }
+
   DISALLOW_COPY_AND_ASSIGN(MockAffiliatedMatchHelper);
 };
 
@@ -258,6 +299,56 @@
   base::MessageLoop::current()->RunUntilIdle();
 }
 
+TEST_F(PasswordStoreTest, GetLoginImpl) {
+  /* clang-format off */
+  static const PasswordFormData kTestCredential = {
+      PasswordForm::SCHEME_HTML,
+      kTestWebRealm1,
+      kTestWebOrigin1,
+      "", L"", L"username_element",  L"password_element",
+      L"username_value",
+      L"", true, true, 1};
+  /* clang-format on */
+
+  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
+      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
+      make_scoped_ptr(new LoginDatabase(test_login_db_file_path()))));
+  store->Init(syncer::SyncableService::StartSyncFlare());
+
+  // For each attribute in the primary key, create one form that mismatches on
+  // that attribute.
+  scoped_ptr<PasswordForm> test_form(
+      CreatePasswordFormFromDataForTesting(kTestCredential));
+  scoped_ptr<PasswordForm> mismatching_form_1(new PasswordForm(*test_form));
+  mismatching_form_1->signon_realm = kTestPSLMatchingWebRealm;
+  scoped_ptr<PasswordForm> mismatching_form_2(new PasswordForm(*test_form));
+  mismatching_form_2->origin = GURL(kTestPSLMatchingWebOrigin);
+  scoped_ptr<PasswordForm> mismatching_form_3(new PasswordForm(*test_form));
+  mismatching_form_3->username_element = base::ASCIIToUTF16("other_element");
+  scoped_ptr<PasswordForm> mismatching_form_4(new PasswordForm(*test_form));
+  mismatching_form_4->password_element = base::ASCIIToUTF16("other_element");
+  scoped_ptr<PasswordForm> mismatching_form_5(new PasswordForm(*test_form));
+  mismatching_form_5->username_value =
+      base::ASCIIToUTF16("other_username_value");
+
+  store->AddLogin(*mismatching_form_1);
+  store->AddLogin(*mismatching_form_2);
+  store->AddLogin(*mismatching_form_3);
+  store->AddLogin(*mismatching_form_4);
+  store->AddLogin(*mismatching_form_5);
+  base::MessageLoop::current()->RunUntilIdle();
+  EXPECT_FALSE(store->GetLoginImpl(*test_form));
+
+  store->AddLogin(*test_form);
+  base::MessageLoop::current()->RunUntilIdle();
+  scoped_ptr<PasswordForm> returned_form = store->GetLoginImpl(*test_form);
+  ASSERT_TRUE(returned_form);
+  EXPECT_EQ(*test_form, *returned_form);
+
+  store->Shutdown();
+  base::MessageLoop::current()->RunUntilIdle();
+}
+
 // When no Android applications are actually affiliated with the realm of the
 // observed form, GetLoginsWithAffiliations() should still return the exact and
 // PSL matching results, but not any stored Android credentials.
@@ -273,8 +364,8 @@
        L"", true, true, 1},
       // Credential that is a PSL match of the observed form.
       {PasswordForm::SCHEME_HTML,
-       kTestWebRealm2,
-       kTestWebOrigin2,
+       kTestPSLMatchingWebRealm,
+       kTestPSLMatchingWebOrigin,
        "", L"", L"",  L"",
        L"username_value_2",
        L"", true, true, 1},
@@ -349,8 +440,8 @@
        L"", true, true, 1},
       // Credential that is a PSL match of the observed form.
       {PasswordForm::SCHEME_HTML,
-       kTestWebRealm2,
-       kTestWebOrigin2,
+       kTestPSLMatchingWebRealm,
+       kTestPSLMatchingWebOrigin,
        "", L"", L"",  L"",
        L"username_value_2",
        L"", true, true, 1},
@@ -435,4 +526,222 @@
   base::MessageLoop::current()->RunUntilIdle();
 }
 
+// This test must use passwords, which are not stored on Mac, therefore the test
+// is disabled on Mac. This should not be a huge issue as functionality in the
+// platform-independent base class is tested. See also the file-level comment.
+#if defined(OS_MACOSX)
+#define MAYBE_UpdatePasswordsStoredForAffiliatedWebsites \
+  DISABLED_UpdatePasswordsStoredForAffiliatedWebsites
+#else
+#define MAYBE_UpdatePasswordsStoredForAffiliatedWebsites \
+  UpdatePasswordsStoredForAffiliatedWebsites
+#endif
+
+// When the password stored for an Android application is updated, credentials
+// with the same username stored for affiliated web sites should also be updated
+// automatically.
+TEST_F(PasswordStoreTest, MAYBE_UpdatePasswordsStoredForAffiliatedWebsites) {
+  const wchar_t kTestUsername[] = L"username_value_1";
+  const wchar_t kTestOtherUsername[] = L"username_value_2";
+  const wchar_t kTestOldPassword[] = L"old_password_value";
+  const wchar_t kTestNewPassword[] = L"new_password_value";
+  const wchar_t kTestOtherPassword[] = L"other_password_value";
+
+  /* clang-format off */
+  static const PasswordFormData kTestCredentials[] = {
+      // The credential for the Android application that will be updated
+      // explicitly so it can be tested if the changes are correctly propagated
+      // to affiliated Web credentials.
+      {PasswordForm::SCHEME_HTML,
+       kTestAndroidRealm1,
+       "", "", L"", L"", L"",
+       kTestUsername,
+       kTestOldPassword, true, true, 2},
+
+      // --- Positive samples --- Credentials that the password update should be
+      // automatically propagated to.
+
+      // Credential for an affiliated web site with the same username.
+      {PasswordForm::SCHEME_HTML,
+       kTestWebRealm1,
+       kTestWebOrigin1,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestOldPassword, true, true, 1},
+      // Credential for another affiliated web site with the same username.
+      // Although the password is different than the current/old password for
+      // the Android application, it should be updated regardless.
+      {PasswordForm::SCHEME_HTML,
+       kTestWebRealm2,
+       kTestWebOrigin2,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestOtherPassword, true, true, 1},
+
+      // --- Negative samples --- Credentials that the password update should
+      // not be propagated to.
+
+      // Credential for another affiliated web site, but one that already has
+      // the new password.
+      {PasswordForm::SCHEME_HTML,
+       kTestWebRealm3,
+       kTestWebOrigin3,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestNewPassword, true, true, 1},
+      // Credential for another affiliated web site, but one that was saved
+      // under insecure conditions.
+      {PasswordForm::SCHEME_HTML,
+       kTestWebRealm4,
+       kTestWebOrigin4,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestOldPassword, true, false, 1},
+      // Credential for the HTTP version of an affiliated web site.
+      {PasswordForm::SCHEME_HTML,
+       kTestInsecureWebRealm,
+       kTestInsecureWebOrigin,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestOldPassword, true, false, 1},
+      // Credential for an affiliated web site, but with a different username.
+      {PasswordForm::SCHEME_HTML,
+       kTestWebRealm1,
+       kTestWebOrigin1,
+       "", L"", L"",  L"",
+       kTestOtherUsername,
+       kTestOldPassword, true, true, 1},
+      // Credential for a web site that is a PSL match to a web sites affiliated
+      // with the Android application.
+      {PasswordForm::SCHEME_HTML,
+       kTestPSLMatchingWebRealm,
+       kTestPSLMatchingWebOrigin,
+       "poisoned", L"poisoned", L"",  L"",
+       kTestUsername,
+       kTestOldPassword, true, true, 1},
+      // Credential for an unrelated web site.
+      {PasswordForm::SCHEME_HTML,
+       kTestUnrelatedWebRealm,
+       kTestUnrelatedWebOrigin,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestOldPassword, true, true, 1},
+      // Credential for an affiliated Android application.
+      {PasswordForm::SCHEME_HTML,
+       kTestAndroidRealm2,
+       "", "", L"", L"", L"",
+       kTestUsername,
+       kTestOldPassword, true, true, 1},
+      // Credential for an unrelated Android application.
+      {PasswordForm::SCHEME_HTML,
+       kTestUnrelatedAndroidRealm,
+       "", "", L"", L"", L"",
+       kTestUsername,
+       kTestOldPassword, true, true, 1},
+      // Credential for an affiliated web site with the same username, but one
+      // that was updated at the same time via Sync as the Android credential.
+      {PasswordForm::SCHEME_HTML,
+       kTestWebRealm5,
+       kTestWebOrigin5,
+       "", L"", L"",  L"",
+       kTestUsername,
+       kTestOtherPassword, true, true, 2}};
+  /* clang-format on */
+
+  // The number of positive samples in |kTestCredentials|.
+  const size_t kExpectedNumberOfPropagatedUpdates = 2u;
+
+  const bool kFalseTrue[] = {false, true};
+  for (bool propagation_enabled : kFalseTrue) {
+    for (bool test_remove_and_add_login : kFalseTrue) {
+      SCOPED_TRACE(testing::Message("propagation_enabled: ")
+                   << propagation_enabled);
+      SCOPED_TRACE(testing::Message("test_remove_and_add_login: ")
+                   << test_remove_and_add_login);
+
+      scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
+          base::ThreadTaskRunnerHandle::Get(),
+          base::ThreadTaskRunnerHandle::Get(),
+          make_scoped_ptr(new LoginDatabase(test_login_db_file_path()))));
+      store->Init(syncer::SyncableService::StartSyncFlare());
+      store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max());
+
+      // Set up the initial test data set.
+      ScopedVector<PasswordForm> all_credentials;
+      for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
+        all_credentials.push_back(
+            CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
+        all_credentials.back()->date_synced =
+            all_credentials.back()->date_created;
+        store->AddLogin(*all_credentials.back());
+        base::MessageLoop::current()->RunUntilIdle();
+      }
+
+      // The helper must be injected after the initial test data is set up,
+      // otherwise it will already start propagating updates as new Android
+      // credentials are added.
+      MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
+      store->SetAffiliatedMatchHelper(make_scoped_ptr(mock_helper));
+      store->enable_propagating_password_changes_to_web_credentials(
+          propagation_enabled);
+
+      // Calculate how the correctly updated test data set should look like.
+      size_t expected_number_of_propageted_updates =
+          propagation_enabled ? kExpectedNumberOfPropagatedUpdates : 0u;
+      ScopedVector<PasswordForm> expected_credentials_after_update;
+      for (size_t i = 0; i < all_credentials.size(); ++i) {
+        expected_credentials_after_update.push_back(
+            new autofill::PasswordForm(*all_credentials[i]));
+        if (i < 1 + expected_number_of_propageted_updates) {
+          expected_credentials_after_update.back()->password_value =
+              base::WideToUTF16(kTestNewPassword);
+        }
+      }
+
+      if (propagation_enabled) {
+        std::vector<std::string> affiliated_web_realms;
+        affiliated_web_realms.push_back(kTestWebRealm1);
+        affiliated_web_realms.push_back(kTestWebRealm2);
+        affiliated_web_realms.push_back(kTestWebRealm3);
+        affiliated_web_realms.push_back(kTestWebRealm4);
+        affiliated_web_realms.push_back(kTestWebRealm5);
+        mock_helper->ExpectCallToGetAffiliatedWebRealms(
+            *expected_credentials_after_update[0], affiliated_web_realms);
+      }
+
+      // Explicitly update the Android credential, wait until things calm down,
+      // then query all passwords and expect that:
+      //   1.) The positive samples in |kTestCredentials| have the new password,
+      //       but the negative samples do not.
+      //   2.) Change notifications are sent about the updates. Note that as the
+      //       test interacts with the (Update|Add)LoginSync methods, only the
+      //       derived changes should trigger notifications, the first one would
+      //       normally be trigger by Sync.
+      MockPasswordStoreObserver mock_observer;
+      store->AddObserver(&mock_observer);
+      if (propagation_enabled) {
+        EXPECT_CALL(mock_observer, OnLoginsChanged(testing::SizeIs(
+                                       expected_number_of_propageted_updates)));
+      }
+      if (test_remove_and_add_login) {
+        store->RemoveLoginSync(*all_credentials[0]);
+        store->AddLoginSync(*expected_credentials_after_update[0]);
+      } else {
+        store->UpdateLoginSync(*expected_credentials_after_update[0]);
+      }
+      base::MessageLoop::current()->RunUntilIdle();
+      store->RemoveObserver(&mock_observer);
+
+      MockPasswordStoreConsumer mock_consumer;
+      EXPECT_CALL(
+          mock_consumer,
+          OnGetPasswordStoreResultsConstRef(UnorderedPasswordFormElementsAre(
+              expected_credentials_after_update.get())));
+      store->GetAutofillableLogins(&mock_consumer);
+      store->Shutdown();
+      base::MessageLoop::current()->RunUntilIdle();
+    }
+  }
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_syncable_service.cc b/components/password_manager/core/browser/password_syncable_service.cc
index 870aecb..d8ced9d 100644
--- a/components/password_manager/core/browser/password_syncable_service.cc
+++ b/components/password_manager/core/browser/password_syncable_service.cc
@@ -260,6 +260,7 @@
     AppendPasswordFromSpecifics(
         specifics.password().client_only_encrypted_data(), time_now, entries);
   }
+
   WriteToPasswordStore(sync_entries);
   return syncer::SyncError();
 }
@@ -335,15 +336,12 @@
 
 void PasswordSyncableService::WriteToPasswordStore(const SyncEntries& entries) {
   PasswordStoreChangeList changes;
-  WriteEntriesToDatabase(&PasswordStoreSync::AddLoginImpl,
-                         entries.new_entries.get(),
-                         &changes);
-  WriteEntriesToDatabase(&PasswordStoreSync::UpdateLoginImpl,
-                         entries.updated_entries.get(),
-                         &changes);
-  WriteEntriesToDatabase(&PasswordStoreSync::RemoveLoginImpl,
-                         entries.deleted_entries.get(),
-                         &changes);
+  WriteEntriesToDatabase(&PasswordStoreSync::AddLoginSync,
+                         entries.new_entries.get(), &changes);
+  WriteEntriesToDatabase(&PasswordStoreSync::UpdateLoginSync,
+                         entries.updated_entries.get(), &changes);
+  WriteEntriesToDatabase(&PasswordStoreSync::RemoveLoginSync,
+                         entries.deleted_entries.get(), &changes);
 
   // We have to notify password store observers of the change by hand since
   // we use internal password store interfaces to make changes synchronously.
diff --git a/components/printing/renderer/print_web_view_helper.h b/components/printing/renderer/print_web_view_helper.h
index d040dbc8..562b1e0 100644
--- a/components/printing/renderer/print_web_view_helper.h
+++ b/components/printing/renderer/print_web_view_helper.h
@@ -26,6 +26,17 @@
 struct PrintMsg_PrintPages_Params;
 struct PrintHostMsg_SetOptionsFromDocument_Params;
 
+// RenderVIewTest-based tests crash on Android
+// http://crbug.com/187500
+#if defined(OS_ANDROID)
+#define MAYBE_PrintWebViewHelperTest DISABLED_PrintWebViewHelperTest
+#define MAYBE_PrintWebViewHelperPreviewTest \
+    DISABLED_PrintWebViewHelperPreviewTest
+#else
+#define MAYBE_PrintWebViewHelperTest PrintWebViewHelperTest
+#define MAYBE_PrintWebViewHelperPreviewTest PrintWebViewHelperPreviewTest
+#endif  // defined(OS_ANDROID)
+
 namespace base {
 class DictionaryValue;
 }
@@ -115,16 +126,16 @@
 
  private:
   friend class PrintWebViewHelperTestBase;
-  FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperPreviewTest,
+  FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintWebViewHelperPreviewTest,
                            BlockScriptInitiatedPrinting);
-  FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, OnPrintPages);
-  FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest,
+  FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintWebViewHelperTest, OnPrintPages);
+  FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintWebViewHelperTest,
                            BlockScriptInitiatedPrinting);
-  FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest,
+  FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintWebViewHelperTest,
                            BlockScriptInitiatedPrintingFromPopup);
 #if defined(OS_WIN) || defined(OS_MACOSX)
-  FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintLayoutTest);
-  FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintWithIframe);
+  FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintWebViewHelperTest, PrintLayoutTest);
+  FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintWebViewHelperTest, PrintWithIframe);
 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
 
   enum PrintingResult {
diff --git a/components/printing/test/print_web_view_helper_browsertest.cc b/components/printing/test/print_web_view_helper_browsertest.cc
index bfdc311..65ecc23 100644
--- a/components/printing/test/print_web_view_helper_browsertest.cc
+++ b/components/printing/test/print_web_view_helper_browsertest.cc
@@ -248,22 +248,30 @@
   DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTestBase);
 };
 
-class PrintWebViewHelperTest : public PrintWebViewHelperTestBase {
+// RenderVIewTest-based tests crash on Android
+// http://crbug.com/187500
+#if defined(OS_ANDROID)
+#define MAYBE_PrintWebViewHelperTest DISABLED_PrintWebViewHelperTest
+#else
+#define MAYBE_PrintWebViewHelperTest PrintWebViewHelperTest
+#endif  // defined(OS_ANDROID)
+
+class MAYBE_PrintWebViewHelperTest : public PrintWebViewHelperTestBase {
  public:
-  PrintWebViewHelperTest() {}
-  ~PrintWebViewHelperTest() override {}
+  MAYBE_PrintWebViewHelperTest() {}
+  ~MAYBE_PrintWebViewHelperTest() override {}
 
   void SetUp() override { PrintWebViewHelperTestBase::SetUp(); }
 
  protected:
-  DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTest);
+  DISALLOW_COPY_AND_ASSIGN(MAYBE_PrintWebViewHelperTest);
 };
 
 // This tests only for platforms without print preview.
 #if !defined(ENABLE_PRINT_PREVIEW)
 // Tests that the renderer blocks window.print() calls if they occur too
 // frequently.
-TEST_F(PrintWebViewHelperTest, BlockScriptInitiatedPrinting) {
+TEST_F(MAYBE_PrintWebViewHelperTest, BlockScriptInitiatedPrinting) {
   // Pretend user will cancel printing.
   print_render_thread_->set_print_dialog_user_response(false);
   // Try to print with window.print() a few times.
@@ -287,7 +295,7 @@
 
 // Tests that the renderer always allows window.print() calls if they are user
 // initiated.
-TEST_F(PrintWebViewHelperTest, AllowUserOriginatedPrinting) {
+TEST_F(MAYBE_PrintWebViewHelperTest, AllowUserOriginatedPrinting) {
   // Pretend user will cancel printing.
   print_render_thread_->set_print_dialog_user_response(false);
   // Try to print with window.print() a few times.
@@ -325,7 +333,7 @@
 }
 
 // Duplicate of OnPrintPagesTest only using javascript to print.
-TEST_F(PrintWebViewHelperTest, PrintWithJavascript) {
+TEST_F(MAYBE_PrintWebViewHelperTest, PrintWithJavascript) {
   PrintWithJavaScript();
 
   VerifyPageCount(1);
@@ -336,7 +344,7 @@
 #if defined(ENABLE_BASIC_PRINTING)
 // Tests that printing pages work and sending and receiving messages through
 // that channel all works.
-TEST_F(PrintWebViewHelperTest, OnPrintPages) {
+TEST_F(MAYBE_PrintWebViewHelperTest, OnPrintPages) {
   LoadHTML(kHelloWorldHTML);
   OnPrintPages();
 
@@ -350,7 +358,7 @@
 // to rip out and replace most of the IPC code if we ever plan to improve
 // printing, and the comment below by sverrir suggests that it doesn't do much
 // for us anyway.
-TEST_F(PrintWebViewHelperTest, PrintWithIframe) {
+TEST_F(MAYBE_PrintWebViewHelperTest, PrintWithIframe) {
   // Document that populates an iframe.
   const char html[] =
       "<html><body>Lorem Ipsum:"
@@ -440,7 +448,7 @@
 // metafile directly.
 // Same for printing via PDF on Windows.
 #if defined(OS_MACOSX) && defined(ENABLE_BASIC_PRINTING)
-TEST_F(PrintWebViewHelperTest, PrintLayoutTest) {
+TEST_F(MAYBE_PrintWebViewHelperTest, PrintLayoutTest) {
   bool baseline = false;
 
   EXPECT_TRUE(print_render_thread_->printer() != NULL);
@@ -496,10 +504,20 @@
 
 // These print preview tests do not work on Chrome OS yet.
 #if !defined(OS_CHROMEOS)
-class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
+
+// RenderVIewTest-based tests crash on Android
+// http://crbug.com/187500
+#if defined(OS_ANDROID)
+#define MAYBE_PrintWebViewHelperPreviewTest \
+  DISABLED_PrintWebViewHelperPreviewTest
+#else
+#define MAYBE_PrintWebViewHelperPreviewTest PrintWebViewHelperPreviewTest
+#endif  // defined(OS_ANDROID)
+
+class MAYBE_PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
  public:
-  PrintWebViewHelperPreviewTest() {}
-  ~PrintWebViewHelperPreviewTest() override {}
+  MAYBE_PrintWebViewHelperPreviewTest() {}
+  ~MAYBE_PrintWebViewHelperPreviewTest() override {}
 
  protected:
   void VerifyPrintPreviewCancelled(bool did_cancel) {
@@ -591,11 +609,11 @@
     }
   }
 
-  DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest);
+  DISALLOW_COPY_AND_ASSIGN(MAYBE_PrintWebViewHelperPreviewTest);
 };
 
 #if defined(ENABLE_PRINT_PREVIEW)
-TEST_F(PrintWebViewHelperPreviewTest, BlockScriptInitiatedPrinting) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, BlockScriptInitiatedPrinting) {
   LoadHTML(kHelloWorldHTML);
   PrintWebViewHelper* print_web_view_helper = PrintWebViewHelper::Get(view_);
   print_web_view_helper->SetScriptedPrintBlocked(true);
@@ -607,7 +625,7 @@
   VerifyPreviewRequest(true);
 }
 
-TEST_F(PrintWebViewHelperPreviewTest, PrintWithJavaScript) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, PrintWithJavaScript) {
   LoadHTML(kPrintOnUserAction);
   gfx::Size new_size(200, 100);
   Resize(new_size, gfx::Rect(), false);
@@ -630,7 +648,7 @@
 
 // Tests that print preview work and sending and receiving messages through
 // that channel all works.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintPreview) {
   LoadHTML(kHelloWorldHTML);
 
   // Fill in some dummy values.
@@ -646,7 +664,8 @@
   VerifyPagesPrinted(false);
 }
 
-TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewHTMLWithPageMarginsCss) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
+       PrintPreviewHTMLWithPageMarginsCss) {
   // A simple web page with print margins css.
   const char kHTMLWithPageMarginsCss[] =
       "<html><head><style>"
@@ -677,7 +696,8 @@
 
 // Test to verify that print preview ignores print media css when non-default
 // margin is selected.
-TEST_F(PrintWebViewHelperPreviewTest, NonDefaultMarginsSelectedIgnorePrintCss) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
+       NonDefaultMarginsSelectedIgnorePrintCss) {
   LoadHTML(kHTMLWithPageSizeCss);
 
   // Fill in some dummy values.
@@ -697,7 +717,7 @@
 
 // Test to verify that print preview honor print media size css when
 // PRINT_TO_PDF is selected and doesn't fit to printer default paper size.
-TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPrintCss) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPrintCss) {
   LoadHTML(kHTMLWithPageSizeCss);
 
   // Fill in some dummy values.
@@ -717,7 +737,8 @@
 
 // Test to verify that print preview honor print margin css when PRINT_TO_PDF
 // is selected and doesn't fit to printer default paper size.
-TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPageMarginsCss) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
+       PrintToPDFSelectedHonorPageMarginsCss) {
   // A simple web page with print margins css.
   const char kHTMLWithPageCss[] =
       "<html><head><style>"
@@ -749,7 +770,7 @@
 
 // Test to verify that print preview workflow center the html page contents to
 // fit the page size.
-TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewCenterToFitPage) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, PrintPreviewCenterToFitPage) {
   LoadHTML(kHTMLWithPageSizeCss);
 
   // Fill in some dummy values.
@@ -768,7 +789,7 @@
 
 // Test to verify that print preview workflow scale the html page contents to
 // fit the page size.
-TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewShrinkToFitPage) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, PrintPreviewShrinkToFitPage) {
   // A simple web page with print margins css.
   const char kHTMLWithPageCss[] =
       "<html><head><style>"
@@ -797,7 +818,7 @@
 
 // Test to verify that print preview workflow honor the orientation settings
 // specified in css.
-TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewHonorsOrientationCss) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, PrintPreviewHonorsOrientationCss) {
   LoadHTML(kHTMLWithLandscapePageCss);
 
   // Fill in some dummy values.
@@ -815,7 +836,8 @@
 
 // Test to verify that print preview workflow honors the orientation settings
 // specified in css when PRINT_TO_PDF is selected.
-TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorOrientationCss) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
+       PrintToPDFSelectedHonorOrientationCss) {
   LoadHTML(kHTMLWithLandscapePageCss);
 
   // Fill in some dummy values.
@@ -833,7 +855,7 @@
 
 // Test to verify that complete metafile is generated for a subset of pages
 // without creating draft pages.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedPages) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedPages) {
   LoadHTML(kMultipageHTML);
 
   // Fill in some dummy values.
@@ -866,7 +888,7 @@
 }
 
 // Test to verify that preview generated only for one page.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedText) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedText) {
   LoadHTML(kMultipageHTML);
   GetMainFrame()->selectRange(
       blink::WebRange::fromDocumentRange(GetMainFrame(), 1, 3));
@@ -887,7 +909,7 @@
 
 // Tests that print preview fails and receiving error messages through
 // that channel all works.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewFail) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintPreviewFail) {
   LoadHTML(kHelloWorldHTML);
 
   // An empty dictionary should fail.
@@ -902,7 +924,7 @@
 }
 
 // Tests that cancelling print preview works.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) {
   LoadHTML(kLongPageHTML);
 
   const int kCancelPage = 3;
@@ -921,7 +943,7 @@
 
 // Tests that printing from print preview works and sending and receiving
 // messages through that channel all works.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintForPrintPreview) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintForPrintPreview) {
   LoadHTML(kPrintPreviewHTML);
 
   // Fill in some dummy values.
@@ -935,7 +957,7 @@
 
 // Tests that printing from print preview fails and receiving error messages
 // through that channel all works.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintForPrintPreviewFail) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest, OnPrintForPrintPreviewFail) {
   LoadHTML(kPrintPreviewHTML);
 
   // An empty dictionary should fail.
@@ -947,7 +969,7 @@
 
 // Tests that when default printer has invalid printer settings, print preview
 // receives error message.
-TEST_F(PrintWebViewHelperPreviewTest,
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
        OnPrintPreviewUsingInvalidPrinterSettings) {
   LoadHTML(kPrintPreviewHTML);
 
@@ -970,7 +992,8 @@
 
 // Tests that when the selected printer has invalid page settings, print preview
 // receives error message.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewUsingInvalidPageSize) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
+       OnPrintPreviewUsingInvalidPageSize) {
   LoadHTML(kPrintPreviewHTML);
 
   print_render_thread_->printer()->UseInvalidPageSize();
@@ -989,7 +1012,8 @@
 
 // Tests that when the selected printer has invalid content settings, print
 // preview receives error message.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewUsingInvalidContentSize) {
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
+       OnPrintPreviewUsingInvalidContentSize) {
   LoadHTML(kPrintPreviewHTML);
 
   print_render_thread_->printer()->UseInvalidContentSize();
@@ -1006,7 +1030,7 @@
   VerifyPrintPreviewGenerated(false);
 }
 
-TEST_F(PrintWebViewHelperPreviewTest,
+TEST_F(MAYBE_PrintWebViewHelperPreviewTest,
        OnPrintForPrintPreviewUsingInvalidPrinterSettings) {
   LoadHTML(kPrintPreviewHTML);
 
diff --git a/components/proximity_auth.gypi b/components/proximity_auth.gypi
index c4e2503..7da4644c 100644
--- a/components/proximity_auth.gypi
+++ b/components/proximity_auth.gypi
@@ -23,6 +23,8 @@
         "proximity_auth/bluetooth_util.cc",
         "proximity_auth/bluetooth_util.h",
         "proximity_auth/bluetooth_util_chromeos.cc",
+        "proximity_auth/ble/proximity_auth_ble_system.cc",
+        "proximity_auth/ble/proximity_auth_ble_system.h",
         "proximity_auth/client.cc",
         "proximity_auth/client.h",
         "proximity_auth/client_observer.h",
diff --git a/components/proximity_auth/ble/BUILD.gn b/components/proximity_auth/ble/BUILD.gn
new file mode 100644
index 0000000..db2d0db
--- /dev/null
+++ b/components/proximity_auth/ble/BUILD.gn
@@ -0,0 +1,17 @@
+# 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("ble") {
+  sources = [
+    "proximity_auth_ble_system.cc",
+    "proximity_auth_ble_system.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/proximity_auth",
+    "//device/bluetooth",
+    "//net",
+  ]
+}
diff --git a/components/proximity_auth/ble/OWNERS b/components/proximity_auth/ble/OWNERS
new file mode 100644
index 0000000..e0920d6
--- /dev/null
+++ b/components/proximity_auth/ble/OWNERS
@@ -0,0 +1,2 @@
+msarda@chromium.org
+sacomoto@chromium.org
diff --git a/components/proximity_auth/ble/proximity_auth_ble_system.cc b/components/proximity_auth/ble/proximity_auth_ble_system.cc
new file mode 100644
index 0000000..b4f20e4
--- /dev/null
+++ b/components/proximity_auth/ble/proximity_auth_ble_system.cc
@@ -0,0 +1,19 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/proximity_auth/ble/proximity_auth_ble_system.h"
+
+#include "base/logging.h"
+
+namespace proximity_auth {
+
+ProximityAuthBleSystem::ProximityAuthBleSystem() {
+  VLOG(1) << "Starting Proximity Auth over Bluetooth Low Energy.";
+}
+
+ProximityAuthBleSystem::~ProximityAuthBleSystem() {
+  VLOG(1) << "Stopping Proximity over Bluetooth Low Energy.";
+}
+
+}  // namespace proximity_auth
diff --git a/components/proximity_auth/ble/proximity_auth_ble_system.h b/components/proximity_auth/ble/proximity_auth_ble_system.h
new file mode 100644
index 0000000..ab59bae
--- /dev/null
+++ b/components/proximity_auth/ble/proximity_auth_ble_system.h
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_
+#define COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_
+
+#include "base/macros.h"
+
+namespace proximity_auth {
+
+// This is the main entry point to start Proximity Auth over Bluetooth Low
+// Energy. This is the underlying system for the Smart Lock features. It will
+// discover Bluetooth Low Energy phones and unlock the lock screen if the phone
+// passes an authorization and authentication protocol.
+class ProximityAuthBleSystem {
+ public:
+  ProximityAuthBleSystem();
+  ~ProximityAuthBleSystem();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProximityAuthBleSystem);
+};
+
+}  // namespace proximity_auth
+
+#endif  // COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_
diff --git a/components/proximity_auth/switches.cc b/components/proximity_auth/switches.cc
index 5e63e9b0..9d1577fe 100644
--- a/components/proximity_auth/switches.cc
+++ b/components/proximity_auth/switches.cc
@@ -14,6 +14,10 @@
 // Disable Easy unlock.
 const char kDisableEasyUnlock[] = "disable-easy-unlock";
 
+// Enables discovery of the phone over Bluetooth Low Energy.
+const char kEnableBluetoothLowEnergyDiscovery[] =
+    "enable-proximity-auth-bluetooth-low-energy-discovery";
+
 // Enables close proximity detection. This allows the user to set a setting to
 // require very close proximity between the remote device and the local device
 // in order to unlock the local device, which trades off convenience for
diff --git a/components/proximity_auth/switches.h b/components/proximity_auth/switches.h
index 04f6162..b58cb5e7 100644
--- a/components/proximity_auth/switches.h
+++ b/components/proximity_auth/switches.h
@@ -12,6 +12,7 @@
 // alongside the definition of their values in the .cc file.
 extern const char kCryptAuthHTTPHost[];
 extern const char kDisableEasyUnlock[];
+extern const char kEnableBluetoothLowEnergyDiscovery[];
 extern const char kEnableProximityDetection[];
 extern const char kForceLoadEasyUnlockAppInTests[];
 
diff --git a/components/scheduler/BUILD.gn b/components/scheduler/BUILD.gn
new file mode 100644
index 0000000..2d00aef
--- /dev/null
+++ b/components/scheduler/BUILD.gn
@@ -0,0 +1,56 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//components/scheduler/scheduler.gni")
+
+# GYP version: components/scheduler.gypi:scheduler
+component("scheduler") {
+  sources = rebase_path(scheduler_gypi_values.scheduler_sources,
+                        ".",
+                        "//components/scheduler")
+
+  defines = [ "SCHEDULER_IMPLEMENTATION" ]
+
+  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+  deps = [
+    ":common",
+    "//base",
+    "//cc:cc",
+    "//third_party/WebKit/public:blink",
+    "//ui/gfx:gfx",
+  ]
+}
+
+# GYP version: components/scheduler.gypi:scheduler_common
+source_set("common") {
+  sources = rebase_path(scheduler_gypi_values.scheduler_common_sources,
+                        ".",
+                        "//components/scheduler")
+}
+
+source_set("unit_tests") {
+  testonly = true
+
+  sources = [
+    "child/nestable_task_runner_for_test.cc",
+    "child/nestable_task_runner_for_test.h",
+    "child/prioritizing_task_queue_selector_unittest.cc",
+    "child/scheduler_helper_unittest.cc",
+    "child/task_queue_manager_unittest.cc",
+    "child/test_time_source.cc",
+    "child/test_time_source.h",
+    "child/worker_scheduler_impl_unittest.cc",
+    "renderer/deadline_task_runner_unittest.cc",
+    "renderer/renderer_scheduler_impl_unittest.cc",
+  ]
+
+  deps = [
+    ":scheduler",
+    "//cc:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/scheduler/DEPS b/components/scheduler/DEPS
new file mode 100644
index 0000000..a298a17
--- /dev/null
+++ b/components/scheduler/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "-components/scheduler",
+  "+components/scheduler/common",
+]
diff --git a/content/child/scheduler/OWNERS b/components/scheduler/OWNERS
similarity index 100%
rename from content/child/scheduler/OWNERS
rename to components/scheduler/OWNERS
diff --git a/components/scheduler/child/DEPS b/components/scheduler/child/DEPS
new file mode 100644
index 0000000..f4ac360
--- /dev/null
+++ b/components/scheduler/child/DEPS
@@ -0,0 +1,12 @@
+include_rules = [
+  "+components/scheduler/common",
+  "+components/scheduler/scheduler_export.h",
+  "+third_party/WebKit/public/platform",
+]
+
+specific_include_rules = {
+  "(test_time_source|.*test)\.cc": [
+    "+cc/test",
+    "+content/test",
+  ],
+}
diff --git a/content/child/scheduler/OWNERS b/components/scheduler/child/OWNERS
similarity index 100%
copy from content/child/scheduler/OWNERS
copy to components/scheduler/child/OWNERS
diff --git a/content/child/scheduler/cancelable_closure_holder.cc b/components/scheduler/child/cancelable_closure_holder.cc
similarity index 85%
rename from content/child/scheduler/cancelable_closure_holder.cc
rename to components/scheduler/child/cancelable_closure_holder.cc
index 09e688d..0e1660a 100644
--- a/content/child/scheduler/cancelable_closure_holder.cc
+++ b/components/scheduler/child/cancelable_closure_holder.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/child/scheduler/cancelable_closure_holder.h"
+#include "components/scheduler/child/cancelable_closure_holder.h"
 
-namespace content {
+namespace scheduler {
 
 CancelableClosureHolder::CancelableClosureHolder() {
 }
@@ -27,4 +27,4 @@
   return cancelable_callback_.callback();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/cancelable_closure_holder.h b/components/scheduler/child/cancelable_closure_holder.h
similarity index 80%
rename from content/child/scheduler/cancelable_closure_holder.h
rename to components/scheduler/child/cancelable_closure_holder.h
index 1e3892cc..20968a4 100644
--- a/content/child/scheduler/cancelable_closure_holder.h
+++ b/components/scheduler/child/cancelable_closure_holder.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_CHILD_SCHEDULER_CANCELABLE_CLOSURE_HOLDER_H_
-#define CONTENT_CHILD_SCHEDULER_CANCELABLE_CLOSURE_HOLDER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_CANCELABLE_CLOSURE_HOLDER_H_
+#define COMPONENTS_SCHEDULER_CHILD_CANCELABLE_CLOSURE_HOLDER_H_
 
 #include "base/cancelable_callback.h"
 
-namespace content {
+namespace scheduler {
 
 // A CancelableClosureHolder is a CancelableCallback which resets its wrapped
 // callback with a cached closure whenever it is canceled.
@@ -34,6 +34,6 @@
   DISALLOW_COPY_AND_ASSIGN(CancelableClosureHolder);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_CANCELABLE_CLOSURE_HOLDER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_CANCELABLE_CLOSURE_HOLDER_H_
diff --git a/content/child/scheduler/child_scheduler.h b/components/scheduler/child/child_scheduler.h
similarity index 84%
rename from content/child/scheduler/child_scheduler.h
rename to components/scheduler/child/child_scheduler.h
index 308dc1c..8fd5359 100644
--- a/content/child/scheduler/child_scheduler.h
+++ b/components/scheduler/child/child_scheduler.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_CHILD_SCHEDULER_H_
-#define CONTENT_CHILD_SCHEDULER_CHILD_SCHEDULER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_CHILD_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_CHILD_CHILD_SCHEDULER_H_
 
 #include "base/message_loop/message_loop.h"
-#include "content/child/scheduler/single_thread_idle_task_runner.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
+#include "components/scheduler/scheduler_export.h"
 
 namespace base {
 class MessageLoop;
 }
 
-namespace content {
+namespace scheduler {
 
-class CONTENT_EXPORT ChildScheduler {
+class SCHEDULER_EXPORT ChildScheduler {
  public:
-  virtual ~ChildScheduler() { }
+  virtual ~ChildScheduler() {}
 
   // Returns the default task runner.
   virtual scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() = 0;
@@ -58,10 +58,10 @@
   virtual void Shutdown() = 0;
 
  protected:
-  ChildScheduler() { }
+  ChildScheduler() {}
   DISALLOW_COPY_AND_ASSIGN(ChildScheduler);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_CHILD_SCHEDULER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_CHILD_SCHEDULER_H_
diff --git a/content/child/scheduler/nestable_single_thread_task_runner.h b/components/scheduler/child/nestable_single_thread_task_runner.h
similarity index 63%
rename from content/child/scheduler/nestable_single_thread_task_runner.h
rename to components/scheduler/child/nestable_single_thread_task_runner.h
index dbacaf8..e1bf990 100644
--- a/content/child/scheduler/nestable_single_thread_task_runner.h
+++ b/components/scheduler/child/nestable_single_thread_task_runner.h
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
-#define CONTENT_CHILD_SCHEDULER_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
+#define COMPONENTS_SCHEDULER_CHILD_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
 
 #include "base/single_thread_task_runner.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/scheduler_export.h"
 
-namespace content {
+namespace scheduler {
 
 // A single thread task runner which exposes whether it is running nested.
-class CONTENT_EXPORT NestableSingleThreadTaskRunner
+class SCHEDULER_EXPORT NestableSingleThreadTaskRunner
     : public base::SingleThreadTaskRunner {
  public:
   NestableSingleThreadTaskRunner() {}
@@ -26,6 +26,6 @@
   DISALLOW_COPY_AND_ASSIGN(NestableSingleThreadTaskRunner);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
diff --git a/content/child/scheduler/nestable_task_runner_for_test.cc b/components/scheduler/child/nestable_task_runner_for_test.cc
similarity index 91%
rename from content/child/scheduler/nestable_task_runner_for_test.cc
rename to components/scheduler/child/nestable_task_runner_for_test.cc
index abab53bb..42e1264d 100644
--- a/content/child/scheduler/nestable_task_runner_for_test.cc
+++ b/components/scheduler/child/nestable_task_runner_for_test.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/child/scheduler/nestable_task_runner_for_test.h"
+#include "components/scheduler/child/nestable_task_runner_for_test.h"
 
-namespace content {
+namespace scheduler {
 
 // static
 scoped_refptr<NestableTaskRunnerForTest> NestableTaskRunnerForTest::Create(
@@ -46,4 +46,4 @@
   is_nested_ = is_nested;
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/nestable_task_runner_for_test.h b/components/scheduler/child/nestable_task_runner_for_test.h
similarity index 91%
rename from content/child/scheduler/nestable_task_runner_for_test.h
rename to components/scheduler/child/nestable_task_runner_for_test.h
index c9b9b96..69056204 100644
--- a/content/child/scheduler/nestable_task_runner_for_test.h
+++ b/components/scheduler/child/nestable_task_runner_for_test.h
@@ -5,9 +5,9 @@
 #ifndef CONTENT_RENDERER_SCHEDULER_NESTABLE_TASK_RUNNER_FOR_TEST_H_
 #define CONTENT_RENDERER_SCHEDULER_NESTABLE_TASK_RUNNER_FOR_TEST_H_
 
-#include "content/child/scheduler/nestable_single_thread_task_runner.h"
+#include "components/scheduler/child/nestable_single_thread_task_runner.h"
 
-namespace content {
+namespace scheduler {
 
 class NestableTaskRunnerForTest : public NestableSingleThreadTaskRunner {
  public:
@@ -39,6 +39,6 @@
   DISALLOW_COPY_AND_ASSIGN(NestableTaskRunnerForTest);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
 #endif  // CONTENT_RENDERER_SCHEDULER_NESTABLE_TASK_RUNNER_FOR_TEST_H_
diff --git a/content/child/scheduler/null_idle_task_runner.cc b/components/scheduler/child/null_idle_task_runner.cc
similarity index 80%
rename from content/child/scheduler/null_idle_task_runner.cc
rename to components/scheduler/child/null_idle_task_runner.cc
index 08818ce..9d11e7c 100644
--- a/content/child/scheduler/null_idle_task_runner.cc
+++ b/components/scheduler/child/null_idle_task_runner.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/child/scheduler/null_idle_task_runner.h"
+#include "components/scheduler/child/null_idle_task_runner.h"
 
-namespace content {
+namespace scheduler {
 
 NullIdleTaskRunner::NullIdleTaskRunner()
     : SingleThreadIdleTaskRunner(nullptr,
@@ -27,8 +27,8 @@
 }
 
 void NullIdleTaskRunner::PostIdleTaskAfterWakeup(
-  const tracked_objects::Location& from_here,
-  const IdleTask& idle_task) {
+    const tracked_objects::Location& from_here,
+    const IdleTask& idle_task) {
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/components/scheduler/child/null_idle_task_runner.h b/components/scheduler/child/null_idle_task_runner.h
new file mode 100644
index 0000000..734d0c1
--- /dev/null
+++ b/components/scheduler/child/null_idle_task_runner.h
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_CHILD_NULL_IDLE_TASK_RUNNER_H_
+#define COMPONENTS_SCHEDULER_CHILD_NULL_IDLE_TASK_RUNNER_H_
+
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
+
+namespace scheduler {
+
+class NullIdleTaskRunner : public SingleThreadIdleTaskRunner {
+ public:
+  NullIdleTaskRunner();
+  void PostIdleTask(const tracked_objects::Location& from_here,
+                    const IdleTask& idle_task) override;
+
+  void PostNonNestableIdleTask(const tracked_objects::Location& from_here,
+                               const IdleTask& idle_task) override;
+
+  void PostIdleTaskAfterWakeup(const tracked_objects::Location& from_here,
+                               const IdleTask& idle_task) override;
+
+ protected:
+  ~NullIdleTaskRunner() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NullIdleTaskRunner);
+};
+
+}  // namespace scheduler
+
+#endif  // COMPONENTS_SCHEDULER_CHILD_NULL_IDLE_TASK_RUNNER_H_
diff --git a/content/child/scheduler/null_worker_scheduler.cc b/components/scheduler/child/null_worker_scheduler.cc
similarity index 78%
rename from content/child/scheduler/null_worker_scheduler.cc
rename to components/scheduler/child/null_worker_scheduler.cc
index 3127c3f1..4abfb0e 100644
--- a/content/child/scheduler/null_worker_scheduler.cc
+++ b/components/scheduler/child/null_worker_scheduler.cc
@@ -2,16 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/null_worker_scheduler.h"
+#include "components/scheduler/child/null_worker_scheduler.h"
 
 #include "base/bind.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "content/child/scheduler/null_idle_task_runner.h"
+#include "base/message_loop/message_loop.h"
+#include "base/thread_task_runner_handle.h"
+#include "components/scheduler/child/null_idle_task_runner.h"
 
-namespace content {
+namespace scheduler {
 
 NullWorkerScheduler::NullWorkerScheduler()
-    : task_runner_(base::MessageLoopProxy::current()),
+    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
       idle_task_runner_(new NullIdleTaskRunner()) {
 }
 
@@ -52,4 +53,4 @@
 void NullWorkerScheduler::Shutdown() {
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/null_worker_scheduler.h b/components/scheduler/child/null_worker_scheduler.h
similarity index 76%
rename from content/child/scheduler/null_worker_scheduler.h
rename to components/scheduler/child/null_worker_scheduler.h
index a03d6b2..535fa08 100644
--- a/content/child/scheduler/null_worker_scheduler.h
+++ b/components/scheduler/child/null_worker_scheduler.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_CHILD_SCHEDULER_NULL_WORKER_SCHEDULER_H_
-#define CONTENT_CHILD_SCHEDULER_NULL_WORKER_SCHEDULER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_NULL_WORKER_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_CHILD_NULL_WORKER_SCHEDULER_H_
 
-#include "content/child/scheduler/worker_scheduler.h"
+#include "components/scheduler/child/worker_scheduler.h"
 
-namespace content {
+namespace scheduler {
 
 class NullWorkerScheduler : public WorkerScheduler {
  public:
@@ -32,6 +32,6 @@
   DISALLOW_COPY_AND_ASSIGN(NullWorkerScheduler);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_NULL_WORKER_SCHEDULER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_NULL_WORKER_SCHEDULER_H_
diff --git a/content/child/scheduler/prioritizing_task_queue_selector.cc b/components/scheduler/child/prioritizing_task_queue_selector.cc
similarity index 97%
rename from content/child/scheduler/prioritizing_task_queue_selector.cc
rename to components/scheduler/child/prioritizing_task_queue_selector.cc
index 193e81ff..5275f72 100644
--- a/content/child/scheduler/prioritizing_task_queue_selector.cc
+++ b/components/scheduler/child/prioritizing_task_queue_selector.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/prioritizing_task_queue_selector.h"
+#include "components/scheduler/child/prioritizing_task_queue_selector.h"
 
 #include "base/logging.h"
 #include "base/pending_task.h"
 #include "base/trace_event/trace_event_argument.h"
 
-namespace content {
+namespace scheduler {
 
 PrioritizingTaskQueueSelector::PrioritizingTaskQueueSelector()
     : starvation_count_(0), task_queue_selector_observer_(nullptr) {
@@ -189,4 +189,4 @@
   task_queue_selector_observer_ = observer;
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/prioritizing_task_queue_selector.h b/components/scheduler/child/prioritizing_task_queue_selector.h
similarity index 90%
rename from content/child/scheduler/prioritizing_task_queue_selector.h
rename to components/scheduler/child/prioritizing_task_queue_selector.h
index 936f2ae..a9a63eb 100644
--- a/content/child/scheduler/prioritizing_task_queue_selector.h
+++ b/components/scheduler/child/prioritizing_task_queue_selector.h
@@ -2,21 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
-#define CONTENT_CHILD_SCHEDULER_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
+#define COMPONENTS_SCHEDULER_CHILD_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
 
 #include <set>
 
 #include "base/compiler_specific.h"
 #include "base/threading/thread_checker.h"
-#include "content/child/scheduler/task_queue_selector.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/child/task_queue_selector.h"
+#include "components/scheduler/scheduler_export.h"
 
-namespace content {
+namespace scheduler {
 
 // A PrioritizingTaskQueueSelector is a TaskQueueSelector which is used by the
 // SchedulerHelper to enable prioritization of particular task queues.
-class CONTENT_EXPORT PrioritizingTaskQueueSelector
+class SCHEDULER_EXPORT PrioritizingTaskQueueSelector
     : NON_EXPORTED_BASE(public TaskQueueSelector) {
  public:
   enum QueuePriority {
@@ -103,6 +103,6 @@
   DISALLOW_COPY_AND_ASSIGN(PrioritizingTaskQueueSelector);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
diff --git a/content/child/scheduler/prioritizing_task_queue_selector_unittest.cc b/components/scheduler/child/prioritizing_task_queue_selector_unittest.cc
similarity index 97%
rename from content/child/scheduler/prioritizing_task_queue_selector_unittest.cc
rename to components/scheduler/child/prioritizing_task_queue_selector_unittest.cc
index f055f3d..81a2a945 100644
--- a/content/child/scheduler/prioritizing_task_queue_selector_unittest.cc
+++ b/components/scheduler/child/prioritizing_task_queue_selector_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/prioritizing_task_queue_selector.h"
+#include "components/scheduler/child/prioritizing_task_queue_selector.h"
 
 #include "base/bind.h"
 #include "base/memory/scoped_ptr.h"
@@ -11,10 +11,9 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace content {
+namespace scheduler {
 
-class MockObserver
-    : public TaskQueueSelector::Observer {
+class MockObserver : public TaskQueueSelector::Observer {
  public:
   MockObserver() {}
   virtual ~MockObserver() {}
@@ -246,4 +245,4 @@
   }
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/scheduler_helper.cc b/components/scheduler/child/scheduler_helper.cc
similarity index 94%
rename from content/child/scheduler/scheduler_helper.cc
rename to components/scheduler/child/scheduler_helper.cc
index 91f4abbd..19e8d2b6 100644
--- a/content/child/scheduler/scheduler_helper.cc
+++ b/components/scheduler/child/scheduler_helper.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/scheduler_helper.h"
+#include "components/scheduler/child/scheduler_helper.h"
 
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
-#include "content/child/scheduler/nestable_single_thread_task_runner.h"
-#include "content/child/scheduler/prioritizing_task_queue_selector.h"
-#include "content/child/scheduler/time_source.h"
+#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/child/prioritizing_task_queue_selector.h"
+#include "components/scheduler/child/time_source.h"
 
-namespace content {
+namespace scheduler {
 
 SchedulerHelper::SchedulerHelper(
     scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
@@ -204,8 +204,7 @@
       ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay);
   if (IsInIdlePeriod(new_idle_period_state)) {
     StartIdlePeriod(new_idle_period_state, now,
-                    now + next_long_idle_period_delay,
-                    false);
+                    now + next_long_idle_period_delay, false);
   }
 
   if (task_queue_manager_->IsQueueEmpty(QueueId::IDLE_TASK_QUEUE)) {
@@ -264,10 +263,9 @@
 
   idle_period_deadline_ = idle_period_deadline;
   if (post_end_idle_period) {
-    control_task_runner_->PostDelayedTask(
-        FROM_HERE,
-        end_idle_period_closure_.callback(),
-        idle_period_deadline_ - now);
+    control_task_runner_->PostDelayedTask(FROM_HERE,
+                                          end_idle_period_closure_.callback(),
+                                          idle_period_deadline_ - now);
   }
 }
 
@@ -333,13 +331,13 @@
   return time_source_->Now();
 }
 
-SchedulerHelper::IdlePeriodState
-SchedulerHelper::SchedulerIdlePeriodState() const {
+SchedulerHelper::IdlePeriodState SchedulerHelper::SchedulerIdlePeriodState()
+    const {
   return idle_period_state_;
 }
 
-PrioritizingTaskQueueSelector*
-SchedulerHelper::SchedulerTaskQueueSelector() const {
+PrioritizingTaskQueueSelector* SchedulerHelper::SchedulerTaskQueueSelector()
+    const {
   return task_queue_selector_.get();
 }
 
@@ -410,4 +408,4 @@
     task_queue_manager_->RemoveTaskObserver(task_observer);
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/scheduler_helper.h b/components/scheduler/child/scheduler_helper.h
similarity index 92%
rename from content/child/scheduler/scheduler_helper.h
rename to components/scheduler/child/scheduler_helper.h
index 0e03aa9..7ace694 100644
--- a/content/child/scheduler/scheduler_helper.h
+++ b/components/scheduler/child/scheduler_helper.h
@@ -2,24 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_SCHEDULER_HELPER_H_
-#define CONTENT_CHILD_SCHEDULER_SCHEDULER_HELPER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_SCHEDULER_HELPER_H_
+#define COMPONENTS_SCHEDULER_CHILD_SCHEDULER_HELPER_H_
 
-#include "content/child/scheduler/cancelable_closure_holder.h"
-#include "content/child/scheduler/single_thread_idle_task_runner.h"
-#include "content/child/scheduler/task_queue_manager.h"
-#include "content/child/scheduler/time_source.h"
+#include "components/scheduler/child/cancelable_closure_holder.h"
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
+#include "components/scheduler/child/task_queue_manager.h"
+#include "components/scheduler/child/time_source.h"
+#include "components/scheduler/scheduler_export.h"
 
-namespace content {
+namespace scheduler {
 
 class PrioritizingTaskQueueSelector;
 class NestableSingleThreadTaskRunner;
 
 // Common scheduler functionality for Default and Idle tasks.
-class CONTENT_EXPORT SchedulerHelper {
+class SCHEDULER_EXPORT SchedulerHelper {
  public:
   // Used to by scheduler implementations to customize idle behaviour.
-  class CONTENT_EXPORT SchedulerHelperDelegate {
+  class SCHEDULER_EXPORT SchedulerHelperDelegate {
    public:
     SchedulerHelperDelegate();
     virtual ~SchedulerHelperDelegate();
@@ -209,6 +210,6 @@
   DISALLOW_COPY_AND_ASSIGN(SchedulerHelper);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_SCHEDULER_HELPER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_SCHEDULER_HELPER_H_
diff --git a/content/child/scheduler/scheduler_helper_unittest.cc b/components/scheduler/child/scheduler_helper_unittest.cc
similarity index 88%
rename from content/child/scheduler/scheduler_helper_unittest.cc
rename to components/scheduler/child/scheduler_helper_unittest.cc
index d3e9bda..0418c0be 100644
--- a/content/child/scheduler/scheduler_helper_unittest.cc
+++ b/components/scheduler/child/scheduler_helper_unittest.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/scheduler_helper.h"
+#include "components/scheduler/child/scheduler_helper.h"
 
 #include "base/callback.h"
 #include "cc/test/ordered_simple_task_runner.h"
 #include "cc/test/test_now_source.h"
-#include "content/child/scheduler/nestable_task_runner_for_test.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/child/scheduler/task_queue_manager.h"
-#include "content/test/test_time_source.h"
+#include "components/scheduler/child/nestable_task_runner_for_test.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/task_queue_manager.h"
+#include "components/scheduler/child/test_time_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -19,7 +19,7 @@
 using testing::Invoke;
 using testing::Return;
 
-namespace content {
+namespace scheduler {
 
 namespace {
 void AppendToVectorTestTask(std::vector<std::string>* vector,
@@ -36,17 +36,16 @@
 void NullTask() {
 }
 
-void AppendToVectorReentrantTask(
-    base::SingleThreadTaskRunner* task_runner,
-    std::vector<int>* vector,
-    int* reentrant_count,
-    int max_reentrant_count) {
+void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner,
+                                 std::vector<int>* vector,
+                                 int* reentrant_count,
+                                 int max_reentrant_count) {
   vector->push_back((*reentrant_count)++);
   if (*reentrant_count < max_reentrant_count) {
     task_runner->PostTask(
-        FROM_HERE, base::Bind(AppendToVectorReentrantTask,
-                              base::Unretained(task_runner), vector,
-                              reentrant_count, max_reentrant_count));
+        FROM_HERE,
+        base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner),
+                   vector, reentrant_count, max_reentrant_count));
   }
 }
 
@@ -62,15 +61,13 @@
 
 int max_idle_task_reposts = 2;
 
-void RepostingIdleTestTask(
-    SingleThreadIdleTaskRunner* idle_task_runner,
-    int* run_count,
-    base::TimeTicks deadline) {
+void RepostingIdleTestTask(SingleThreadIdleTaskRunner* idle_task_runner,
+                           int* run_count,
+                           base::TimeTicks deadline) {
   if ((*run_count + 1) < max_idle_task_reposts) {
     idle_task_runner->PostIdleTask(
-        FROM_HERE,
-        base::Bind(&RepostingIdleTestTask,
-                   base::Unretained(idle_task_runner), run_count));
+        FROM_HERE, base::Bind(&RepostingIdleTestTask,
+                              base::Unretained(idle_task_runner), run_count));
   }
   (*run_count)++;
 }
@@ -284,10 +281,8 @@
   EXPECT_EQ(0, run_count);
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      expected_deadline,
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      expected_deadline, true);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_EQ(expected_deadline, deadline_in_task);
@@ -305,10 +300,8 @@
   EXPECT_EQ(0, run_count);
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   scheduler_helper_->EndIdlePeriod();
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
@@ -322,10 +315,8 @@
       FROM_HERE,
       base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 
@@ -334,10 +325,8 @@
   EXPECT_EQ(1, run_count);
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   EXPECT_EQ(2, run_count);
 }
@@ -354,20 +343,16 @@
                             default_task_runner_, &run_count));
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Only the first idle task should execute since it's used up the deadline.
   EXPECT_EQ(1, run_count);
 
   scheduler_helper_->EndIdlePeriod();
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Second task should be run on the next idle period.
   EXPECT_EQ(2, run_count);
@@ -381,10 +366,8 @@
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Shouldn't run yet as no other task woke up the scheduler.
   EXPECT_EQ(0, run_count);
@@ -393,10 +376,8 @@
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Another after wakeup idle task shouldn't wake the scheduler.
   EXPECT_EQ(0, run_count);
@@ -406,10 +387,8 @@
   RunUntilIdle();
   // Must start a new idle period before idle task runs.
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Execution of default task queue task should trigger execution of idle task.
   EXPECT_EQ(2, run_count);
@@ -426,10 +405,8 @@
   RunUntilIdle();
   // Must start a new idle period before idle task runs.
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Should run as the scheduler was already awakened by the normal task.
   EXPECT_EQ(1, run_count);
@@ -445,17 +422,13 @@
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Must start a new idle period before after-wakeup idle task runs.
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Normal idle task should wake up after-wakeup idle task.
   EXPECT_EQ(2, run_count);
@@ -527,10 +500,8 @@
       }
     }
     scheduler_helper_->StartIdlePeriod(
-        SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-        clock_->Now(),
-        clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-        true);
+        SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+        clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
     message_loop_->RunUntilIdle();
   }
 
@@ -565,10 +536,8 @@
                  base::Unretained(&tasks_to_post_from_nested_loop)));
 
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   // Note we expect task 3 to run last because it's non-nestable.
   EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
@@ -727,14 +696,14 @@
   int run_count = 0;
 
   ON_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
-      .WillByDefault(Invoke([delay, delayOver](
-          base::TimeTicks now,
-          base::TimeDelta* next_long_idle_period_delay_out) {
-        if (now >= delayOver)
-          return true;
-        *next_long_idle_period_delay_out = delay;
-        return false;
-      }));
+      .WillByDefault(Invoke(
+          [delay, delayOver](base::TimeTicks now,
+                             base::TimeDelta* next_long_idle_period_delay_out) {
+            if (now >= delayOver)
+              return true;
+            *next_long_idle_period_delay_out = delay;
+            return false;
+          }));
 
   EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)).Times(3);
 
@@ -781,10 +750,8 @@
                             scheduler_helper_.get(), &can_exceed_idle_deadline,
                             &run_count));
   scheduler_helper_->StartIdlePeriod(
-      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-      clock_->Now(),
-      clock_->Now() + base::TimeDelta::FromMilliseconds(10),
-      true);
+      SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
+      clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_FALSE(can_exceed_idle_deadline);
@@ -945,4 +912,4 @@
   EXPECT_EQ(expected_deadline, deadline_in_task);
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/scheduler_message_loop_delegate.cc b/components/scheduler/child/scheduler_message_loop_delegate.cc
similarity index 91%
rename from content/child/scheduler/scheduler_message_loop_delegate.cc
rename to components/scheduler/child/scheduler_message_loop_delegate.cc
index 32fdc087..8c06e30 100644
--- a/content/child/scheduler/scheduler_message_loop_delegate.cc
+++ b/components/scheduler/child/scheduler_message_loop_delegate.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/child/scheduler/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
 
-namespace content {
+namespace scheduler {
 
 // static
 scoped_refptr<SchedulerMessageLoopDelegate>
@@ -43,4 +43,4 @@
   return message_loop_->IsNested();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/scheduler_message_loop_delegate.h b/components/scheduler/child/scheduler_message_loop_delegate.h
similarity index 73%
rename from content/child/scheduler/scheduler_message_loop_delegate.h
rename to components/scheduler/child/scheduler_message_loop_delegate.h
index 05e405b2..2fce4b6 100644
--- a/content/child/scheduler/scheduler_message_loop_delegate.h
+++ b/components/scheduler/child/scheduler_message_loop_delegate.h
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
-#define CONTENT_CHILD_SCHEDULER_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
+#define COMPONENTS_SCHEDULER_CHILD_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
 
 #include "base/message_loop/message_loop.h"
-#include "content/child/scheduler/nestable_single_thread_task_runner.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/scheduler_export.h"
 
-namespace content {
+namespace scheduler {
 
-class CONTENT_EXPORT SchedulerMessageLoopDelegate
+class SCHEDULER_EXPORT SchedulerMessageLoopDelegate
     : public NestableSingleThreadTaskRunner {
  public:
   // |message_loop| is not owned and must outlive the lifetime of this object.
@@ -40,6 +40,6 @@
   DISALLOW_COPY_AND_ASSIGN(SchedulerMessageLoopDelegate);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
diff --git a/content/child/scheduler/single_thread_idle_task_runner.cc b/components/scheduler/child/single_thread_idle_task_runner.cc
similarity index 86%
rename from content/child/scheduler/single_thread_idle_task_runner.cc
rename to components/scheduler/child/single_thread_idle_task_runner.cc
index 1b0eb69..e7aeda3 100644
--- a/content/child/scheduler/single_thread_idle_task_runner.cc
+++ b/components/scheduler/child/single_thread_idle_task_runner.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 "content/child/scheduler/single_thread_idle_task_runner.h"
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
 
 #include "base/location.h"
 #include "base/trace_event/trace_event.h"
 
-namespace content {
+namespace scheduler {
 
 SingleThreadIdleTaskRunner::SingleThreadIdleTaskRunner(
     scoped_refptr<base::SingleThreadTaskRunner> idle_priority_task_runner,
@@ -37,18 +37,16 @@
     const tracked_objects::Location& from_here,
     const IdleTask& idle_task) {
   idle_priority_task_runner_->PostTask(
-      from_here,
-      base::Bind(&SingleThreadIdleTaskRunner::RunTask,
-                 weak_scheduler_ptr_, idle_task));
+      from_here, base::Bind(&SingleThreadIdleTaskRunner::RunTask,
+                            weak_scheduler_ptr_, idle_task));
 }
 
 void SingleThreadIdleTaskRunner::PostNonNestableIdleTask(
     const tracked_objects::Location& from_here,
     const IdleTask& idle_task) {
   idle_priority_task_runner_->PostNonNestableTask(
-      from_here,
-      base::Bind(&SingleThreadIdleTaskRunner::RunTask,
-                 weak_scheduler_ptr_, idle_task));
+      from_here, base::Bind(&SingleThreadIdleTaskRunner::RunTask,
+                            weak_scheduler_ptr_, idle_task));
 }
 
 void SingleThreadIdleTaskRunner::PostIdleTaskAfterWakeup(
@@ -75,4 +73,4 @@
   }
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/single_thread_idle_task_runner.h b/components/scheduler/child/single_thread_idle_task_runner.h
similarity index 89%
rename from content/child/scheduler/single_thread_idle_task_runner.h
rename to components/scheduler/child/single_thread_idle_task_runner.h
index b5281a57..358389a 100644
--- a/content/child/scheduler/single_thread_idle_task_runner.h
+++ b/components/scheduler/child/single_thread_idle_task_runner.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_CHILD_SCHEDULER_SINGLE_THREAD_IDLE_TASK_RUNNER_H_
-#define CONTENT_CHILD_SCHEDULER_SINGLE_THREAD_IDLE_TASK_RUNNER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_SINGLE_THREAD_IDLE_TASK_RUNNER_H_
+#define COMPONENTS_SCHEDULER_CHILD_SINGLE_THREAD_IDLE_TASK_RUNNER_H_
 
 #include "base/bind.h"
 #include "base/callback.h"
@@ -11,7 +11,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
 
-namespace content {
+namespace scheduler {
 
 // A SingleThreadIdleTaskRunner is a task runner for running idle tasks. Idle
 // tasks have an unbound argument which is bound to a deadline
@@ -60,6 +60,6 @@
   DISALLOW_COPY_AND_ASSIGN(SingleThreadIdleTaskRunner);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_SINGLE_THREAD_IDLE_TASK_RUNNER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_SINGLE_THREAD_IDLE_TASK_RUNNER_H_
diff --git a/content/child/scheduler/task_queue_manager.cc b/components/scheduler/child/task_queue_manager.cc
similarity index 98%
rename from content/child/scheduler/task_queue_manager.cc
rename to components/scheduler/child/task_queue_manager.cc
index 646c8591..2c03bd6 100644
--- a/content/child/scheduler/task_queue_manager.cc
+++ b/components/scheduler/child/task_queue_manager.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/child/scheduler/task_queue_manager.h"
+#include "components/scheduler/child/task_queue_manager.h"
 
 #include <queue>
 #include <set>
@@ -10,15 +10,15 @@
 #include "base/bind.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
-#include "content/child/scheduler/nestable_single_thread_task_runner.h"
-#include "content/child/scheduler/task_queue_selector.h"
-#include "content/child/scheduler/time_source.h"
+#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/child/task_queue_selector.h"
+#include "components/scheduler/child/time_source.h"
 
 namespace {
 const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max();
 }
 
-namespace content {
+namespace scheduler {
 namespace internal {
 
 // Now() is somewhat expensive so it makes sense not to call Now() unless we
@@ -606,7 +606,7 @@
     MaybePostDoWorkOnMainRunner();
 
     if (ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task))
-      return; // The TaskQueueManager got deleted, we must bail out.
+      return;  // The TaskQueueManager got deleted, we must bail out.
 
     if (!UpdateWorkQueues(&previous_task))
       return;
@@ -741,4 +741,4 @@
   MaybePostDoWorkOnMainRunner();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/task_queue_manager.h b/components/scheduler/child/task_queue_manager.h
similarity index 96%
rename from content/child/scheduler/task_queue_manager.h
rename to components/scheduler/child/task_queue_manager.h
index 48588194..dad1573 100644
--- a/content/child/scheduler/task_queue_manager.h
+++ b/components/scheduler/child/task_queue_manager.h
@@ -14,9 +14,9 @@
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/thread_checker.h"
-#include "content/child/scheduler/task_queue_selector.h"
-#include "content/child/scheduler/time_source.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/child/task_queue_selector.h"
+#include "components/scheduler/child/time_source.h"
+#include "components/scheduler/scheduler_export.h"
 
 namespace base {
 namespace trace_event {
@@ -25,7 +25,7 @@
 }
 }
 
-namespace content {
+namespace scheduler {
 namespace internal {
 class LazyNow;
 class TaskQueue;
@@ -46,8 +46,7 @@
 //    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 TaskQueueSelector::Observer {
+class SCHEDULER_EXPORT TaskQueueManager : public TaskQueueSelector::Observer {
  public:
   // Keep TaskQueue::PumpPolicyToString in sync with this enum.
   enum class PumpPolicy {
@@ -221,6 +220,6 @@
   DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
 #endif  // CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
diff --git a/content/child/scheduler/task_queue_manager_perftest.cc b/components/scheduler/child/task_queue_manager_perftest.cc
similarity index 95%
rename from content/child/scheduler/task_queue_manager_perftest.cc
rename to components/scheduler/child/task_queue_manager_perftest.cc
index e056872..80a9c901 100644
--- a/content/child/scheduler/task_queue_manager_perftest.cc
+++ b/components/scheduler/child/task_queue_manager_perftest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/task_queue_manager.h"
+#include "components/scheduler/child/task_queue_manager.h"
 
 #include "base/bind.h"
 #include "base/threading/thread.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/child/scheduler/task_queue_selector.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/task_queue_selector.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_test.h"
 
-namespace content {
+namespace scheduler {
 
 namespace {
 
@@ -172,4 +172,4 @@
 // TODO(alexclarke): Add additional tests with different mixes of non-delayed vs
 // delayed tasks.
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/task_queue_manager_unittest.cc b/components/scheduler/child/task_queue_manager_unittest.cc
similarity index 98%
rename from content/child/scheduler/task_queue_manager_unittest.cc
rename to components/scheduler/child/task_queue_manager_unittest.cc
index 5a573200..f34f878 100644
--- a/content/child/scheduler/task_queue_manager_unittest.cc
+++ b/components/scheduler/child/task_queue_manager_unittest.cc
@@ -2,21 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/task_queue_manager.h"
+#include "components/scheduler/child/task_queue_manager.h"
 
 #include "base/threading/thread.h"
 #include "cc/test/ordered_simple_task_runner.h"
 #include "cc/test/test_now_source.h"
-#include "content/child/scheduler/nestable_task_runner_for_test.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/child/scheduler/task_queue_selector.h"
-#include "content/test/test_time_source.h"
+#include "components/scheduler/child/nestable_task_runner_for_test.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/task_queue_selector.h"
+#include "components/scheduler/child/test_time_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 using testing::ElementsAre;
 using testing::_;
 
-namespace content {
+namespace scheduler {
 namespace {
 
 class SelectorForTest : public TaskQueueSelector {
@@ -59,8 +59,7 @@
     return work_queues_;
   }
 
-  void SetTaskQueueSelectorObserver(Observer* observer) override {
-  }
+  void SetTaskQueueSelectorObserver(Observer* observer) override {}
 
  private:
   std::vector<const base::TaskQueue*> work_queues_;
@@ -94,8 +93,7 @@
     return work_queues_;
   }
 
-  void SetTaskQueueSelectorObserver(Observer* observer) override {
-  }
+  void SetTaskQueueSelectorObserver(Observer* observer) override {}
 
  private:
   std::deque<size_t> queues_to_service_;
@@ -106,9 +104,7 @@
 
 class TaskQueueManagerTest : public testing::Test {
  public:
-  void DeleteTaskQueueManager() {
-    manager_.reset();
-  }
+  void DeleteTaskQueueManager() { manager_.reset(); }
 
  protected:
   enum class SelectorType {
@@ -454,8 +450,8 @@
   runner->PostDelayedTask(
       FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())),
       delay);
-  runner->PostTask(
-      FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())));
+  runner->PostTask(FROM_HERE,
+                   base::Bind(&TestObject::Run, base::Owned(new TestObject())));
 
   manager_.reset();
 
@@ -1103,4 +1099,4 @@
 }
 
 }  // namespace
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/task_queue_selector.h b/components/scheduler/child/task_queue_selector.h
similarity index 81%
rename from content/child/scheduler/task_queue_selector.h
rename to components/scheduler/child/task_queue_selector.h
index 0a6c256..2af9e2b 100644
--- a/content/child/scheduler/task_queue_selector.h
+++ b/components/scheduler/child/task_queue_selector.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_TASK_QUEUE_SELECTOR_H_
-#define CONTENT_CHILD_SCHEDULER_TASK_QUEUE_SELECTOR_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_SELECTOR_H_
+#define COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_SELECTOR_H_
 
 #include <vector>
 
 #include "base/basictypes.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/scheduler_export.h"
 
 namespace base {
 class TaskQueue;
@@ -17,7 +17,7 @@
 }  // namespace trace_event
 }  // namespace base
 
-namespace content {
+namespace scheduler {
 
 class TaskQueueSelector {
  public:
@@ -28,7 +28,7 @@
   virtual void RegisterWorkQueues(
       const std::vector<const base::TaskQueue*>& work_queues) = 0;
 
-  class CONTENT_EXPORT Observer {
+  class SCHEDULER_EXPORT Observer {
    public:
     virtual ~Observer() {}
 
@@ -51,6 +51,6 @@
   virtual void AsValueInto(base::trace_event::TracedValue* state) const = 0;
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_TASK_QUEUE_SELECTOR_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_SELECTOR_H_
diff --git a/content/test/test_time_source.cc b/components/scheduler/child/test_time_source.cc
similarity index 80%
rename from content/test/test_time_source.cc
rename to components/scheduler/child/test_time_source.cc
index ad602fd..3482bb5 100644
--- a/content/test/test_time_source.cc
+++ b/components/scheduler/child/test_time_source.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/test/test_time_source.h"
+#include "components/scheduler/child/test_time_source.h"
 
 #include "cc/test/test_now_source.h"
 
-namespace content {
+namespace scheduler {
 
 TestTimeSource::TestTimeSource(scoped_refptr<cc::TestNowSource> time_source)
     : time_source_(time_source) {
@@ -19,4 +19,4 @@
   return time_source_->Now();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/test/test_time_source.h b/components/scheduler/child/test_time_source.h
similarity index 67%
rename from content/test/test_time_source.h
rename to components/scheduler/child/test_time_source.h
index 04270ec..6219a4dbd 100644
--- a/content/test/test_time_source.h
+++ b/components/scheduler/child/test_time_source.h
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_TEST_TEST_TIME_SOURCE_H_
-#define CONTENT_TEST_TEST_TIME_SOURCE_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_TEST_TIME_SOURCE_H_
+#define COMPONENTS_SCHEDULER_CHILD_TEST_TIME_SOURCE_H_
 
 #include "base/memory/ref_counted.h"
-#include "content/child/scheduler/time_source.h"
+#include "components/scheduler/child/time_source.h"
 
 namespace cc {
 class TestNowSource;
 }
 
-namespace content {
+namespace scheduler {
 
 class TestTimeSource : public TimeSource {
  public:
@@ -27,6 +27,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestTimeSource);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_TEST_TEST_TIME_SOURCE_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_TEST_TIME_SOURCE_H_
diff --git a/content/child/scheduler/time_source.cc b/components/scheduler/child/time_source.cc
similarity index 75%
rename from content/child/scheduler/time_source.cc
rename to components/scheduler/child/time_source.cc
index ce64df8..f8cf6c43 100644
--- a/content/child/scheduler/time_source.cc
+++ b/components/scheduler/child/time_source.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/child/scheduler/time_source.h"
+#include "components/scheduler/child/time_source.h"
 
-namespace content {
+namespace scheduler {
 
 TimeSource::TimeSource() {
 }
@@ -16,4 +16,4 @@
   return base::TimeTicks::Now();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/components/scheduler/child/time_source.h b/components/scheduler/child/time_source.h
new file mode 100644
index 0000000..079e78dc
--- /dev/null
+++ b/components/scheduler/child/time_source.h
@@ -0,0 +1,26 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_CHILD_TIME_SOURCE_H_
+#define COMPONENTS_SCHEDULER_CHILD_TIME_SOURCE_H_
+
+#include "base/time/time.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace scheduler {
+
+class SCHEDULER_EXPORT TimeSource {
+ public:
+  TimeSource();
+  virtual ~TimeSource();
+
+  virtual base::TimeTicks Now() const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TimeSource);
+};
+
+}  // namespace scheduler
+
+#endif  // COMPONENTS_SCHEDULER_CHILD_TIME_SOURCE_H_
diff --git a/content/child/scheduler/web_scheduler_impl.cc b/components/scheduler/child/web_scheduler_impl.cc
similarity index 93%
rename from content/child/scheduler/web_scheduler_impl.cc
rename to components/scheduler/child/web_scheduler_impl.cc
index 25772f8..9d8aac9 100644
--- a/content/child/scheduler/web_scheduler_impl.cc
+++ b/components/scheduler/child/web_scheduler_impl.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/web_scheduler_impl.h"
+#include "components/scheduler/child/web_scheduler_impl.h"
 
 #include "base/bind.h"
 #include "base/single_thread_task_runner.h"
-#include "content/child/scheduler/worker_scheduler.h"
+#include "components/scheduler/child/worker_scheduler.h"
 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
 
-namespace content {
+namespace scheduler {
 
 WebSchedulerImpl::WebSchedulerImpl(
     ChildScheduler* child_scheduler,
@@ -97,10 +97,11 @@
   scoped_ptr<blink::WebThread::Task> scoped_task(task);
   tracked_objects::Location location(web_location.functionName(),
                                      web_location.fileName(), -1, nullptr);
-  timer_task_runner_->PostDelayedTask(
+  // Timer tasks should not run in a nested messageloop.
+  timer_task_runner_->PostNonNestableDelayedTask(
       location,
       base::Bind(&WebSchedulerImpl::runTask, base::Passed(&scoped_task)),
       base::TimeDelta::FromMilliseconds(delayMs));
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/web_scheduler_impl.h b/components/scheduler/child/web_scheduler_impl.h
similarity index 92%
rename from content/child/scheduler/web_scheduler_impl.h
rename to components/scheduler/child/web_scheduler_impl.h
index 0f661b4..0d1b484 100644
--- a/content/child/scheduler/web_scheduler_impl.h
+++ b/components/scheduler/child/web_scheduler_impl.h
@@ -8,7 +8,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/scheduler_export.h"
 #include "third_party/WebKit/public/platform/WebScheduler.h"
 #include "third_party/WebKit/public/platform/WebThread.h"
 
@@ -16,12 +16,12 @@
 class SingleThreadTaskRunner;
 }
 
-namespace content {
+namespace scheduler {
 
 class ChildScheduler;
 class SingleThreadIdleTaskRunner;
 
-class CONTENT_EXPORT WebSchedulerImpl : public blink::WebScheduler {
+class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler {
  public:
   WebSchedulerImpl(
       ChildScheduler* child_scheduler,
@@ -56,6 +56,6 @@
   scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
 };
 
-}  // namespace content
+}  // namespace scheduler
 
 #endif  // CONTENT_CHILD_SCHEDULER_BASE_WEB_SCHEDULER_IMPL_H_
diff --git a/content/child/webthread_base.cc b/components/scheduler/child/webthread_base.cc
similarity index 96%
rename from content/child/webthread_base.cc
rename to components/scheduler/child/webthread_base.cc
index 818c960..9da4254a 100644
--- a/content/child/webthread_base.cc
+++ b/components/scheduler/child/webthread_base.cc
@@ -5,16 +5,16 @@
 // An implementation of WebThread in terms of base::MessageLoop and
 // base::Thread
 
-#include "content/child/webthread_base.h"
+#include "components/scheduler/child/webthread_base.h"
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/pending_task.h"
 #include "base/threading/platform_thread.h"
-#include "content/child/scheduler/single_thread_idle_task_runner.h"
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
 
-namespace content {
+namespace scheduler {
 
 class WebThreadBase::TaskObserverAdapter
     : public base::MessageLoop::TaskObserver {
@@ -161,4 +161,4 @@
   return TaskRunner()->BelongsToCurrentThread();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/webthread_base.h b/components/scheduler/child/webthread_base.h
similarity index 85%
rename from content/child/webthread_base.h
rename to components/scheduler/child/webthread_base.h
index 5d6ebb9b..c7f86562 100644
--- a/content/child/webthread_base.h
+++ b/components/scheduler/child/webthread_base.h
@@ -2,24 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_WEBTHREAD_BASE_H_
-#define CONTENT_CHILD_WEBTHREAD_BASE_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_BASE_H_
+#define COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_BASE_H_
 
 #include <map>
 
 #include "base/memory/scoped_ptr.h"
 #include "base/threading/thread.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/scheduler_export.h"
 #include "third_party/WebKit/public/platform/WebThread.h"
 
 namespace blink {
 class WebTraceLocation;
 }
 
-namespace content {
+namespace scheduler {
 class SingleThreadIdleTaskRunner;
 
-class CONTENT_EXPORT WebThreadBase : public blink::WebThread {
+class SCHEDULER_EXPORT WebThreadBase : public blink::WebThread {
  public:
   virtual ~WebThreadBase();
 
@@ -48,7 +48,7 @@
 
   // Returns the base::Bind-compatible task runner for posting idle tasks to
   // this thread. Can be called from any thread.
-  virtual SingleThreadIdleTaskRunner* IdleTaskRunner() const = 0;
+  virtual scheduler::SingleThreadIdleTaskRunner* IdleTaskRunner() const = 0;
 
  protected:
   class TaskObserverAdapter;
@@ -75,6 +75,6 @@
   TaskObserverMap task_observer_map_;
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_WEBTHREAD_BASE_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_BASE_H_
diff --git a/content/child/scheduler/webthread_impl_for_worker_scheduler.cc b/components/scheduler/child/webthread_impl_for_worker_scheduler.cc
similarity index 89%
rename from content/child/scheduler/webthread_impl_for_worker_scheduler.cc
rename to components/scheduler/child/webthread_impl_for_worker_scheduler.cc
index 09004f8..c293faae 100644
--- a/content/child/scheduler/webthread_impl_for_worker_scheduler.cc
+++ b/components/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/webthread_impl_for_worker_scheduler.h"
+#include "components/scheduler/child/webthread_impl_for_worker_scheduler.h"
 
 #include "base/bind.h"
 #include "base/synchronization/waitable_event.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/child/scheduler/web_scheduler_impl.h"
-#include "content/child/scheduler/worker_scheduler_impl.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/web_scheduler_impl.h"
+#include "components/scheduler/child/worker_scheduler_impl.h"
 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
 
-namespace content {
+namespace scheduler {
 
 WebThreadImplForWorkerScheduler::WebThreadImplForWorkerScheduler(
     const char* name)
@@ -92,4 +92,4 @@
   worker_scheduler_->RemoveTaskObserver(observer);
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/webthread_impl_for_worker_scheduler.h b/components/scheduler/child/webthread_impl_for_worker_scheduler.h
similarity index 61%
rename from content/child/scheduler/webthread_impl_for_worker_scheduler.h
rename to components/scheduler/child/webthread_impl_for_worker_scheduler.h
index d5346ba..2ea02e4 100644
--- a/content/child/scheduler/webthread_impl_for_worker_scheduler.h
+++ b/components/scheduler/child/webthread_impl_for_worker_scheduler.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
-#define CONTENT_CHILD_SCHEDULER_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
 
-#include "content/child/scheduler/task_queue_manager.h"
-#include "content/child/webthread_base.h"
+#include "components/scheduler/child/task_queue_manager.h"
+#include "components/scheduler/child/webthread_base.h"
 
 namespace base {
 class WaitableEvent;
@@ -16,13 +16,12 @@
 class WebScheduler;
 };
 
-namespace content {
-
+namespace scheduler {
 class SingleThreadIdleTaskRunner;
 class WebSchedulerImpl;
 class WorkerScheduler;
 
-class CONTENT_EXPORT WebThreadImplForWorkerScheduler : public WebThreadBase {
+class SCHEDULER_EXPORT WebThreadImplForWorkerScheduler : public WebThreadBase {
  public:
   explicit WebThreadImplForWorkerScheduler(const char* name);
   virtual ~WebThreadImplForWorkerScheduler();
@@ -33,7 +32,7 @@
 
   // WebThreadBase implementation.
   base::SingleThreadTaskRunner* TaskRunner() const override;
-  SingleThreadIdleTaskRunner* IdleTaskRunner() const override;
+  scheduler::SingleThreadIdleTaskRunner* IdleTaskRunner() const override;
 
  private:
   base::MessageLoop* MessageLoop() const override;
@@ -46,12 +45,12 @@
   void ShutDownOnThread(base::WaitableEvent* completion);
 
   scoped_ptr<base::Thread> thread_;
-  scoped_ptr<WorkerScheduler> worker_scheduler_;
-  scoped_ptr<WebSchedulerImpl> web_scheduler_;
+  scoped_ptr<scheduler::WorkerScheduler> worker_scheduler_;
+  scoped_ptr<scheduler::WebSchedulerImpl> web_scheduler_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
+  scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_;
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
diff --git a/content/child/scheduler/webthread_impl_for_worker_scheduler_unittest.cc b/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
similarity index 95%
rename from content/child/scheduler/webthread_impl_for_worker_scheduler_unittest.cc
rename to components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
index b03749a..7bb1f89 100644
--- a/content/child/scheduler/webthread_impl_for_worker_scheduler_unittest.cc
+++ b/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.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 "content/child/scheduler/webthread_impl_for_worker_scheduler.h"
+#include "components/scheduler/child/webthread_impl_for_worker_scheduler.h"
 
 #include "base/synchronization/waitable_event.h"
-#include "content/child/scheduler/worker_scheduler_impl.h"
+#include "components/scheduler/child/worker_scheduler_impl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
@@ -15,7 +15,7 @@
 using testing::ElementsAre;
 using testing::Invoke;
 
-namespace content {
+namespace scheduler {
 namespace {
 
 class NopTask : public blink::WebThread::Task {
@@ -167,4 +167,4 @@
   EXPECT_THAT(calls, testing::HasSubstr("willProcessTask run didProcessTask"));
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/worker_scheduler.cc b/components/scheduler/child/worker_scheduler.cc
similarity index 67%
rename from content/child/scheduler/worker_scheduler.cc
rename to components/scheduler/child/worker_scheduler.cc
index ac30ab3..a1ddc988 100644
--- a/content/child/scheduler/worker_scheduler.cc
+++ b/components/scheduler/child/worker_scheduler.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/worker_scheduler.h"
+#include "components/scheduler/child/worker_scheduler.h"
 
 #include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
-#include "content/child/scheduler/null_worker_scheduler.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/child/scheduler/worker_scheduler_impl.h"
-#include "content/public/common/content_switches.h"
+#include "components/scheduler/child/null_worker_scheduler.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/worker_scheduler_impl.h"
+#include "components/scheduler/common/scheduler_switches.h"
 
-namespace content {
+namespace scheduler {
 
 WorkerScheduler::WorkerScheduler() {
 }
@@ -31,4 +31,4 @@
   }
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/components/scheduler/child/worker_scheduler.h b/components/scheduler/child/worker_scheduler.h
new file mode 100644
index 0000000..33382109
--- /dev/null
+++ b/components/scheduler/child/worker_scheduler.h
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_CHILD_WORKER_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_CHILD_WORKER_SCHEDULER_H_
+
+#include "base/message_loop/message_loop.h"
+#include "components/scheduler/child/child_scheduler.h"
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace base {
+class MessageLoop;
+}
+
+namespace scheduler {
+
+class SCHEDULER_EXPORT WorkerScheduler : public ChildScheduler {
+ public:
+  ~WorkerScheduler() override;
+  static scoped_ptr<WorkerScheduler> Create(base::MessageLoop* message_loop);
+
+  // Must be called before the scheduler can be used. Does any post construction
+  // initialization needed such as initializing idle period detection.
+  virtual void Init() = 0;
+
+ protected:
+  WorkerScheduler();
+  DISALLOW_COPY_AND_ASSIGN(WorkerScheduler);
+};
+
+}  // namespace scheduler
+
+#endif  // COMPONENTS_SCHEDULER_CHILD_WORKER_SCHEDULER_H_
diff --git a/content/child/scheduler/worker_scheduler_impl.cc b/components/scheduler/child/worker_scheduler_impl.cc
similarity index 88%
rename from content/child/scheduler/worker_scheduler_impl.cc
rename to components/scheduler/child/worker_scheduler_impl.cc
index c22c0c3..cfd444e9 100644
--- a/content/child/scheduler/worker_scheduler_impl.cc
+++ b/components/scheduler/child/worker_scheduler_impl.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/worker_scheduler_impl.h"
+#include "components/scheduler/child/worker_scheduler_impl.h"
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
-#include "content/child/scheduler/nestable_single_thread_task_runner.h"
+#include "components/scheduler/child/nestable_single_thread_task_runner.h"
 
-namespace content {
+namespace scheduler {
 
 WorkerSchedulerImpl::WorkerSchedulerImpl(
     scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
@@ -79,10 +79,6 @@
   return &helper_;
 }
 
-void WorkerSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) {
-  helper_.SetWorkBatchSizeForTesting(work_batch_size);
-}
-
 bool WorkerSchedulerImpl::CanEnterLongIdlePeriod(base::TimeTicks,
                                                  base::TimeDelta*) {
   return true;
@@ -94,4 +90,4 @@
   return deadline;
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/child/scheduler/worker_scheduler_impl.h b/components/scheduler/child/worker_scheduler_impl.h
similarity index 77%
rename from content/child/scheduler/worker_scheduler_impl.h
rename to components/scheduler/child/worker_scheduler_impl.h
index 06e9d58..989d9cf 100644
--- a/content/child/scheduler/worker_scheduler_impl.h
+++ b/components/scheduler/child/worker_scheduler_impl.h
@@ -2,11 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_CHILD_SCHEDULER_WORKER_SCHEDULER_IMPL_H_
-#define CONTENT_CHILD_SCHEDULER_WORKER_SCHEDULER_IMPL_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_WORKER_SCHEDULER_IMPL_H_
+#define COMPONENTS_SCHEDULER_CHILD_WORKER_SCHEDULER_IMPL_H_
 
-#include "content/child/scheduler/worker_scheduler.h"
-#include "content/child/scheduler/scheduler_helper.h"
+#include "components/scheduler/child/scheduler_helper.h"
+#include "components/scheduler/child/worker_scheduler.h"
+#include "components/scheduler/scheduler_export.h"
 
 namespace base {
 namespace trace_event {
@@ -14,11 +15,11 @@
 }
 }
 
-namespace content {
+namespace scheduler {
 
 class NestableSingleThreadTaskRunner;
 
-class CONTENT_EXPORT WorkerSchedulerImpl
+class SCHEDULER_EXPORT WorkerSchedulerImpl
     : public WorkerScheduler,
       public SchedulerHelper::SchedulerHelperDelegate {
  public:
@@ -38,7 +39,6 @@
   void Shutdown() override;
 
   SchedulerHelper* GetSchedulerHelperForTesting();
-  void SetWorkBatchSizeForTesting(size_t work_batch_size);
   base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;
 
  protected:
@@ -57,6 +57,6 @@
   DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerImpl);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_CHILD_SCHEDULER_WORKER_SCHEDULER_IMPL_H_
+#endif  // COMPONENTS_SCHEDULER_CHILD_WORKER_SCHEDULER_IMPL_H_
diff --git a/content/child/scheduler/worker_scheduler_impl_unittest.cc b/components/scheduler/child/worker_scheduler_impl_unittest.cc
similarity index 95%
rename from content/child/scheduler/worker_scheduler_impl_unittest.cc
rename to components/scheduler/child/worker_scheduler_impl_unittest.cc
index edeaa36..495e88b6 100644
--- a/content/child/scheduler/worker_scheduler_impl_unittest.cc
+++ b/components/scheduler/child/worker_scheduler_impl_unittest.cc
@@ -2,21 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/child/scheduler/worker_scheduler_impl.h"
+#include "components/scheduler/child/worker_scheduler_impl.h"
 
 #include "base/callback.h"
 #include "base/strings/stringprintf.h"
 #include "cc/test/ordered_simple_task_runner.h"
 #include "cc/test/test_now_source.h"
-#include "content/child/scheduler/nestable_task_runner_for_test.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/test/test_time_source.h"
+#include "components/scheduler/child/nestable_task_runner_for_test.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/test_time_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using testing::ElementsAreArray;
 
-namespace content {
+namespace scheduler {
 
 namespace {
 void NopTask() {
@@ -28,15 +28,15 @@
 
 void WakeUpTask(std::vector<std::string>* timeline, cc::TestNowSource* clock) {
   if (timeline) {
-    timeline->push_back(base::StringPrintf(
-        "run WakeUpTask @ %d", TimeTicksToIntMs(clock->Now())));
+    timeline->push_back(base::StringPrintf("run WakeUpTask @ %d",
+                                           TimeTicksToIntMs(clock->Now())));
   }
 }
 
 void RecordTimelineTask(std::vector<std::string>* timeline,
                         cc::TestNowSource* clock) {
-  timeline->push_back(base::StringPrintf(
-      "run RecordTimelineTask @ %d", TimeTicksToIntMs(clock->Now())));
+  timeline->push_back(base::StringPrintf("run RecordTimelineTask @ %d",
+                                         TimeTicksToIntMs(clock->Now())));
 }
 
 void AppendToVectorTestTask(std::vector<std::string>* vector,
@@ -423,4 +423,4 @@
   EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/components/scheduler/common/scheduler_switches.cc b/components/scheduler/common/scheduler_switches.cc
new file mode 100644
index 0000000..7d7eca64a
--- /dev/null
+++ b/components/scheduler/common/scheduler_switches.cc
@@ -0,0 +1,15 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/scheduler/common/scheduler_switches.h"
+
+namespace scheduler {
+namespace switches {
+
+// Disable the Blink Scheduler. Ensures there's no reordering of blink tasks.
+// This switch is intended only for performance tests.
+const char kDisableBlinkScheduler[] = "disable-blink-scheduler";
+
+}  // namespace switches
+}  // namespace scheduler
diff --git a/components/scheduler/common/scheduler_switches.h b/components/scheduler/common/scheduler_switches.h
new file mode 100644
index 0000000..8d909d9
--- /dev/null
+++ b/components/scheduler/common/scheduler_switches.h
@@ -0,0 +1,16 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_COMMON_SCHEDULER_SWITCHES_H_
+#define COMPONENTS_SCHEDULER_COMMON_SCHEDULER_SWITCHES_H_
+
+namespace scheduler {
+namespace switches {
+
+extern const char kDisableBlinkScheduler[];
+
+}  // namespace switches
+}  // namespace scheduler
+
+#endif  // COMPONENTS_SCHEDULER_COMMON_SCHEDULER_SWITCHES_H_
diff --git a/components/scheduler/renderer/DEPS b/components/scheduler/renderer/DEPS
new file mode 100644
index 0000000..3425c1a
--- /dev/null
+++ b/components/scheduler/renderer/DEPS
@@ -0,0 +1,15 @@
+include_rules = [
+  "+components/scheduler/child",
+  "+components/scheduler/common",
+  "+components/scheduler/scheduler_export.h",
+  "+cc/output",
+  "+ui/gfx",
+  "+third_party/WebKit/public/platform",
+  "+third_party/WebKit/public/web",
+]
+
+specific_include_rules = {
+  ".*test\.cc": [
+    "+cc/test",
+  ],
+}
diff --git a/content/renderer/scheduler/deadline_task_runner.cc b/components/scheduler/renderer/deadline_task_runner.cc
similarity index 90%
rename from content/renderer/scheduler/deadline_task_runner.cc
rename to components/scheduler/renderer/deadline_task_runner.cc
index 04564cd..fd6859f 100644
--- a/content/renderer/scheduler/deadline_task_runner.cc
+++ b/components/scheduler/renderer/deadline_task_runner.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/deadline_task_runner.h"
+#include "components/scheduler/renderer/deadline_task_runner.h"
 
 #include "base/bind.h"
 
-namespace content {
+namespace scheduler {
 
 DeadlineTaskRunner::DeadlineTaskRunner(
     const base::Closure& callback,
@@ -37,4 +37,4 @@
   callback_.Run();
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/deadline_task_runner.h b/components/scheduler/renderer/deadline_task_runner.h
similarity index 76%
rename from content/renderer/scheduler/deadline_task_runner.h
rename to components/scheduler/renderer/deadline_task_runner.h
index e9b2755d..7988cc4 100644
--- a/content/renderer/scheduler/deadline_task_runner.h
+++ b/components/scheduler/renderer/deadline_task_runner.h
@@ -2,21 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_SCHEDULER_DEADLINE_TASK_RUNNER_H_
-#define CONTENT_RENDERER_SCHEDULER_DEADLINE_TASK_RUNNER_H_
+#ifndef COMPONENTS_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_
+#define COMPONENTS_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_
 
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
-#include "content/child/scheduler/cancelable_closure_holder.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/child/cancelable_closure_holder.h"
+#include "components/scheduler/scheduler_export.h"
 
-namespace content {
+namespace scheduler {
 
 // Runs a posted task at latest by a given deadline, but possibly sooner.
-class CONTENT_EXPORT DeadlineTaskRunner {
+class SCHEDULER_EXPORT DeadlineTaskRunner {
  public:
   DeadlineTaskRunner(const base::Closure& callback,
                      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
@@ -45,6 +45,6 @@
   DISALLOW_COPY_AND_ASSIGN(DeadlineTaskRunner);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_RENDERER_SCHEDULER_DEADLINE_TASK_RUNNER_H_
+#endif  // COMPONENTS_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_
diff --git a/content/renderer/scheduler/deadline_task_runner_unittest.cc b/components/scheduler/renderer/deadline_task_runner_unittest.cc
similarity index 96%
rename from content/renderer/scheduler/deadline_task_runner_unittest.cc
rename to components/scheduler/renderer/deadline_task_runner_unittest.cc
index 87ec6a1..ae56f41 100644
--- a/content/renderer/scheduler/deadline_task_runner_unittest.cc
+++ b/components/scheduler/renderer/deadline_task_runner_unittest.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/deadline_task_runner.h"
+#include "components/scheduler/renderer/deadline_task_runner.h"
 
 #include "cc/test/ordered_simple_task_runner.h"
 #include "cc/test/test_now_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace content {
+namespace scheduler {
 
 class DeadlineTaskRunnerTest : public testing::Test {
  public:
@@ -95,4 +95,4 @@
   EXPECT_TRUE(run_times_.empty());
 };
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/null_renderer_scheduler.cc b/components/scheduler/renderer/null_renderer_scheduler.cc
similarity index 86%
rename from content/renderer/scheduler/null_renderer_scheduler.cc
rename to components/scheduler/renderer/null_renderer_scheduler.cc
index 349ab54cb..22736b6 100644
--- a/content/renderer/scheduler/null_renderer_scheduler.cc
+++ b/components/scheduler/renderer/null_renderer_scheduler.cc
@@ -2,16 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/null_renderer_scheduler.h"
+#include "components/scheduler/renderer/null_renderer_scheduler.h"
 
 #include "base/bind.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "content/child/scheduler/null_idle_task_runner.h"
+#include "base/message_loop/message_loop.h"
+#include "base/thread_task_runner_handle.h"
+#include "components/scheduler/child/null_idle_task_runner.h"
 
-namespace content {
+namespace scheduler {
 
 NullRendererScheduler::NullRendererScheduler()
-    : task_runner_(base::MessageLoopProxy::current()),
+    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
       idle_task_runner_(new NullIdleTaskRunner()) {
 }
 
@@ -96,4 +97,4 @@
 void NullRendererScheduler::ResumeTimerQueue() {
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/null_renderer_scheduler.h b/components/scheduler/renderer/null_renderer_scheduler.h
similarity index 84%
rename from content/renderer/scheduler/null_renderer_scheduler.h
rename to components/scheduler/renderer/null_renderer_scheduler.h
index 162e8d99..a346665 100644
--- a/content/renderer/scheduler/null_renderer_scheduler.h
+++ b/components/scheduler/renderer/null_renderer_scheduler.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_RENDERER_SCHEDULER_NULL_RENDERER_SCHEDULER_H_
-#define CONTENT_RENDERER_SCHEDULER_NULL_RENDERER_SCHEDULER_H_
+#ifndef COMPONENTS_SCHEDULER_RENDERER_NULL_RENDERER_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_RENDERER_NULL_RENDERER_SCHEDULER_H_
 
-#include "content/renderer/scheduler/renderer_scheduler.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 
-namespace content {
+namespace scheduler {
 
 class NullRendererScheduler : public RendererScheduler {
  public:
@@ -45,6 +45,6 @@
   DISALLOW_COPY_AND_ASSIGN(NullRendererScheduler);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_RENDERER_SCHEDULER_NULL_RENDERER_SCHEDULER_H_
+#endif  // COMPONENTS_SCHEDULER_RENDERER_NULL_RENDERER_SCHEDULER_H_
diff --git a/content/renderer/scheduler/renderer_scheduler.cc b/components/scheduler/renderer/renderer_scheduler.cc
similarity index 73%
rename from content/renderer/scheduler/renderer_scheduler.cc
rename to components/scheduler/renderer/renderer_scheduler.cc
index 0ecba8c..95669507e 100644
--- a/content/renderer/scheduler/renderer_scheduler.cc
+++ b/components/scheduler/renderer/renderer_scheduler.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/renderer_scheduler.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 
 #include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_impl.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/public/common/content_switches.h"
-#include "content/renderer/scheduler/null_renderer_scheduler.h"
-#include "content/renderer/scheduler/renderer_scheduler_impl.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/common/scheduler_switches.h"
+#include "components/scheduler/renderer/null_renderer_scheduler.h"
+#include "components/scheduler/renderer/renderer_scheduler_impl.h"
 
-namespace content {
+namespace scheduler {
 
 RendererScheduler::RendererScheduler() {
 }
@@ -37,4 +37,4 @@
   }
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/renderer_scheduler.h b/components/scheduler/renderer/renderer_scheduler.h
similarity index 86%
rename from content/renderer/scheduler/renderer_scheduler.h
rename to components/scheduler/renderer/renderer_scheduler.h
index 7d08f31..e2756149 100644
--- a/content/renderer/scheduler/renderer_scheduler.h
+++ b/components/scheduler/renderer/renderer_scheduler.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_SCHEDULER_RENDERER_SCHEDULER_H_
-#define CONTENT_RENDERER_SCHEDULER_RENDERER_SCHEDULER_H_
+#ifndef COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_H_
 
 #include "base/message_loop/message_loop.h"
-#include "content/child/scheduler/child_scheduler.h"
-#include "content/child/scheduler/single_thread_idle_task_runner.h"
-#include "content/common/content_export.h"
+#include "components/scheduler/child/child_scheduler.h"
+#include "components/scheduler/child/single_thread_idle_task_runner.h"
+#include "components/scheduler/scheduler_export.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
 namespace cc {
 struct BeginFrameArgs;
 }
 
-namespace content {
+namespace scheduler {
 
-class CONTENT_EXPORT RendererScheduler : public ChildScheduler {
+class SCHEDULER_EXPORT RendererScheduler : public ChildScheduler {
  public:
   ~RendererScheduler() override;
   static scoped_ptr<RendererScheduler> Create();
@@ -84,6 +84,6 @@
   DISALLOW_COPY_AND_ASSIGN(RendererScheduler);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_RENDERER_SCHEDULER_RENDERER_SCHEDULER_H_
+#endif  // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_H_
diff --git a/content/renderer/scheduler/renderer_scheduler_impl.cc b/components/scheduler/renderer/renderer_scheduler_impl.cc
similarity index 95%
rename from content/renderer/scheduler/renderer_scheduler_impl.cc
rename to components/scheduler/renderer/renderer_scheduler_impl.cc
index 7ca3eb7a..5ed3d6d 100644
--- a/content/renderer/scheduler/renderer_scheduler_impl.cc
+++ b/components/scheduler/renderer/renderer_scheduler_impl.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/renderer_scheduler_impl.h"
+#include "components/scheduler/renderer/renderer_scheduler_impl.h"
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "cc/output/begin_frame_args.h"
-#include "content/child/scheduler/nestable_single_thread_task_runner.h"
-#include "content/child/scheduler/prioritizing_task_queue_selector.h"
+#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/child/prioritizing_task_queue_selector.h"
 #include "ui/gfx/frame_time.h"
 
-namespace content {
+namespace scheduler {
 
 RendererSchedulerImpl::RendererSchedulerImpl(
     scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
@@ -45,8 +45,7 @@
   end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
       &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
 
-  for (size_t i = SchedulerHelper::TASK_QUEUE_COUNT;
-       i < TASK_QUEUE_COUNT;
+  for (size_t i = SchedulerHelper::TASK_QUEUE_COUNT; i < TASK_QUEUE_COUNT;
        i++) {
     helper_.SetQueueName(i, TaskQueueIdToString(static_cast<QueueId>(i)));
   }
@@ -133,10 +132,8 @@
     // TODO(rmcilroy): Consider reducing the idle period based on the runtime of
     // the next pending delayed tasks (as currently done in for long idle times)
     helper_.StartIdlePeriod(
-        SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
-        now,
-        estimated_next_frame_begin_,
-        true);
+        SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now,
+        estimated_next_frame_begin_, true);
   }
 }
 
@@ -168,8 +165,7 @@
   base::TimeDelta end_idle_when_hidden_delay =
       base::TimeDelta::FromMilliseconds(kEndIdleWhenHiddenDelayMillis);
   control_task_runner_->PostDelayedTask(
-      FROM_HERE,
-      end_renderer_hidden_idle_period_closure_.callback(),
+      FROM_HERE, end_renderer_hidden_idle_period_closure_.callback(),
       end_idle_when_hidden_delay);
   renderer_hidden_ = true;
 
@@ -303,8 +299,8 @@
   }
 }
 
-base::TimeTicks
-RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting() const {
+base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting()
+    const {
   base::TimeTicks deadline;
   helper_.CurrentIdleTaskDeadlineCallback(&deadline);
   return deadline;
@@ -489,10 +485,6 @@
   return &helper_;
 }
 
-void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) {
-  helper_.SetWorkBatchSizeForTesting(work_batch_size);
-}
-
 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
     base::Lock* write_lock_)
     : flag_(false), write_lock_(write_lock_) {
@@ -515,8 +507,8 @@
   helper_.CheckOnValidThread();
   timer_queue_suspend_count_++;
   ForceUpdatePolicy();
-  DCHECK(!helper_.SchedulerTaskQueueSelector()->IsQueueEnabled(
-      TIMER_TASK_QUEUE));
+  DCHECK(
+      !helper_.SchedulerTaskQueueSelector()->IsQueueEnabled(TIMER_TASK_QUEUE));
 }
 
 void RendererSchedulerImpl::ResumeTimerQueue() {
@@ -638,4 +630,4 @@
   return InputStreamState::ACTIVE;
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/renderer_scheduler_impl.h b/components/scheduler/renderer/renderer_scheduler_impl.h
similarity index 93%
rename from content/renderer/scheduler/renderer_scheduler_impl.h
rename to components/scheduler/renderer/renderer_scheduler_impl.h
index 04c9ab8..6dcd3c9d 100644
--- a/content/renderer/scheduler/renderer_scheduler_impl.h
+++ b/components/scheduler/renderer/renderer_scheduler_impl.h
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_SCHEDULER_RENDERER_SCHEDULER_IMPL_H_
-#define CONTENT_RENDERER_SCHEDULER_RENDERER_SCHEDULER_IMPL_H_
+#ifndef COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
+#define COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
 
 #include "base/atomicops.h"
 #include "base/synchronization/lock.h"
-#include "content/child/scheduler/scheduler_helper.h"
-#include "content/renderer/scheduler/deadline_task_runner.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
+#include "components/scheduler/child/scheduler_helper.h"
+#include "components/scheduler/renderer/deadline_task_runner.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/scheduler_export.h"
 
 namespace base {
 namespace trace_event {
@@ -17,9 +18,9 @@
 }
 }
 
-namespace content {
+namespace scheduler {
 
-class CONTENT_EXPORT RendererSchedulerImpl
+class SCHEDULER_EXPORT RendererSchedulerImpl
     : public RendererScheduler,
       public SchedulerHelper::SchedulerHelperDelegate {
  public:
@@ -52,7 +53,6 @@
   void ResumeTimerQueue() override;
 
   SchedulerHelper* GetSchedulerHelperForTesting();
-  void SetWorkBatchSizeForTesting(size_t work_batch_size);
   base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;
 
  private:
@@ -209,6 +209,6 @@
   DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl);
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_RENDERER_SCHEDULER_RENDERER_SCHEDULER_IMPL_H_
+#endif  // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
diff --git a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
similarity index 96%
rename from content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
rename to components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
index 150be2e..27ec431 100644
--- a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
+++ b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/renderer_scheduler_impl.h"
+#include "components/scheduler/renderer/renderer_scheduler_impl.h"
 
 #include "base/callback.h"
 #include "cc/output/begin_frame_args.h"
 #include "cc/test/ordered_simple_task_runner.h"
 #include "cc/test/test_now_source.h"
-#include "content/child/scheduler/nestable_task_runner_for_test.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/test/test_time_source.h"
+#include "components/scheduler/child/nestable_task_runner_for_test.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/test_time_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace content {
+namespace scheduler {
 
 namespace {
 class FakeInputEvent : public blink::WebInputEvent {
@@ -45,17 +45,16 @@
 void NullTask() {
 }
 
-void AppendToVectorReentrantTask(
-    base::SingleThreadTaskRunner* task_runner,
-    std::vector<int>* vector,
-    int* reentrant_count,
-    int max_reentrant_count) {
+void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner,
+                                 std::vector<int>* vector,
+                                 int* reentrant_count,
+                                 int max_reentrant_count) {
   vector->push_back((*reentrant_count)++);
   if (*reentrant_count < max_reentrant_count) {
     task_runner->PostTask(
-        FROM_HERE, base::Bind(AppendToVectorReentrantTask,
-                              base::Unretained(task_runner), vector,
-                              reentrant_count, max_reentrant_count));
+        FROM_HERE,
+        base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner),
+                   vector, reentrant_count, max_reentrant_count));
   }
 }
 
@@ -68,15 +67,13 @@
 
 int max_idle_task_reposts = 2;
 
-void RepostingIdleTestTask(
-    SingleThreadIdleTaskRunner* idle_task_runner,
-    int* run_count,
-    base::TimeTicks deadline) {
+void RepostingIdleTestTask(SingleThreadIdleTaskRunner* idle_task_runner,
+                           int* run_count,
+                           base::TimeTicks deadline) {
   if ((*run_count + 1) < max_idle_task_reposts) {
     idle_task_runner->PostIdleTask(
-        FROM_HERE,
-        base::Bind(&RepostingIdleTestTask, base::Unretained(idle_task_runner),
-                   run_count));
+        FROM_HERE, base::Bind(&RepostingIdleTestTask,
+                              base::Unretained(idle_task_runner), run_count));
   }
   (*run_count)++;
 }
@@ -95,12 +92,11 @@
   (*run_count)++;
 }
 
-void PostingYieldingTestTask(
-    RendererSchedulerImpl* scheduler,
-    base::SingleThreadTaskRunner* task_runner,
-    bool simulate_input,
-    bool* should_yield_before,
-    bool* should_yield_after) {
+void PostingYieldingTestTask(RendererSchedulerImpl* scheduler,
+                             base::SingleThreadTaskRunner* task_runner,
+                             bool simulate_input,
+                             bool* should_yield_before,
+                             bool* should_yield_after) {
   *should_yield_before = scheduler->ShouldYieldForHighPriorityWork();
   task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
   if (simulate_input) {
@@ -553,8 +549,7 @@
       FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
   RunUntilIdle();
 
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("L1")));
+  EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
 }
 
 TEST_F(RendererSchedulerImplTest,
@@ -1167,8 +1162,8 @@
 
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
-  default_task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&NullTask), pending_task_delay);
+  default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
+                                        pending_task_delay);
 
   scheduler_->BeginFrameNotExpectedSoon();
   RunUntilIdle();
@@ -1182,8 +1177,8 @@
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
-  default_task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&NullTask), pending_task_delay);
+  default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
+                                        pending_task_delay);
 
   // Advance clock until after delayed task was meant to be run.
   clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20));
@@ -1253,8 +1248,7 @@
   // Posting a after-wakeup idle task also shouldn't wake the scheduler or
   // initiate the next long idle period.
   idle_task_runner_->PostIdleTaskAfterWakeup(
-      FROM_HERE,
-      base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+      FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
   RunUntilIdle();
   new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
   EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
@@ -1275,8 +1269,7 @@
   int run_count = 0;
 
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+      FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
   // Observation of touchstart should defer the start of the long idle period.
   scheduler_->DidReceiveInputEventOnCompositorThread(
@@ -1424,4 +1417,4 @@
               testing::ElementsAre(std::string("T1"), std::string("T2")));
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/webthread_impl_for_renderer_scheduler.cc b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
similarity index 87%
rename from content/renderer/scheduler/webthread_impl_for_renderer_scheduler.cc
rename to components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
index 79ee88f..9bad0b3 100644
--- a/content/renderer/scheduler/webthread_impl_for_renderer_scheduler.cc
+++ b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h"
+#include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
 
-#include "content/child/scheduler/web_scheduler_impl.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
+#include "components/scheduler/child/web_scheduler_impl.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
 
-namespace content {
+namespace scheduler {
 
 WebThreadImplForRendererScheduler::WebThreadImplForRendererScheduler(
     RendererScheduler* scheduler)
@@ -58,4 +58,4 @@
   scheduler_->RemoveTaskObserver(observer);
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
similarity index 75%
rename from content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h
rename to components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
index 6d1af5a..70202feb 100644
--- a/content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h
+++ b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_SCHEDULER_WEBTHREAD_IMPL_FOR_RENDERER_SCHEDULER_H_
-#define CONTENT_RENDERER_SCHEDULER_WEBTHREAD_IMPL_FOR_RENDERER_SCHEDULER_H_
+#ifndef COMPONENTS_SCHEDULER_RENDERER_WEBTHREAD_IMPL_FOR_RENDERER_SCHEDULER_H_
+#define COMPONENTS_SCHEDULER_RENDERER_WEBTHREAD_IMPL_FOR_RENDERER_SCHEDULER_H_
 
 #include "base/containers/scoped_ptr_hash_map.h"
-#include "content/child/webthread_base.h"
+#include "components/scheduler/child/webthread_base.h"
 
 namespace blink {
 class WebScheduler;
 };
 
-namespace content {
-
+namespace scheduler {
 class RendererScheduler;
 class WebSchedulerImpl;
 
-class CONTENT_EXPORT WebThreadImplForRendererScheduler : public WebThreadBase {
+class SCHEDULER_EXPORT WebThreadImplForRendererScheduler
+    : public WebThreadBase {
  public:
   explicit WebThreadImplForRendererScheduler(RendererScheduler* scheduler);
   virtual ~WebThreadImplForRendererScheduler();
@@ -44,6 +44,6 @@
   blink::PlatformThreadId thread_id_;
 };
 
-}  // namespace content
+}  // namespace scheduler
 
-#endif  // CONTENT_RENDERER_SCHEDULER_WEBTHREAD_IMPL_FOR_RENDERER_SCHEDULER_H_
+#endif  // COMPONENTS_SCHEDULER_RENDERER_WEBTHREAD_IMPL_FOR_RENDERER_SCHEDULER_H_
diff --git a/content/renderer/scheduler/webthread_impl_for_renderer_scheduler_unittest.cc b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
similarity index 91%
rename from content/renderer/scheduler/webthread_impl_for_renderer_scheduler_unittest.cc
rename to components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
index 191a2710..e92e7d3 100644
--- a/content/renderer/scheduler/webthread_impl_for_renderer_scheduler_unittest.cc
+++ b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h"
+#include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
 
 #include "base/run_loop.h"
-#include "content/child/scheduler/scheduler_message_loop_delegate.h"
-#include "content/renderer/scheduler/renderer_scheduler_impl.h"
+#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/renderer/renderer_scheduler_impl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
 
-namespace content {
+namespace scheduler {
 namespace {
 
 const int kWorkBatchSize = 2;
@@ -38,7 +38,8 @@
   ~WebThreadImplForRendererSchedulerTest() override {}
 
   void SetWorkBatchSizeForTesting(size_t work_batch_size) {
-    scheduler_.SetWorkBatchSizeForTesting(work_batch_size);
+    scheduler_.GetSchedulerHelperForTesting()->SetWorkBatchSizeForTesting(
+        work_batch_size);
   }
 
  protected:
@@ -80,7 +81,7 @@
   thread_.addTaskObserver(&observer);
   scoped_ptr<MockTask> task(new MockTask());
 
-  scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize);
+  SetWorkBatchSizeForTesting(kWorkBatchSize);
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
@@ -101,7 +102,7 @@
   scoped_ptr<MockTask> task1(new MockTask());
   scoped_ptr<MockTask> task2(new MockTask());
 
-  scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize);
+  SetWorkBatchSizeForTesting(kWorkBatchSize);
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
@@ -128,7 +129,7 @@
   scoped_ptr<MockTask> task2(new MockTask());
   scoped_ptr<MockTask> task3(new MockTask());
 
-  scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize);
+  SetWorkBatchSizeForTesting(kWorkBatchSize);
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
@@ -199,4 +200,4 @@
   thread_.removeTaskObserver(&observer);
 }
 
-}  // namespace content
+}  // namespace scheduler
diff --git a/components/scheduler/scheduler.gni b/components/scheduler/scheduler.gni
new file mode 100644
index 0000000..4a93aed
--- /dev/null
+++ b/components/scheduler/scheduler.gni
@@ -0,0 +1,12 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This file defines the scheduler gypi values. This file is read once and
+# cached, which is a performance optimization that allows us to share the
+# results of parsing the .gypi file between the public and private BUILD.gn
+# files. It also saves us from duplicating this exec_script call.
+scheduler_gypi_values = exec_script("//build/gypi_to_gn.py",
+                                    [ rebase_path("scheduler.gypi") ],
+                                    "scope",
+                                    [ "scheduler.gypi" ])
diff --git a/components/scheduler/scheduler.gyp b/components/scheduler/scheduler.gyp
new file mode 100644
index 0000000..a9c4402
--- /dev/null
+++ b/components/scheduler/scheduler.gyp
@@ -0,0 +1,51 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'variables': {
+    # This turns on e.g. the filename-based detection of which
+    # platforms to include source files on (e.g. files ending in
+    # _mac.h or _mac.cc are only compiled on MacOSX).
+    'chromium_code': 1,
+  },
+  'includes': [
+    'scheduler.gypi',
+  ],
+  'targets': [
+    {
+      # GN version: //components/scheduler:common
+      'target_name': 'scheduler_common',
+      'type': 'static_library',
+      'include_dirs': [
+        '../..',
+      ],
+      'sources': [
+        '<@(scheduler_common_sources)',
+      ],
+    },
+    {
+      # GN version: //components/scheduler:scheduler
+      'target_name': 'scheduler',
+      'type': '<(component)',
+      'dependencies': [
+        'scheduler_common',
+        '../../base/base.gyp:base',
+        '../../cc/cc.gyp:cc',
+        '../../third_party/WebKit/public/blink.gyp:blink',
+        '../../ui/gfx/gfx.gyp:gfx',
+      ],
+      'include_dirs': [
+        '../..',
+      ],
+      'defines': [
+        'SCHEDULER_IMPLEMENTATION',
+      ],
+      # Disable c4267 warnings until we fix size_t to int truncations.
+      'msvs_disabled_warnings': [ 4267, ],
+      'sources': [
+        '<@(scheduler_sources)',
+      ],
+    },
+  ],
+}
diff --git a/components/scheduler/scheduler.gypi b/components/scheduler/scheduler.gypi
new file mode 100644
index 0000000..72a3f5c4b
--- /dev/null
+++ b/components/scheduler/scheduler.gypi
@@ -0,0 +1,56 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'variables': {
+    'scheduler_common_sources': [
+      'common/scheduler_switches.cc',
+      'common/scheduler_switches.h',
+    ],
+    'scheduler_sources': [
+      'child/cancelable_closure_holder.cc',
+      'child/cancelable_closure_holder.h',
+      'child/child_scheduler.h',
+      'child/nestable_single_thread_task_runner.h',
+      'child/null_idle_task_runner.cc',
+      'child/null_idle_task_runner.h',
+      'child/null_worker_scheduler.cc',
+      'child/null_worker_scheduler.h',
+      'child/prioritizing_task_queue_selector.cc',
+      'child/prioritizing_task_queue_selector.h',
+      'child/scheduler_helper.cc',
+      'child/scheduler_helper.h',
+      'child/scheduler_message_loop_delegate.cc',
+      'child/scheduler_message_loop_delegate.h',
+      'child/single_thread_idle_task_runner.cc',
+      'child/single_thread_idle_task_runner.h',
+      'child/task_queue_manager.cc',
+      'child/task_queue_manager.h',
+      'child/task_queue_selector.h',
+      'child/time_source.cc',
+      'child/time_source.h',
+      'child/web_scheduler_impl.cc',
+      'child/web_scheduler_impl.h',
+      'child/webthread_base.cc',
+      'child/webthread_base.h',
+      'child/webthread_impl_for_worker_scheduler.cc',
+      'child/webthread_impl_for_worker_scheduler.h',
+      'child/worker_scheduler.cc',
+      'child/worker_scheduler.h',
+      'child/worker_scheduler_impl.cc',
+      'child/worker_scheduler_impl.h',
+      'renderer/deadline_task_runner.cc',
+      'renderer/deadline_task_runner.h',
+      'renderer/null_renderer_scheduler.cc',
+      'renderer/null_renderer_scheduler.h',
+      'renderer/renderer_scheduler.cc',
+      'renderer/renderer_scheduler.h',
+      'renderer/renderer_scheduler_impl.cc',
+      'renderer/renderer_scheduler_impl.h',
+      'renderer/webthread_impl_for_renderer_scheduler.cc',
+      'renderer/webthread_impl_for_renderer_scheduler.h',
+      'scheduler_export.h',
+    ],
+  },
+}
diff --git a/components/scheduler/scheduler_export.h b/components/scheduler/scheduler_export.h
new file mode 100644
index 0000000..b441b84
--- /dev/null
+++ b/components/scheduler/scheduler_export.h
@@ -0,0 +1,29 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_SCHEDULER_EXPORT_H_
+#define COMPONENTS_SCHEDULER_SCHEDULER_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(SCHEDULER_IMPLEMENTATION)
+#define SCHEDULER_EXPORT __declspec(dllexport)
+#else
+#define SCHEDULER_EXPORT __declspec(dllimport)
+#endif  // defined(SCHEDULER_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(SCHEDULER_IMPLEMENTATION)
+#define SCHEDULER_EXPORT __attribute__((visibility("default")))
+#else
+#define SCHEDULER_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define SCHEDULER_EXPORT
+#endif
+
+#endif  // COMPONENTS_SCHEDULER_SCHEDULER_EXPORT_H_
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc
index cb4c6db..8c565f2 100644
--- a/components/search_engines/template_url.cc
+++ b/components/search_engines/template_url.cc
@@ -1430,7 +1430,7 @@
   }
 
   std::string new_params(old_params, 0, search_terms_position.begin);
-  new_params += base::UTF16ToUTF8(search_terms_args.search_terms);
+  new_params += base::UTF16ToUTF8(encoded_terms);
   new_params += old_params.substr(search_terms_position.end());
   GURL::Replacements replacements;
 
diff --git a/components/search_engines/template_url_unittest.cc b/components/search_engines/template_url_unittest.cc
index 861ce79..2ab7428 100644
--- a/components/search_engines/template_url_unittest.cc
+++ b/components/search_engines/template_url_unittest.cc
@@ -1154,8 +1154,8 @@
 
   // Russian text encoded with UTF-8.
   EXPECT_TRUE(url.ExtractSearchTermsFromURL(
-      GURL("http://utf-8.ru/?q=\xD0\x97\xD0\xB4\xD1\x80\xD0\xB0\xD0\xB2\xD1\x81"
-           "\xD1\x82\xD0\xB2\xD1\x83\xD0\xB9,+\xD0\xBC\xD0\xB8\xD1\x80!"),
+      GURL("http://utf-8.ru/?q=%D0%97%D0%B4%D1%80%D0%B0%D0%B2%D1%81%D1%82"
+           "%D0%B2%D1%83%D0%B9,+%D0%BC%D0%B8%D1%80!"),
       search_terms_data_, &result));
   EXPECT_EQ(
       base::WideToUTF16(
@@ -1164,16 +1164,16 @@
       result);
 
   EXPECT_TRUE(url.ExtractSearchTermsFromURL(
-      GURL("http://utf-8.ru/#q=\xD0\xB4\xD0\xB2\xD0\xB0+\xD1\x81\xD0\xBB"
-           "\xD0\xBE\xD0\xB2\xD0\xB0"),
+      GURL("http://utf-8.ru/#q=%D0%B4%D0%B2%D0%B0+%D1%81%D0%BB%D0%BE%D0%B2"
+           "%D0%B0"),
       search_terms_data_, &result));
   EXPECT_EQ(
       base::WideToUTF16(L"\x0434\x0432\x0430 \x0441\x043B\x043E\x0432\x0430"),
       result);
 
   EXPECT_TRUE(url.ExtractSearchTermsFromURL(
-      GURL("http://utf-8.ru/path/\xD0\xB1\xD1\x83\xD0\xBA\xD0\xB2\xD1\x8B%20"
-           "\xD0\x90%20\xD0\xB8%20A"),
+      GURL("http://utf-8.ru/path/%D0%B1%D1%83%D0%BA%D0%B2%D1%8B%20%D0%90%20"
+           "%D0%B8%20A"),
       search_terms_data_, &result));
   EXPECT_EQ(
       base::WideToUTF16(L"\x0431\x0443\x043A\x0432\x044B \x0410 \x0438 A"),
@@ -1313,7 +1313,7 @@
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/?q=something"), search_terms,
       search_terms_data_, &result));
-  EXPECT_EQ(GURL("http://google.com/?q=Bob%20Morane"), result);
+  EXPECT_EQ(GURL("http://google.com/?q=Bob+Morane"), result);
 
   result = GURL("http://should.not.change.com");
   EXPECT_FALSE(url.ReplaceSearchTermsInURL(
@@ -1328,7 +1328,7 @@
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("https://google.com/?q=foo"), search_terms,
       search_terms_data_, &result));
-  EXPECT_EQ(GURL("https://google.com/?q=Bob%20Morane"), result);
+  EXPECT_EQ(GURL("https://google.com/?q=Bob+Morane"), result);
 
   EXPECT_FALSE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com:8080/?q=foo"), search_terms,
@@ -1337,26 +1337,26 @@
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/?q=1+2+3&b=456"), search_terms,
       search_terms_data_, &result));
-  EXPECT_EQ(GURL("http://google.com/?q=Bob%20Morane&b=456"), result);
+  EXPECT_EQ(GURL("http://google.com/?q=Bob+Morane&b=456"), result);
 
   // Note: Spaces in REF parameters are not escaped. See TryEncoding() in
   // template_url.cc for details.
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/alt/?q=123#q=456"), search_terms,
       search_terms_data_, &result));
-  EXPECT_EQ(GURL("http://google.com/alt/?q=123#q=Bob Morane"), result);
+  EXPECT_EQ(GURL("http://google.com/alt/?q=123#q=Bob+Morane"), result);
 
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/alt/?a=012&q=123&b=456#f=789"), search_terms,
       search_terms_data_, &result));
-  EXPECT_EQ(GURL("http://google.com/alt/?a=012&q=Bob%20Morane&b=456#f=789"),
+  EXPECT_EQ(GURL("http://google.com/alt/?a=012&q=Bob+Morane&b=456#f=789"),
             result);
 
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/alt/?a=012&q=123&b=456#j=abc&q=789&h=def9"),
       search_terms, search_terms_data_, &result));
   EXPECT_EQ(GURL("http://google.com/alt/?a=012&q=123&b=456"
-                 "#j=abc&q=Bob Morane&h=def9"), result);
+                 "#j=abc&q=Bob+Morane&h=def9"), result);
 
   EXPECT_FALSE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/alt/?q="), search_terms,
@@ -1377,7 +1377,7 @@
   EXPECT_TRUE(url.ReplaceSearchTermsInURL(
       GURL("http://google.com/alt/?q=#q=123"), search_terms,
       search_terms_data_, &result));
-  EXPECT_EQ(GURL("http://google.com/alt/?q=#q=Bob Morane"), result);
+  EXPECT_EQ(GURL("http://google.com/alt/?q=#q=Bob+Morane"), result);
 }
 
 TEST_F(TemplateURLTest, ReplaceSearchTermsInURLPath) {
@@ -1404,6 +1404,75 @@
   EXPECT_EQ(GURL("http://should.not.change.com"), result);
 }
 
+// Checks that the ReplaceSearchTermsInURL function works correctly
+// for search terms containing non-latin characters for a search engine
+// using UTF-8 input encoding.
+TEST_F(TemplateURLTest, ReplaceSearchTermsInUTF8URL) {
+  TemplateURLData data;
+  data.SetURL("http://utf-8.ru/?q={searchTerms}");
+  data.alternate_urls.push_back("http://utf-8.ru/#q={searchTerms}");
+  data.alternate_urls.push_back("http://utf-8.ru/path/{searchTerms}");
+  TemplateURL url(data);
+
+  // Russian text which will be encoded with UTF-8.
+  TemplateURLRef::SearchTermsArgs search_terms(base::WideToUTF16(
+      L"\x0442\x0435\x043A\x0441\x0442"));
+  GURL result;
+
+  EXPECT_TRUE(url.ReplaceSearchTermsInURL(
+      GURL("http://utf-8.ru/?q=a+b"), search_terms, search_terms_data_,
+      &result));
+  EXPECT_EQ(GURL("http://utf-8.ru/?q=%D1%82%D0%B5%D0%BA%D1%81%D1%82"),
+            result);
+
+  EXPECT_TRUE(url.ReplaceSearchTermsInURL(
+      GURL("http://utf-8.ru/#q=a+b"), search_terms, search_terms_data_,
+      &result));
+  EXPECT_EQ(GURL("http://utf-8.ru/#q=%D1%82%D0%B5%D0%BA%D1%81%D1%82"),
+            result);
+
+  EXPECT_TRUE(url.ReplaceSearchTermsInURL(
+      GURL("http://utf-8.ru/path/a%20b"), search_terms, search_terms_data_,
+      &result));
+  EXPECT_EQ(GURL("http://utf-8.ru/path/%D1%82%D0%B5%D0%BA%D1%81%D1%82"),
+            result);
+}
+
+// Checks that the ReplaceSearchTermsInURL function works correctly
+// for search terms containing non-latin characters for a search engine
+// using non UTF-8 input encoding.
+TEST_F(TemplateURLTest, ReplaceSearchTermsInNonUTF8URL) {
+  TemplateURLData data;
+  data.SetURL("http://windows-1251.ru/?q={searchTerms}");
+  data.alternate_urls.push_back("http://windows-1251.ru/#q={searchTerms}");
+  data.alternate_urls.push_back("http://windows-1251.ru/path/{searchTerms}");
+  data.input_encodings.push_back("windows-1251");
+  TemplateURL url(data);
+
+  // Russian text which will be encoded with Windows-1251.
+  TemplateURLRef::SearchTermsArgs search_terms(base::WideToUTF16(
+      L"\x0442\x0435\x043A\x0441\x0442"));
+  GURL result;
+
+  EXPECT_TRUE(url.ReplaceSearchTermsInURL(
+      GURL("http://windows-1251.ru/?q=a+b"), search_terms, search_terms_data_,
+      &result));
+  EXPECT_EQ(GURL("http://windows-1251.ru/?q=%F2%E5%EA%F1%F2"),
+            result);
+
+  EXPECT_TRUE(url.ReplaceSearchTermsInURL(
+      GURL("http://windows-1251.ru/#q=a+b"), search_terms, search_terms_data_,
+      &result));
+  EXPECT_EQ(GURL("http://windows-1251.ru/#q=%F2%E5%EA%F1%F2"),
+            result);
+
+  EXPECT_TRUE(url.ReplaceSearchTermsInURL(
+      GURL("http://windows-1251.ru/path/a%20b"), search_terms,
+      search_terms_data_, &result));
+  EXPECT_EQ(GURL("http://windows-1251.ru/path/%F2%E5%EA%F1%F2"),
+            result);
+}
+
 // Test the |suggest_query_params| field of SearchTermsArgs.
 TEST_F(TemplateURLTest, SuggestQueryParams) {
   TemplateURLData data;
diff --git a/components/signin.gypi b/components/signin.gypi
index 4030c5a1..2bad402 100644
--- a/components/signin.gypi
+++ b/components/signin.gypi
@@ -62,8 +62,6 @@
         'signin/core/browser/profile_oauth2_token_service.h',
         'signin/core/browser/refresh_token_annotation_request.cc',
         'signin/core/browser/refresh_token_annotation_request.h',
-        'signin/core/browser/signin_account_id_helper.cc',
-        'signin/core/browser/signin_account_id_helper.h',
         'signin/core/browser/signin_client.h',
         'signin/core/browser/signin_error_controller.cc',
         'signin/core/browser/signin_error_controller.h',
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn
index df217e0b..5e9d59aa 100644
--- a/components/signin/core/browser/BUILD.gn
+++ b/components/signin/core/browser/BUILD.gn
@@ -20,8 +20,6 @@
     "profile_oauth2_token_service.h",
     "refresh_token_annotation_request.cc",
     "refresh_token_annotation_request.h",
-    "signin_account_id_helper.cc",
-    "signin_account_id_helper.h",
     "signin_client.h",
     "signin_error_controller.cc",
     "signin_error_controller.h",
diff --git a/components/signin/core/browser/signin_account_id_helper.cc b/components/signin/core/browser/signin_account_id_helper.cc
deleted file mode 100644
index 9288fff3..0000000
--- a/components/signin/core/browser/signin_account_id_helper.cc
+++ /dev/null
@@ -1,170 +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 "components/signin/core/browser/signin_account_id_helper.h"
-
-#include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_tracker.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "components/signin/core/browser/signin_client.h"
-#include "components/signin/core/common/signin_pref_names.h"
-#include "google_apis/gaia/gaia_oauth_client.h"
-
-// TODO(guohui): this class should be moved to a more generic place for reuse.
-class SigninAccountIdHelper::GaiaIdFetcher
-    : public OAuth2TokenService::Consumer,
-      public gaia::GaiaOAuthClient::Delegate {
- public:
-  GaiaIdFetcher(SigninClient* client,
-                ProfileOAuth2TokenService* token_service,
-                SigninManagerBase* signin_manager,
-                SigninAccountIdHelper* signin_account_id_helper);
-  ~GaiaIdFetcher() override;
-
-  // OAuth2TokenService::Consumer implementation.
-  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.
-  void OnGetUserIdResponse(const std::string& gaia_id) override;
-  void OnOAuthError() override;
-  void OnNetworkError(int response_code) override;
-
- private:
-  void Start();
-
-  SigninClient* client_;
-  ProfileOAuth2TokenService* token_service_;
-  SigninManagerBase* signin_manager_;
-  SigninAccountIdHelper* signin_account_id_helper_;
-
-  scoped_ptr<OAuth2TokenService::Request> login_token_request_;
-  scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(GaiaIdFetcher);
-};
-
-SigninAccountIdHelper::GaiaIdFetcher::GaiaIdFetcher(
-    SigninClient* client,
-    ProfileOAuth2TokenService* token_service,
-    SigninManagerBase* signin_manager,
-    SigninAccountIdHelper* signin_account_id_helper)
-    : OAuth2TokenService::Consumer("gaia_id_fetcher"),
-      client_(client),
-      token_service_(token_service),
-      signin_manager_(signin_manager),
-      signin_account_id_helper_(signin_account_id_helper) {
-  Start();
-}
-
-SigninAccountIdHelper::GaiaIdFetcher::~GaiaIdFetcher() {}
-
-void SigninAccountIdHelper::GaiaIdFetcher::Start() {
-  OAuth2TokenService::ScopeSet scopes;
-  scopes.insert("https://www.googleapis.com/auth/userinfo.profile");
-  login_token_request_ = token_service_->StartRequest(
-      signin_manager_->GetAuthenticatedAccountId(), scopes, this);
-}
-
-void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenSuccess(
-    const OAuth2TokenService::Request* request,
-    const std::string& access_token,
-    const base::Time& expiration_time) {
-  DCHECK_EQ(request, login_token_request_.get());
-
-  gaia_oauth_client_.reset(
-      new gaia::GaiaOAuthClient(client_->GetURLRequestContext()));
-
-  const int kMaxGetUserIdRetries = 3;
-  gaia_oauth_client_->GetUserId(access_token, kMaxGetUserIdRetries, this);
-}
-
-void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenFailure(
-    const OAuth2TokenService::Request* request,
-    const GoogleServiceAuthError& error) {
-  VLOG(1) << "OnGetTokenFailure: " << error.error_message();
-  DCHECK_EQ(request, login_token_request_.get());
-  signin_account_id_helper_->OnPrimaryAccountIdFetched("");
-}
-
-void SigninAccountIdHelper::GaiaIdFetcher::OnGetUserIdResponse(
-    const std::string& gaia_id) {
-  signin_account_id_helper_->OnPrimaryAccountIdFetched(gaia_id);
-}
-
-void SigninAccountIdHelper::GaiaIdFetcher::OnOAuthError() {
-  VLOG(1) << "OnOAuthError";
-}
-
-void SigninAccountIdHelper::GaiaIdFetcher::OnNetworkError(int response_code) {
-  VLOG(1) << "OnNetworkError " << response_code;
-}
-
-SigninAccountIdHelper::SigninAccountIdHelper(
-    SigninClient* client,
-    ProfileOAuth2TokenService* token_service,
-    SigninManagerBase* signin_manager)
-    : client_(client),
-      token_service_(token_service),
-      signin_manager_(signin_manager) {
-  DCHECK(client_);
-  DCHECK(token_service_);
-  DCHECK(signin_manager_);
-  signin_manager_->AddObserver(this);
-  std::string primary_email = signin_manager_->GetAuthenticatedAccountId();
-  if (!primary_email.empty() &&
-      token_service_->RefreshTokenIsAvailable(primary_email) &&
-      !disable_for_test_) {
-    id_fetcher_.reset(
-        new GaiaIdFetcher(client_, token_service_, signin_manager_, this));
-  }
-  token_service_->AddObserver(this);
-}
-
-SigninAccountIdHelper::~SigninAccountIdHelper() {
-  signin_manager_->RemoveObserver(this);
-  token_service_->RemoveObserver(this);
-}
-
-void SigninAccountIdHelper::GoogleSignedOut(const std::string& account_id,
-                                            const std::string& username) {
-  client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
-}
-
-void SigninAccountIdHelper::OnRefreshTokenAvailable(
-    const std::string& account_id) {
-  // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is
-  // fixed.
-  tracked_objects::ScopedTracker tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "422460 SigninAccountIdHelper::OnRefreshTokenAvailable"));
-
-  if (account_id == signin_manager_->GetAuthenticatedAccountId()) {
-    std::string current_gaia_id =
-        client_->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId);
-    if (current_gaia_id.empty() && !disable_for_test_) {
-      id_fetcher_.reset(
-          new GaiaIdFetcher(client_, token_service_, signin_manager_, this));
-    }
-  }
-}
-
-void SigninAccountIdHelper::OnPrimaryAccountIdFetched(
-    const std::string& gaia_id) {
-  if (!gaia_id.empty()) {
-    client_->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId,
-                                   gaia_id);
-  }
-}
-
-// static
-bool SigninAccountIdHelper::disable_for_test_ = false;
-
-// static
-void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test) {
-  disable_for_test_ = disable_for_test;
-}
diff --git a/components/signin/core/browser/signin_account_id_helper.h b/components/signin/core/browser/signin_account_id_helper.h
deleted file mode 100644
index 8c93896..0000000
--- a/components/signin/core/browser/signin_account_id_helper.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 COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ACCOUNT_ID_HELPER_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ACCOUNT_ID_HELPER_H_
-
-#include "components/signin/core/browser/signin_manager.h"
-#include "google_apis/gaia/gaia_oauth_client.h"
-#include "google_apis/gaia/oauth2_token_service.h"
-
-class CookieSettings;
-class GaiaAuthFetcher;
-class ProfileOAuth2TokenService;
-class SigninClient;
-
-// The helper class for managing the obfuscated GAIA ID of the primary
-// account. It fetches the ID when user first signs into Chrome or when user
-// opens a connected Chrome profile without an obfuscated GAIA ID, and stores
-// the ID in the profile preference.
-class SigninAccountIdHelper : public SigninManagerBase::Observer,
-                              public OAuth2TokenService::Observer {
- public:
-  SigninAccountIdHelper(SigninClient* client,
-                        ProfileOAuth2TokenService* token_service,
-                        SigninManagerBase* signin_manager);
-  ~SigninAccountIdHelper() override;
-
-  // SigninManagerBase::Observer:
-  void GoogleSignedOut(const std::string& account_id,
-                       const std::string& username) override;
-
-  // OAuth2TokenService::Observer:
-  void OnRefreshTokenAvailable(const std::string& account_id) override;
-
-  // Disables network requests for testing to avoid messing up with irrelevant
-  // tests.
-  static void SetDisableForTest(bool disable_for_test);
-
- private:
-  // Invoked when receiving the response for |account_id_fetcher_|.
-  void OnPrimaryAccountIdFetched(const std::string& gaia_id);
-
-  // Helper class for fetching the obfuscated account ID.
-  class GaiaIdFetcher;
-  scoped_ptr<GaiaIdFetcher> id_fetcher_;
-
-  static bool disable_for_test_;
-
-  SigninClient* client_;
-  ProfileOAuth2TokenService* token_service_;
-  SigninManagerBase* signin_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(SigninAccountIdHelper);
-};
-
-#endif  // COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ACCOUNT_ID_HELPER_H_
diff --git a/components/storage_monitor/image_capture_device.mm b/components/storage_monitor/image_capture_device.mm
index 1008bfd..29285d9 100644
--- a/components/storage_monitor/image_capture_device.mm
+++ b/components/storage_monitor/image_capture_device.mm
@@ -13,7 +13,7 @@
 
 base::File::Error RenameFile(const base::FilePath& downloaded_filename,
                              const base::FilePath& desired_filename) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   bool success = base::ReplaceFile(downloaded_filename, desired_filename, NULL);
   return success ? base::File::FILE_OK : base::File::FILE_ERROR_NOT_FOUND;
 }
@@ -22,7 +22,7 @@
     base::WeakPtr<ImageCaptureDeviceListener> listener,
     const std::string& name,
     const base::File::Error& result) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (listener)
     listener->DownloadedFile(name, result);
 }
@@ -75,18 +75,18 @@
 
 - (void)setListener:(base::WeakPtr<storage_monitor::ImageCaptureDeviceListener>)
         listener {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   listener_ = listener;
 }
 
 - (void)open {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(listener_);
   [camera_ requestOpenSession];
 }
 
 - (void)close {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   closing_ = true;
   [camera_ cancelDownload];
   [camera_ requestCloseSession];
@@ -100,7 +100,7 @@
 
 - (void)downloadFile:(const std::string&)name
            localPath:(const base::FilePath&)localPath {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Find the file with that name and start download.
   for (ICCameraItem* item in [camera_ mediaFiles]) {
diff --git a/components/storage_monitor/mtab_watcher_linux.cc b/components/storage_monitor/mtab_watcher_linux.cc
index 00a9d0cc..31dda986 100644
--- a/components/storage_monitor/mtab_watcher_linux.cc
+++ b/components/storage_monitor/mtab_watcher_linux.cc
@@ -38,7 +38,7 @@
     : mtab_path_(mtab_path),
       delegate_(delegate),
       weak_ptr_factory_(this) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   bool ret = file_watcher_.Watch(
       mtab_path_, false,
       base::Bind(&MtabWatcherLinux::OnFilePathChanged,
@@ -52,11 +52,11 @@
 }
 
 MtabWatcherLinux::~MtabWatcherLinux() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 }
 
 void MtabWatcherLinux::ReadMtab() const {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   FILE* fp = setmntent(mtab_path_.value().c_str(), "r");
   if (!fp)
@@ -87,7 +87,7 @@
 
 void MtabWatcherLinux::OnFilePathChanged(
     const base::FilePath& path, bool error) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   if (path != mtab_path_) {
     // This cannot happen unless FilePathWatcher is buggy. Just ignore this
diff --git a/components/storage_monitor/portable_device_watcher_win.cc b/components/storage_monitor/portable_device_watcher_win.cc
index 3f90fee..8095a89d 100644
--- a/components/storage_monitor/portable_device_watcher_win.cc
+++ b/components/storage_monitor/portable_device_watcher_win.cc
@@ -489,7 +489,7 @@
 }
 
 void PortableDeviceWatcherWin::Init(HWND hwnd) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   notifications_ = RegisterPortableDeviceNotification(hwnd);
   base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
   media_task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior(
@@ -499,7 +499,7 @@
 }
 
 void PortableDeviceWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!IsPortableDeviceStructure(data))
     return;
 
@@ -514,7 +514,7 @@
     const std::string& storage_device_id,
     base::string16* device_location,
     base::string16* storage_object_id) const {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(device_location);
   DCHECK(storage_object_id);
   MTPStorageMap::const_iterator storage_map_iter =
@@ -573,7 +573,7 @@
 
 void PortableDeviceWatcherWin::EnumerateAttachedDevices() {
   DCHECK(media_task_runner_.get());
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   Devices* devices = new Devices;
   base::PostTaskAndReplyWithResult(
       media_task_runner_.get(), FROM_HERE,
@@ -584,7 +584,7 @@
 
 void PortableDeviceWatcherWin::OnDidEnumerateAttachedDevices(
     const Devices* devices, const bool result) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(devices);
   if (!result)
     return;
@@ -597,7 +597,7 @@
 void PortableDeviceWatcherWin::HandleDeviceAttachEvent(
     const base::string16& pnp_device_id) {
   DCHECK(media_task_runner_.get());
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DeviceDetails* device_details = new DeviceDetails;
   base::PostTaskAndReplyWithResult(
       media_task_runner_.get(), FROM_HERE,
@@ -609,7 +609,7 @@
 
 void PortableDeviceWatcherWin::OnDidHandleDeviceAttachEvent(
     const DeviceDetails* device_details, const bool result) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(device_details);
   if (!result)
     return;
@@ -646,7 +646,7 @@
 
 void PortableDeviceWatcherWin::HandleDeviceDetachEvent(
     const base::string16& pnp_device_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   MTPDeviceMap::iterator device_iter = device_map_.find(pnp_device_id);
   if (device_iter == device_map_.end())
     return;
diff --git a/components/storage_monitor/storage_monitor_chromeos.cc b/components/storage_monitor/storage_monitor_chromeos.cc
index 92e7cfd..6227ee0 100644
--- a/components/storage_monitor/storage_monitor_chromeos.cc
+++ b/components/storage_monitor/storage_monitor_chromeos.cc
@@ -79,7 +79,7 @@
 // Returns whether the mount point in |mount_info| is a media device or not.
 bool CheckMountedPathOnFileThread(
     const DiskMountManager::MountPointInfo& mount_info) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
   return MediaStorageUtil::HasDcim(base::FilePath(mount_info.mount_path));
 }
 
@@ -115,7 +115,7 @@
 }
 
 void StorageMonitorCros::CheckExistingMountPoints() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   const DiskMountManager::MountPointMap& mount_point_map =
       DiskMountManager::GetInstance()->mount_points();
   for (DiskMountManager::MountPointMap::const_iterator it =
@@ -148,7 +148,7 @@
     DiskMountManager::MountEvent event,
     chromeos::MountError error_code,
     const DiskMountManager::MountPointInfo& mount_info) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Ignore mount points that are not devices.
   if (mount_info.mount_type != chromeos::MOUNT_TYPE_DEVICE)
@@ -277,7 +277,7 @@
 void StorageMonitorCros::AddMountedPath(
     const DiskMountManager::MountPointInfo& mount_info,
     bool has_dcim) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (ContainsKey(mount_map_, mount_info.mount_path)) {
     // CheckExistingMountPointsOnUIThread() added the mount point information
diff --git a/components/storage_monitor/storage_monitor_mac.mm b/components/storage_monitor/storage_monitor_mac.mm
index d8055dc..22a884b 100644
--- a/components/storage_monitor/storage_monitor_mac.mm
+++ b/components/storage_monitor/storage_monitor_mac.mm
@@ -47,7 +47,7 @@
 
 StorageInfo BuildStorageInfo(
     CFDictionaryRef dict, std::string* bsd_name) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   CFStringRef device_bsd_name = base::mac::GetValueFromDictionary<CFStringRef>(
       dict, kDADiskDescriptionMediaBSDNameKey);
@@ -109,7 +109,7 @@
     const base::WeakPtr<StorageMonitorMac>& monitor,
     base::ScopedCFTypeRef<CFDictionaryRef> dict,
     StorageMonitorMac::UpdateType update_type) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
   std::string bsd_name;
   StorageInfo info = BuildStorageInfo(dict, &bsd_name);
@@ -209,7 +209,7 @@
     const std::string& bsd_name,
     const StorageInfo& info,
     UpdateType update_type) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   pending_disk_updates_--;
   bool initialization_complete = false;
@@ -348,7 +348,7 @@
 void StorageMonitorMac::GetDiskInfoAndUpdate(
     DADiskRef disk,
     StorageMonitorMac::UpdateType update_type) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   pending_disk_updates_++;
 
diff --git a/components/test/DEPS b/components/test/DEPS
index ad35ec8..ec6ab2f 100644
--- a/components/test/DEPS
+++ b/components/test/DEPS
@@ -2,7 +2,17 @@
   # To initialize the global data of content_settings.
   "+components/content_settings/core/common",
   "+components/invalidation/android/component_jni_registrar.h",
+  "+content/public/android/java/src/org/chromium/content/browser",
+  "+content/public/app/content_jni_onload.h",
+  "+content/public/app/content_main.h",
+  "+content/public/common/content_switches.h",
   "+content/public/test",
+  "+content/shell/android/java/src/org/chromium/content_shell",
+  "+content/shell/android/shell_jni_registrar.h",
+  "+content/shell/app/shell_main_delegate.h",
+  "+jni",
+  "+media/base/media_switches.h",
+  "+ui/android/java/src/org/chromium/ui/base",
   "+ui/base/android/ui_base_jni_registrar.h",
   "+ui/base/resource/resource_bundle.h",
   "+ui/base/ui_base_paths.h",
diff --git a/components/test/android/OWNERS b/components/test/android/OWNERS
new file mode 100644
index 0000000..c43b4b3
--- /dev/null
+++ b/components/test/android/OWNERS
@@ -0,0 +1,3 @@
+jaekyun@chromium.org
+sievers@chromium.org
+tedchoc@chromium.org
diff --git a/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2 b/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2
new file mode 100644
index 0000000..3ac010d
--- /dev/null
+++ b/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2015 The Chromium Authors. All rights reserved.
+
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.chromium.components_browsertests_apk">
+
+    <application android:name="ComponentsBrowserTestsApplication"
+            android:label="ComponentsBrowserTests">
+        <activity android:name="ComponentsBrowserTestsActivity"
+                  android:launchMode="singleTask"
+                  android:theme="@android:style/Theme.Holo.Light.NoActionBar"
+                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
+                  android:hardwareAccelerated="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <!-- The following service entries exist in order to allow us to
+             start more than one sandboxed process. -->
+
+        <!-- NOTE: If you change the values of "android:process" for any of the below services,
+             you also need to update kHelperProcessExecutableName in chrome_constants.cc. -->
+        {% set num_sandboxed_services = 20 %}
+        <meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES"
+                   android:value="{{ num_sandboxed_services }}"/>
+        {% for i in range(num_sandboxed_services) %}
+        <service android:name="org.chromium.content.app.SandboxedProcessService{{ i }}"
+                 android:process=":sandboxed_process{{ i }}"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        {% endfor %}
+
+        {% set num_privileged_services = 3 %}
+        <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
+                   android:value="{{ num_privileged_services }}"/>
+        {% for i in range(num_privileged_services) %}
+        <service android:name="org.chromium.content.app.PrivilegedProcessService{{ i }}"
+                 android:process=":privileged_process{{ i }}"
+                 android:isolatedProcess="false"
+                 android:exported="false" />
+        {% endfor %}
+    </application>
+
+    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />
+    <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" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.VIBRATE"/>
+    <uses-permission android:name="android.permission.WAKE_LOCK"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+</manifest>
diff --git a/components/test/android/browsertests_apk/components_browser_tests_android.cc b/components/test/android/browsertests_apk/components_browser_tests_android.cc
new file mode 100644
index 0000000..baf8efe
--- /dev/null
+++ b/components/test/android/browsertests_apk/components_browser_tests_android.cc
@@ -0,0 +1,99 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This class sets up the environment for running the content browser tests
+// inside an android application.
+
+#include <android/log.h>
+#include <unistd.h>
+
+#include "base/android/base_jni_registrar.h"
+#include "base/android/fifo_utils.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/library_loader/library_loader_hooks.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/base_switches.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/test_launcher.h"
+#include "jni/ComponentsBrowserTestsActivity_jni.h"
+#include "media/base/media_switches.h"
+#include "testing/android/native_test/native_test_util.h"
+
+using testing::native_test_util::ArgsToArgv;
+using testing::native_test_util::ParseArgsFromCommandLineFile;
+using testing::native_test_util::ScopedMainEntryLogger;
+
+// The main function of the program to be wrapped as an apk.
+extern int main(int argc, char** argv);
+
+namespace {
+
+// The test runner script writes the command line file in
+// "/data/local/tmp".
+static const char kCommandLineFilePath[] =
+    "/data/local/tmp/components-browser-tests-command-line";
+
+}  // namespace
+
+namespace components {
+
+// TODO(jaekyun): Refactor and deduplicate with
+// testing/android/native_test/native_test_launcher.cc (http://crbug.com/476410)
+static void RunTests(JNIEnv* env,
+                     jobject obj,
+                     jstring jfiles_dir,
+                     jobject app_context) {
+  // Command line basic initialization, will be fully initialized later.
+  static const char* const kInitialArgv[] = {"ComponentsBrowserTestsActivity"};
+  base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
+
+  // Set the application context in base.
+  base::android::ScopedJavaLocalRef<jobject> scoped_context(
+      env, env->NewLocalRef(app_context));
+  base::android::InitApplicationContext(env, scoped_context);
+  base::android::RegisterJni(env);
+
+  std::vector<std::string> args;
+  ParseArgsFromCommandLineFile(kCommandLineFilePath, &args);
+
+  std::vector<char*> argv;
+  int argc = ArgsToArgv(args, &argv);
+
+  // Fully initialize command line with arguments.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  command_line->AppendArguments(base::CommandLine(argc, &argv[0]), false);
+
+  // Append required switches.
+  command_line->AppendSwitch(content::kSingleProcessTestsFlag);
+  command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
+  command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
+  // Specify a socket name to not conflict with the default one used
+  // in content_shell.
+  command_line->AppendSwitchASCII(switches::kRemoteDebuggingSocketName,
+                                  "components_browsertests_devtools_remote");
+
+  // Create fifo and redirect stdout and stderr to it.
+  base::FilePath files_dir(
+      base::android::ConvertJavaStringToUTF8(env, jfiles_dir));
+  base::FilePath fifo_path(files_dir.Append(base::FilePath("test.fifo")));
+  base::android::CreateFIFO(fifo_path, 0666);
+  base::android::RedirectStream(stdout, fifo_path, "w+");
+  dup2(STDOUT_FILENO, STDERR_FILENO);
+
+  ScopedMainEntryLogger scoped_main_entry_logger;
+  main(argc, &argv[0]);
+}
+
+bool RegisterComponentsBrowserTestsAndroid(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+}  // namespace components
diff --git a/components/test/android/browsertests_apk/components_browser_tests_android.h b/components/test/android/browsertests_apk/components_browser_tests_android.h
new file mode 100644
index 0000000..a989706
--- /dev/null
+++ b/components/test/android/browsertests_apk/components_browser_tests_android.h
@@ -0,0 +1,16 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_TEST_ANDROID_BROWSERTESTS_APK_COMPONENTS_BROWSER_TESTS_ANDROID_H_
+#define COMPONENTS_TEST_ANDROID_BROWSERTESTS_APK_COMPONENTS_BROWSER_TESTS_ANDROID_H_
+
+#include <jni.h>
+
+namespace components {
+
+bool RegisterComponentsBrowserTestsAndroid(JNIEnv* env);
+
+}  // namespace components
+
+#endif  // COMPONENTS_TEST_ANDROID_BROWSERTESTS_APK_COMPONENTS_BROWSER_TESTS_ANDROID_H_
diff --git a/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc b/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc
new file mode 100644
index 0000000..e47b840
--- /dev/null
+++ b/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc
@@ -0,0 +1,40 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/jni_android.h"
+#include "base/bind.h"
+#include "components/test/android/browsertests_apk/components_browser_tests_android.h"
+#include "content/public/app/content_jni_onload.h"
+#include "content/public/app/content_main.h"
+#include "content/public/test/nested_message_pump_android.h"
+#include "content/shell/android/shell_jni_registrar.h"
+#include "content/shell/app/shell_main_delegate.h"
+
+namespace {
+
+bool RegisterJNI(JNIEnv* env) {
+  return content::android::RegisterShellJni(env) &&
+         content::NestedMessagePumpAndroid::RegisterJni(env) &&
+         components::RegisterComponentsBrowserTestsAndroid(env);
+}
+
+bool Init() {
+  content::SetContentMainDelegate(new content::ShellMainDelegate());
+  return true;
+}
+
+}  // namespace
+
+// This is called by the VM when the shared library is first loaded.
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+  std::vector<base::android::RegisterCallback> register_callbacks;
+  register_callbacks.push_back(base::Bind(&RegisterJNI));
+  std::vector<base::android::InitCallback> init_callbacks;
+  init_callbacks.push_back(base::Bind(&Init));
+  if (!content::android::OnJNIOnLoadRegisterJNI(vm, register_callbacks) ||
+      !content::android::OnJNIOnLoadInit(init_callbacks)) {
+    return -1;
+  }
+  return JNI_VERSION_1_4;
+}
diff --git a/components/test/android/browsertests_apk/res/layout/test_activity.xml b/components/test/android/browsertests_apk/res/layout/test_activity.xml
new file mode 100644
index 0000000..227ce1f
--- /dev/null
+++ b/components/test/android/browsertests_apk/res/layout/test_activity.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2015 The Chromium Authors. All rights reserved.
+
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent"
+    android:orientation="vertical">
+    <org.chromium.content_shell.ShellManager
+        android:id="@+id/shell_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java b/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java
new file mode 100644
index 0000000..bbf2461
--- /dev/null
+++ b/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java
@@ -0,0 +1,75 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components_browsertests_apk;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
+
+import org.chromium.base.JNINamespace;
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.library_loader.LibraryProcessType;
+import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.content.browser.BrowserStartupController;
+import org.chromium.content_shell.ShellManager;
+import org.chromium.ui.base.ActivityWindowAndroid;
+import org.chromium.ui.base.WindowAndroid;
+
+/**
+ * Android activity for running components browser tests
+ */
+@JNINamespace("components")
+public class ComponentsBrowserTestsActivity extends Activity {
+    private static final String TAG = "ComponentsBrowserTestsActivity";
+
+    private ShellManager mShellManager;
+    private WindowAndroid mWindowAndroid;
+
+    @Override
+    @SuppressFBWarnings("DM_EXIT")
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        try {
+            LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized();
+        } catch (ProcessInitException e) {
+            Log.i(TAG, "Cannot load components_browsertests:" + e);
+            System.exit(-1);
+        }
+        BrowserStartupController.get(getApplicationContext(), LibraryProcessType.PROCESS_BROWSER)
+                .initChromiumBrowserProcessForTests();
+
+        setContentView(R.layout.test_activity);
+        mShellManager = (ShellManager) findViewById(R.id.shell_container);
+        mWindowAndroid = new ActivityWindowAndroid(this);
+        mShellManager.setWindow(mWindowAndroid, false);
+
+        Window wind = this.getWindow();
+        wind.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+        wind.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        wind.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
+
+        new Handler().post(new Runnable() {
+            @Override
+            public void run() {
+                Log.i(TAG, "Running tests");
+                runTests();
+                Log.i(TAG, "Tests finished.");
+                finish();
+            }
+        });
+    }
+
+    private void runTests() {
+        nativeRunTests(getFilesDir().getAbsolutePath(), getApplicationContext());
+    }
+
+    private native void nativeRunTests(String filesDir, Context appContext);
+}
diff --git a/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java b/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java
new file mode 100644
index 0000000..91ee597b
--- /dev/null
+++ b/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java
@@ -0,0 +1,32 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components_browsertests_apk;
+
+import android.content.Context;
+
+import org.chromium.base.BaseChromiumApplication;
+import org.chromium.base.PathUtils;
+import org.chromium.base.ResourceExtractor;
+
+/**
+ * A basic content browser tests {@link android.app.Application}.
+ */
+public class ComponentsBrowserTestsApplication extends BaseChromiumApplication {
+    private static final String[] MANDATORY_PAK_FILES =
+            new String[] {"components_tests_resources.pak", "content_shell.pak", "icudtl.dat",
+                    "natives_blob.bin", "snapshot_blob.bin"};
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "components_shell";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        initializeApplicationParameters(this);
+    }
+
+    public static void initializeApplicationParameters(Context context) {
+        ResourceExtractor.setMandatoryPaksToExtract(MANDATORY_PAK_FILES);
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
+    }
+}
diff --git a/components/test/data/password_manager/automated_tests/environment.py b/components/test/data/password_manager/automated_tests/environment.py
index fd52754..37434650 100644
--- a/components/test/data/password_manager/automated_tests/environment.py
+++ b/components/test/data/password_manager/automated_tests/environment.py
@@ -288,7 +288,12 @@
         getattr(websitetest, test_case_name)()
       except Exception as e:
         successful = False
-        error = e.message
+        # httplib.CannotSendRequest doesn't define a message,
+        # so type(e).__name__ will at least log exception name as a reason.
+        # TODO(melandory): logging.exception(e) produces meaningful result
+        # for httplib.CannotSendRequest, so we can try to propagate information
+        # that reason is an exception to the logging phase.
+        error = "Exception %s %s" % (type(e).__name__, e)
       self.tests_results.append(
           (websitetest.name, test_case_name, successful, error))
 
diff --git a/components/test/data/password_manager/automated_tests/run_tests.py b/components/test/data/password_manager/automated_tests/run_tests.py
index d1118f0..ef114da 100644
--- a/components/test/data/password_manager/automated_tests/run_tests.py
+++ b/components/test/data/password_manager/automated_tests/run_tests.py
@@ -35,15 +35,20 @@
 You have to set up appropriate logging handlers to have the logs appear.
 """
 
-import argparse
 import ConfigParser
+import Queue
+import argparse
 import logging
+import multiprocessing
 import os
 import shutil
-import subprocess
+import stopit
 import tempfile
 import time
 
+from threading import Thread
+from collections import defaultdict
+
 import tests
 
 
@@ -51,126 +56,90 @@
 # of logging.DEBUG, which is already used for detailed test debug messages.
 SCRIPT_DEBUG = 9
 
+class Config:
+  test_cases_to_run = tests.TEST_CASES
+  save_only_fails = False
+  tests_to_run = tests.all_tests.keys()
+  max_tests_in_parallel = 1
 
-class TestRunner(object):
-  """Runs tests for a single website."""
+  def __init__(self, config_path):
+    config = ConfigParser.ConfigParser()
+    config.read(config_path)
+    if config.has_option("run_options", "tests_in_parallel"):
+      self.max_tests_in_parallel = config.getint(
+          "run_options", "tests_in_parallel")
 
-  def __init__(self, test_cmd, test_name):
-    """Initialize the TestRunner.
+    self.chrome_path = config.get("binaries", "chrome-path")
+    self.chromedriver_path = config.get("binaries", "chromedriver-path")
+    self.passwords_path = config.get("data_files", "passwords_path")
 
-    Args:
-      test_cmd: List of command line arguments to be supplied to
-        every test run.
-      test_name: Test name (e.g., facebook).
-    """
-    self.logger = logging.getLogger("run_tests")
+    if config.has_option("run_options", "tests_to_run"):
+      self.tests_to_run = config.get("run_options", "tests_to_run").split(",")
 
-    self.profile_path = tempfile.mkdtemp()
-    results = tempfile.NamedTemporaryFile(delete=False)
-    self.results_path = results.name
-    results.close()
-    self.test_cmd = test_cmd + ["--profile-path", self.profile_path,
-                                "--save-path", self.results_path]
-    self.test_name = test_name
-    # TODO(vabr): Ideally we would replace timeout with something allowing
-    # calling tests directly inside Python, and working on other platforms.
-    #
-    # The website test runs multiple scenarios, each one has an internal
-    # timeout of 200s for waiting (see |remaining_time_to_wait| and
-    # Wait() in websitetest.py). Expecting that not every scenario should
-    # take 200s, the maximum time allocated for all of them is 300s.
-    self.test_cmd = ["timeout", "300"] + self.test_cmd
-
-    self.logger.log(SCRIPT_DEBUG,
-                    "TestRunner set up for test %s, command '%s', "
-                    "profile path %s, results file %s",
-                    self.test_name, self.test_cmd, self.profile_path,
-                    self.results_path)
-
-    self.runner_process = None
-    # The tests can be flaky. This is why we try to rerun up to 3 times.
-    self.max_test_runs_left = 3
-    self.failures = []
-    self._run_test()
-
-  def get_test_result(self):
-    """Return the test results.
-
-    Returns:
-      (True, []) if the test passed.
-      (False, list_of_failures) if the test failed.
-      None if the test is still running.
-    """
-
-    test_running = self.runner_process and self.runner_process.poll() is None
-    if test_running:
-      return None
-    # Test is not running, now we have to check if we want to start it again.
-    if self._check_if_test_passed():
-      self.logger.log(SCRIPT_DEBUG, "Test %s passed", self.test_name)
-      return True, []
-    if self.max_test_runs_left == 0:
-      self.logger.log(SCRIPT_DEBUG, "Test %s failed", self.test_name)
-      return False, self.failures
-    self._run_test()
-    return None
-
-  def _check_if_test_passed(self):
-    """Returns True if and only if the test passed."""
-
-    success = False
-    if os.path.isfile(self.results_path):
-      with open(self.results_path, "r") as results:
-        # TODO(vabr): Parse the results to make sure all scenarios succeeded
-        # instead of hard-coding here the number of tests scenarios from
-        # test.py:main.
-        NUMBER_OF_TEST_SCENARIOS = 3
-        passed_scenarios = 0
-        for line in results:
-          self.failures.append(line)
-          passed_scenarios += line.count("successful='True'")
-          success = passed_scenarios == NUMBER_OF_TEST_SCENARIOS
-          if success:
-            break
-
-    self.logger.log(
-        SCRIPT_DEBUG,
-        "Test run of {0} has succeeded: {1}".format(self.test_name, success))
-    return success
-
-  def _run_test(self):
-    """Executes the command to run the test."""
-    with open(self.results_path, "w"):
-      pass  # Just clear the results file.
-    shutil.rmtree(path=self.profile_path, ignore_errors=True)
-    self.max_test_runs_left -= 1
-    self.logger.log(SCRIPT_DEBUG, "Run of test %s started", self.test_name)
-    self.runner_process = subprocess.Popen(self.test_cmd)
+    if config.has_option("run_options", "test_cases_to_run"):
+      self.test_cases_to_run = config.get(
+          "run_options", "test_cases_to_run").split(",")
+    if (config.has_option("logging", "save-only-fails")):
+      self.save_only_fails = config.getboolean("logging", "save-only-fails")
 
 
-def _apply_defaults(config, defaults):
-  """Adds default values from |defaults| to |config|.
+def LogResultsOfTestRun(config, results):
+  """ Logs |results| of a test run. """
+  logger = logging.getLogger("run_tests")
+  failed_tests = []
+  failed_tests_num = 0
+  for result in results:
+    website, test_case, success, reason = result
+    if not (config.save_only_fails and success):
+      logger.debug("Test case %s has %s on Website %s", test_case,
+                  website, {True: "passed", False: "failed"}[success])
+      if not success:
+        logger.debug("Reason of failure: %s", reason)
 
-  Note: This differs from ConfigParser's mechanism for providing defaults in
-  two aspects:
-    * The "defaults" here become explicit, and are associated with sections.
-    * Sections get created for the added defaults where needed, that is, if
-      they do not exist before.
+    if not success:
+      failed_tests.append("%s.%s" % (website, test_case))
+      failed_tests_num += 1
 
-  Args:
-    config: A ConfigParser instance to be updated
-    defaults: A dictionary mapping (section_string, option_string) pairs
-      to string values. For every section/option combination not already
-      contained in |config|, the value from |defaults| is stored in |config|.
+  logger.info("%d failed test cases out of %d, failing test cases: %s",
+              failed_tests_num, len(results),
+              sorted([name for name in failed_tests]))
+
+
+def RunTestCaseOnWebsite((website, test_case, config)):
+  """ Runs a |test_case| on a |website|. In case when |test_case| has
+  failed it tries to rerun it. If run takes too long, then it is stopped.
   """
-  for (section, option) in defaults:
-    if not config.has_section(section):
-      config.add_section(section)
-    if not config.has_option(section, option):
-      config.set(section, option, defaults[(section, option)])
+
+  profile_path = tempfile.mkdtemp()
+  # The tests can be flaky. This is why we try to rerun up to 3 times.
+  attempts = 3
+  result = ("", "", False, "")
+  logger = logging.getLogger("run_tests")
+  for _ in xrange(attempts):
+    shutil.rmtree(path=profile_path, ignore_errors=True)
+    logger.log(SCRIPT_DEBUG, "Run of test case %s of website %s started",
+               test_case, website)
+    try:
+      with stopit.ThreadingTimeout(100) as timeout:
+        logger.log(SCRIPT_DEBUG,
+                   "Run test with parameters: %s %s %s %s %s %s",
+                   config.chrome_path, config.chromedriver_path,
+                   profile_path, config.passwords_path,
+                   website, test_case)
+        result = tests.RunTest(config.chrome_path, config.chromedriver_path,
+                               profile_path, config.passwords_path,
+                               website, test_case)[0]
+      if timeout != timeout.EXECUTED:
+        result =  (website, test_case, False, "Timeout")
+      _, _, success, _ = result
+      if success:
+        return result
+    except Exception as e:
+      result = (website, test_case, False, e)
+  return result
 
 
-def run_tests(config_path):
+def RunTests(config_path):
   """Runs automated tests.
 
   Runs the tests and returns the results through logging:
@@ -183,61 +152,21 @@
     config_path: The path to the config INI file. See the top of the file
       for format description.
   """
-  def has_test_run_finished(runner, result):
-    result = runner.get_test_result()
-    if result:  # This test run is finished.
-      status, log = result
-      results.append((runner.test_name, status, log))
-      return True
-    else:
-      return False
-
-  defaults = {("run_options", "tests_in_parallel"): "1"}
-  config = ConfigParser.ConfigParser()
-  _apply_defaults(config, defaults)
-  config.read(config_path)
-  max_tests_in_parallel = config.getint("run_options", "tests_in_parallel")
-  full_path = os.path.realpath(__file__)
-  tests_dir = os.path.dirname(full_path)
-  tests_path = os.path.join(tests_dir, "tests.py")
-  test_name_idx = 2  # Index of "test_name_placeholder" below.
-  general_test_cmd = ["python", tests_path, "test_name_placeholder",
-                      "--chrome-path", config.get("binaries", "chrome-path"),
-                      "--chromedriver-path",
-                      config.get("binaries", "chromedriver-path"),
-                      "--passwords-path",
-                      config.get("data_files", "passwords_path")]
-  runners = []
-  if config.has_option("run_options", "tests_to_run"):
-    tests_to_run = config.get("run_options", "tests_to_run").split(",")
-  else:
-    tests_to_run = tests.all_tests.keys()
-  if (config.has_option("logging", "save-only-failures") and
-      config.getboolean("logging", "save-only-failures")):
-    general_test_cmd.append("--save-only-failures")
-
-  if config.has_option("run_options", "test_cases_to_run"):
-    general_test_cmd += ["--test-cases-to-run",
-        config.get("run_options", "test_cases_to_run").replace(",", " ")]
-
+  config = Config(config_path)
   logger = logging.getLogger("run_tests")
-  logger.log(SCRIPT_DEBUG, "%d tests to run: %s", len(tests_to_run),
-             tests_to_run)
-  results = []  # List of (name, bool_passed, failure_log).
-  while len(runners) + len(tests_to_run) > 0:
-    runners = [runner for runner in runners if not has_test_run_finished(
-        runner, results)]
-    while len(runners) < max_tests_in_parallel and len(tests_to_run):
-      test_name = tests_to_run.pop()
-      specific_test_cmd = list(general_test_cmd)
-      specific_test_cmd[test_name_idx] = test_name
-      runners.append(TestRunner(specific_test_cmd, test_name))
-    time.sleep(1)
-  failed_tests = [(name, log) for (name, passed, log) in results if not passed]
-  logger.info("%d failed tests out of %d, failing tests: %s",
-              len(failed_tests), len(results),
-              [name for (name, _) in failed_tests])
-  logger.debug("Logs of failing tests: %s", failed_tests)
+  logger.log(SCRIPT_DEBUG, "%d tests to run: %s", len(config.tests_to_run),
+             config.tests_to_run)
+  data = [(website, test_case, config)
+          for website in config.tests_to_run
+          for test_case in config.test_cases_to_run]
+  number_of_processes = min([config.max_tests_in_parallel,
+                             len(config.test_cases_to_run) *
+                             len(config.tests_to_run)])
+  p = multiprocessing.Pool(number_of_processes)
+  results = p.map(RunTestCaseOnWebsite, data)
+  p.close()
+  p.join()
+  LogResultsOfTestRun(config, results)
 
 
 def main():
@@ -245,7 +174,7 @@
   parser.add_argument("config_path", metavar="N",
                       help="Path to the config.ini file.")
   args = parser.parse_args()
-  run_tests(args.config_path)
+  RunTests(args.config_path)
 
 
 if __name__ == "__main__":
diff --git a/components/test/data/password_manager/automated_tests/tests.py b/components/test/data/password_manager/automated_tests/tests.py
index bddbafb1..f8fe6ff 100644
--- a/components/test/data/password_manager/automated_tests/tests.py
+++ b/components/test/data/password_manager/automated_tests/tests.py
@@ -11,6 +11,9 @@
 from websitetest import WebsiteTest
 
 
+TEST_CASES = ("PromptFailTest", "PromptSuccessTest", "SaveAndAutofillTest")
+
+
 class Alexa(WebsiteTest):
 
   def Login(self):
@@ -504,8 +507,10 @@
     with open(environment_save_path, "w") as save_file:
       save_file.write(xml)
 
+
 def RunTest(chrome_path, chromedriver_path, profile_path,
-            environment_passwords_path, website_test_name, test_case_name):
+            environment_passwords_path, website_test_name,
+            test_case_name):
   """Runs the test for the specified website.
 
   Args:
@@ -528,15 +533,16 @@
   environment = Environment(chrome_path, chromedriver_path, profile_path,
                             environment_passwords_path,
                             enable_automatic_password_saving)
+  try:
+    if website_test_name in all_tests:
+      environment.AddWebsiteTest(all_tests[website_test_name])
+    else:
+      raise Exception("Test name {} is unknown.".format(website_test_name))
 
-  if website_test_name in all_tests:
-    environment.AddWebsiteTest(all_tests[website_test_name])
-  else:
-    raise Exception("Test name {} is unknown.".format(website_test_name))
-
-  environment.RunTestsOnSites(test_case_name)
-  environment.Quit()
-  return environment.tests_results
+    environment.RunTestsOnSites(test_case_name)
+    return environment.tests_results
+  finally:
+    environment.Quit()
 
 def main():
   parser = argparse.ArgumentParser(
@@ -575,9 +581,7 @@
   if args.save_path:
     save_path = args.save_path
 
-  test_cases_to_run = args.test_cases_to_run or\
-      ("PromptFailTest", "PromptSuccessTest", "SaveAndAutofillTest")
-
+  test_cases_to_run = args.test_cases_to_run or TEST_CASES
   for test_case in test_cases_to_run:
     tests_results = RunTest(
         args.chrome_path, args.chromedriver_path, args.profile_path,
diff --git a/components/tracing/child_memory_dump_manager_delegate_impl.cc b/components/tracing/child_memory_dump_manager_delegate_impl.cc
index 5595b14..f8048d9 100644
--- a/components/tracing/child_memory_dump_manager_delegate_impl.cc
+++ b/components/tracing/child_memory_dump_manager_delegate_impl.cc
@@ -68,4 +68,8 @@
   ctmf_->SendGlobalMemoryDumpRequest(args, callback);
 }
 
+bool ChildMemoryDumpManagerDelegateImpl::IsCoordinatorProcess() const {
+  return false;
+}
+
 }  // namespace tracing
diff --git a/components/tracing/child_memory_dump_manager_delegate_impl.h b/components/tracing/child_memory_dump_manager_delegate_impl.h
index 1938ac5..912815dd 100644
--- a/components/tracing/child_memory_dump_manager_delegate_impl.h
+++ b/components/tracing/child_memory_dump_manager_delegate_impl.h
@@ -33,6 +33,7 @@
   void RequestGlobalMemoryDump(
       const base::trace_event::MemoryDumpRequestArgs& args,
       const base::trace_event::MemoryDumpCallback& callback) override;
+  bool IsCoordinatorProcess() const override;
 
   void SetChildTraceMessageFilter(ChildTraceMessageFilter* ctmf);
 
diff --git a/components/tracing_nacl.gyp b/components/tracing_nacl.gyp
index d0fc45d..022a6c6 100644
--- a/components/tracing_nacl.gyp
+++ b/components/tracing_nacl.gyp
@@ -19,7 +19,6 @@
             '../base/base_nacl.gyp:base_nacl_nonsfi',
             '../ipc/ipc_nacl.gyp:ipc_nacl',
             '../ipc/ipc_nacl.gyp:ipc_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
           ],
           'include_dirs': [
             '..',
diff --git a/components/undo/BUILD.gn b/components/undo/BUILD.gn
index b7c4266..250e023 100644
--- a/components/undo/BUILD.gn
+++ b/components/undo/BUILD.gn
@@ -36,4 +36,5 @@
     "//components/bookmarks/test",
     "//testing/gtest",
   ]
+  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
 }
diff --git a/components/user_manager/BUILD.gn b/components/user_manager/BUILD.gn
index 7a5143e88..37f2893 100644
--- a/components/user_manager/BUILD.gn
+++ b/components/user_manager/BUILD.gn
@@ -38,6 +38,7 @@
       "user_type.h",
     ]
     deps += [
+      "//base:prefs",
       "//chromeos:chromeos",
       "//components/session_manager/core",
       "//google_apis",
diff --git a/components/view_manager/BUILD.gn b/components/view_manager/BUILD.gn
index 04b3988..9ae3c4d0 100644
--- a/components/view_manager/BUILD.gn
+++ b/components/view_manager/BUILD.gn
@@ -86,7 +86,6 @@
     "//third_party/mojo_services/src/geometry/public/interfaces",
     "//third_party/mojo_services/src/input_events/public/interfaces",
     "//third_party/mojo_services/src/native_viewport/public/interfaces",
-    "//third_party/mojo_services/src/surfaces/public/cpp",
     "//third_party/mojo_services/src/surfaces/public/interfaces",
     "//third_party/mojo_services/src/view_manager/public/interfaces",
     "//third_party/mojo_services/src/view_manager/public/cpp:common",
diff --git a/components/view_manager/display_manager.cc b/components/view_manager/display_manager.cc
index 52825edca..05eafc1 100644
--- a/components/view_manager/display_manager.cc
+++ b/components/view_manager/display_manager.cc
@@ -10,11 +10,11 @@
 #include "components/view_manager/view_coordinate_conversions.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/converters/transform/transform_type_converters.h"
 #include "third_party/mojo/src/mojo/public/cpp/application/application_connection.h"
 #include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h"
 #include "third_party/mojo_services/src/gpu/public/interfaces/gpu.mojom.h"
-#include "third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.h"
 #include "third_party/mojo_services/src/surfaces/public/interfaces/quads.mojom.h"
 #include "third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom.h"
 
@@ -61,7 +61,7 @@
       base::saturated_cast<int32_t>(pass->shared_quad_states.size());
   surface_quad->surface_quad_state = surface_quad_state.Pass();
 
-  auto sqs = CreateDefaultSQS(*Size::From(view->bounds().size()));
+  auto sqs = mojo::CreateDefaultSQS(view->bounds().size());
   sqs->blend_mode = mojo::SK_XFERMODE_kSrcOver_Mode;
   sqs->opacity = combined_opacity;
   sqs->content_to_target_transform = mojo::Transform::From(node_transform);
@@ -135,10 +135,8 @@
 }
 
 void DefaultDisplayManager::Draw() {
-  Rect rect;
-  rect.width = metrics_.size->width;
-  rect.height = metrics_.size->height;
-  auto pass = CreateDefaultPass(1, rect);
+  gfx::Rect rect(metrics_.size->width, metrics_.size->height);
+  auto pass = mojo::CreateDefaultPass(1, rect);
   pass->damage_rect = Rect::From(dirty_rect_);
 
   DrawViewTree(pass.get(), connection_manager_->root(), gfx::Vector2d(), 1.0f);
diff --git a/components/webcrypto/crypto_data.cc b/components/webcrypto/crypto_data.cc
index f5b3c203..dd369ca 100644
--- a/components/webcrypto/crypto_data.cc
+++ b/components/webcrypto/crypto_data.cc
@@ -15,17 +15,19 @@
 }
 
 CryptoData::CryptoData(const std::vector<unsigned char>& bytes)
-    : bytes_(vector_as_array(&bytes)), byte_length_(bytes.size()) {
+    : bytes_(vector_as_array(&bytes)),
+      byte_length_(static_cast<unsigned int>(bytes.size())) {
 }
 
 CryptoData::CryptoData(const std::string& bytes)
     : bytes_(bytes.size() ? reinterpret_cast<const unsigned char*>(bytes.data())
                           : NULL),
-      byte_length_(bytes.size()) {
+      byte_length_(static_cast<unsigned int>(bytes.size())) {
 }
 
 CryptoData::CryptoData(const blink::WebVector<unsigned char>& bytes)
-    : bytes_(bytes.data()), byte_length_(bytes.size()) {
+    : bytes_(bytes.data()),
+      byte_length_(static_cast<unsigned int>(bytes.size())) {
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/jwk.cc b/components/webcrypto/jwk.cc
index e3e2de6..4e1781d 100644
--- a/components/webcrypto/jwk.cc
+++ b/components/webcrypto/jwk.cc
@@ -416,7 +416,7 @@
 }
 
 std::string MakeJwkAesAlgorithmName(const std::string& suffix,
-                                    unsigned int keylen_bytes) {
+                                    size_t keylen_bytes) {
   if (keylen_bytes == 16)
     return std::string("A128") + suffix;
   if (keylen_bytes == 24)
diff --git a/components/webcrypto/jwk.h b/components/webcrypto/jwk.h
index 8c548ac..5ab62fee 100644
--- a/components/webcrypto/jwk.h
+++ b/components/webcrypto/jwk.h
@@ -153,7 +153,7 @@
 // Creates an AES algorithm name for the given key size (in bytes). For
 // instance "A128CBC" is the result of suffix="CBC", keylen_bytes=16.
 std::string MakeJwkAesAlgorithmName(const std::string& suffix,
-                                    unsigned int keylen_bytes);
+                                    size_t keylen_bytes);
 
 // This is very similar to ReadSecretKeyJwk(), except instead of specifying an
 // absolute "expected_alg", the suffix for an AES algorithm name is given
diff --git a/components/webcrypto/openssl/aes_cbc_openssl.cc b/components/webcrypto/openssl/aes_cbc_openssl.cc
index bfbe57e..4d1ece2 100644
--- a/components/webcrypto/openssl/aes_cbc_openssl.cc
+++ b/components/webcrypto/openssl/aes_cbc_openssl.cc
@@ -22,7 +22,7 @@
 
 namespace {
 
-const EVP_CIPHER* GetAESCipherByKeyLength(unsigned int key_length_bytes) {
+const EVP_CIPHER* GetAESCipherByKeyLength(size_t key_length_bytes) {
   // BoringSSL does not support 192-bit AES keys.
   switch (key_length_bytes) {
     case 16:
diff --git a/components/webcrypto/openssl/aes_ctr_openssl.cc b/components/webcrypto/openssl/aes_ctr_openssl.cc
index 1f5b299..26363f72 100644
--- a/components/webcrypto/openssl/aes_ctr_openssl.cc
+++ b/components/webcrypto/openssl/aes_ctr_openssl.cc
@@ -23,7 +23,7 @@
 
 namespace {
 
-const EVP_CIPHER* GetAESCipherByKeyLength(unsigned int key_length_bytes) {
+const EVP_CIPHER* GetAESCipherByKeyLength(size_t key_length_bytes) {
   // BoringSSL does not support 192-bit AES keys.
   switch (key_length_bytes) {
     case 16:
@@ -119,7 +119,7 @@
       counter_block.bytes(),
       counter_block.bytes() + counter_block.byte_length());
 
-  unsigned int index = new_counter_block.size() - counter_length_bytes;
+  size_t index = new_counter_block.size() - counter_length_bytes;
   memset(&new_counter_block.front() + index, 0, counter_length_bytes);
 
   if (counter_length_bits_remainder) {
diff --git a/components/webcrypto/openssl/aes_gcm_openssl.cc b/components/webcrypto/openssl/aes_gcm_openssl.cc
index d122276..564b54f8 100644
--- a/components/webcrypto/openssl/aes_gcm_openssl.cc
+++ b/components/webcrypto/openssl/aes_gcm_openssl.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-const EVP_AEAD* GetAesGcmAlgorithmFromKeySize(unsigned int key_size_bytes) {
+const EVP_AEAD* GetAesGcmAlgorithmFromKeySize(size_t key_size_bytes) {
   switch (key_size_bytes) {
     case 16:
       return EVP_aead_aes_128_gcm();
diff --git a/components/webcrypto/openssl/aes_kw_openssl.cc b/components/webcrypto/openssl/aes_kw_openssl.cc
index 498d675..31dacea 100644
--- a/components/webcrypto/openssl/aes_kw_openssl.cc
+++ b/components/webcrypto/openssl/aes_kw_openssl.cc
@@ -20,7 +20,7 @@
 
 namespace {
 
-const EVP_AEAD* GetAesKwAlgorithmFromKeySize(unsigned int key_size_bytes) {
+const EVP_AEAD* GetAesKwAlgorithmFromKeySize(size_t key_size_bytes) {
   switch (key_size_bytes) {
     case 16:
       return EVP_aead_aes_128_key_wrap();
diff --git a/components/webcrypto/openssl/hmac_openssl.cc b/components/webcrypto/openssl/hmac_openssl.cc
index 012c114..9962bfd 100644
--- a/components/webcrypto/openssl/hmac_openssl.cc
+++ b/components/webcrypto/openssl/hmac_openssl.cc
@@ -34,7 +34,7 @@
   const EVP_MD* digest_algorithm = GetDigest(hash.id());
   if (!digest_algorithm)
     return Status::ErrorUnsupported();
-  unsigned int hmac_expected_length = EVP_MD_size(digest_algorithm);
+  size_t hmac_expected_length = EVP_MD_size(digest_algorithm);
 
   buffer->resize(hmac_expected_length);
   crypto::ScopedOpenSSLSafeSizeBuffer<EVP_MAX_MD_SIZE> hmac_result(
diff --git a/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc b/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc
index 337b9cf..9857a07 100644
--- a/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc
+++ b/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc
@@ -47,7 +47,8 @@
     return Status::ErrorUnexpected();
 
   *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed(
-      rsa_algorithm, modulus_length_bits, &e[0], e.size(), hash_algorithm);
+      rsa_algorithm, modulus_length_bits, &e[0],
+      static_cast<unsigned int>(e.size()), hash_algorithm);
 
   return Status::Success();
 }
diff --git a/components/webcrypto/test/aes_cbc_unittest.cc b/components/webcrypto/test/aes_cbc_unittest.cc
index e1eebe0..0f6ae85 100644
--- a/components/webcrypto/test/aes_cbc_unittest.cc
+++ b/components/webcrypto/test/aes_cbc_unittest.cc
@@ -20,7 +20,8 @@
     const std::vector<uint8_t>& iv) {
   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
       blink::WebCryptoAlgorithmIdAesCbc,
-      new blink::WebCryptoAesCbcParams(vector_as_array(&iv), iv.size()));
+      new blink::WebCryptoAesCbcParams(vector_as_array(&iv),
+                                       static_cast<unsigned int>(iv.size())));
 }
 
 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
diff --git a/components/webcrypto/test/aes_ctr_unittest.cc b/components/webcrypto/test/aes_ctr_unittest.cc
index b968672f..96453a1 100644
--- a/components/webcrypto/test/aes_ctr_unittest.cc
+++ b/components/webcrypto/test/aes_ctr_unittest.cc
@@ -29,8 +29,9 @@
     uint8_t length_bits) {
   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
       blink::WebCryptoAlgorithmIdAesCtr,
-      new blink::WebCryptoAesCtrParams(length_bits, vector_as_array(&counter),
-                                       counter.size()));
+      new blink::WebCryptoAesCtrParams(
+          length_bits, vector_as_array(&counter),
+          static_cast<unsigned int>(counter.size())));
 }
 
 TEST(WebCryptoAesCtrTest, EncryptDecryptKnownAnswer) {
diff --git a/components/webcrypto/test/aes_gcm_unittest.cc b/components/webcrypto/test/aes_gcm_unittest.cc
index c5ad1df..2d651492 100644
--- a/components/webcrypto/test/aes_gcm_unittest.cc
+++ b/components/webcrypto/test/aes_gcm_unittest.cc
@@ -24,10 +24,11 @@
   EXPECT_TRUE(SupportsAesGcm());
   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
       blink::WebCryptoAlgorithmIdAesGcm,
-      new blink::WebCryptoAesGcmParams(vector_as_array(&iv), iv.size(), true,
-                                       vector_as_array(&additional_data),
-                                       additional_data.size(), true,
-                                       tag_length_bits));
+      new blink::WebCryptoAesGcmParams(
+          vector_as_array(&iv), static_cast<unsigned int>(iv.size()), true,
+          vector_as_array(&additional_data),
+          static_cast<unsigned int>(additional_data.size()), true,
+          tag_length_bits));
 }
 
 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm(
@@ -173,7 +174,8 @@
         GetBytesFromHexString(test, "plain_text");
     const std::vector<uint8_t> test_authentication_tag =
         GetBytesFromHexString(test, "authentication_tag");
-    const unsigned int test_tag_size_bits = test_authentication_tag.size() * 8;
+    const unsigned int test_tag_size_bits =
+        static_cast<unsigned int>(test_authentication_tag.size()) * 8;
     const std::vector<uint8_t> test_cipher_text =
         GetBytesFromHexString(test, "cipher_text");
 
diff --git a/components/webcrypto/test/hmac_unittest.cc b/components/webcrypto/test/hmac_unittest.cc
index 6c84f85..f00c764 100644
--- a/components/webcrypto/test/hmac_unittest.cc
+++ b/components/webcrypto/test/hmac_unittest.cc
@@ -90,7 +90,8 @@
     // Ensure truncated signature does not verify by passing one less byte.
     EXPECT_EQ(Status::Success(),
               Verify(algorithm, key,
-                     CryptoData(vector_as_array(&output), output.size() - 1),
+                     CryptoData(vector_as_array(&output),
+                                static_cast<unsigned int>(output.size()) - 1),
                      CryptoData(test_message), &signature_match));
     EXPECT_FALSE(signature_match);
 
diff --git a/components/webcrypto/test/rsa_oaep_unittest.cc b/components/webcrypto/test/rsa_oaep_unittest.cc
index 9fb882b8..34352967 100644
--- a/components/webcrypto/test/rsa_oaep_unittest.cc
+++ b/components/webcrypto/test/rsa_oaep_unittest.cc
@@ -23,8 +23,9 @@
     const std::vector<uint8_t>& label) {
   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
       blink::WebCryptoAlgorithmIdRsaOaep,
-      new blink::WebCryptoRsaOaepParams(!label.empty(), vector_as_array(&label),
-                                        label.size()));
+      new blink::WebCryptoRsaOaepParams(
+          !label.empty(), vector_as_array(&label),
+          static_cast<unsigned int>(label.size())));
 }
 
 scoped_ptr<base::DictionaryValue> CreatePublicKeyJwkDict() {
diff --git a/components/webcrypto/test/rsa_ssa_unittest.cc b/components/webcrypto/test/rsa_ssa_unittest.cc
index 55a1a1c28..3170a96 100644
--- a/components/webcrypto/test/rsa_ssa_unittest.cc
+++ b/components/webcrypto/test/rsa_ssa_unittest.cc
@@ -559,10 +559,11 @@
             Sign(algorithm, private_key, CryptoData(data), &signature));
 
   // Ensure truncated signature does not verify by passing one less byte.
-  EXPECT_EQ(Status::Success(), Verify(algorithm, public_key,
-                                      CryptoData(vector_as_array(&signature),
-                                                 signature.size() - 1),
-                                      CryptoData(data), &signature_match));
+  EXPECT_EQ(Status::Success(),
+            Verify(algorithm, public_key,
+                   CryptoData(vector_as_array(&signature),
+                              static_cast<unsigned int>(signature.size()) - 1),
+                   CryptoData(data), &signature_match));
   EXPECT_FALSE(signature_match);
 
   // Ensure truncated signature does not verify by passing no bytes.
diff --git a/components/webcrypto/test/sha_unittest.cc b/components/webcrypto/test/sha_unittest.cc
index e6c553c2..a22c90d 100644
--- a/components/webcrypto/test/sha_unittest.cc
+++ b/components/webcrypto/test/sha_unittest.cc
@@ -67,7 +67,8 @@
       size_t chunk_length = std::min(kChunkSizeBytes, length - chunk_index);
       std::vector<uint8_t> chunk(begin, begin + chunk_length);
       ASSERT_TRUE(chunk.size() > 0);
-      EXPECT_TRUE(digestor->consume(vector_as_array(&chunk), chunk.size()));
+      EXPECT_TRUE(digestor->consume(vector_as_array(&chunk),
+                                    static_cast<unsigned int>(chunk.size())));
       chunk_index = chunk_index + chunk_length;
       begin = begin + chunk_length;
     }
diff --git a/components/webcrypto/test/test_helpers.cc b/components/webcrypto/test/test_helpers.cc
index 7d3ff449..76da7fa 100644
--- a/components/webcrypto/test/test_helpers.cc
+++ b/components/webcrypto/test/test_helpers.cc
@@ -124,7 +124,7 @@
 
 bool SupportsRsaPrivateKeyImport() {
 // TODO(eroman): Exclude version test for OS_CHROMEOS
-#if defined(USE_NSS_CERTS)
+#if !defined(USE_OPENSSL) && defined(USE_NSS_CERTS)
   crypto::EnsureNSSInit();
   if (!NSS_VersionCheck("3.16.2")) {
     LOG(WARNING) << "RSA key import is not supported by this version of NSS. "
@@ -142,10 +142,10 @@
     const std::vector<uint8_t>& public_exponent) {
   DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
-      algorithm_id,
-      new blink::WebCryptoRsaHashedKeyGenParams(
-          CreateAlgorithm(hash_id), modulus_length,
-          vector_as_array(&public_exponent), public_exponent.size()));
+      algorithm_id, new blink::WebCryptoRsaHashedKeyGenParams(
+                        CreateAlgorithm(hash_id), modulus_length,
+                        vector_as_array(&public_exponent),
+                        static_cast<unsigned int>(public_exponent.size())));
 }
 
 std::vector<uint8_t> Corrupted(const std::vector<uint8_t>& input) {
diff --git a/components/webcrypto/webcrypto.gyp b/components/webcrypto/webcrypto.gyp
index 91b4476..f386343 100644
--- a/components/webcrypto/webcrypto.gyp
+++ b/components/webcrypto/webcrypto.gyp
@@ -21,8 +21,6 @@
       'export_dependent_settings': [
         '../../base/base.gyp:base',
       ],
-      # Disable c4267 warnings until we fix size_t to int truncations.
-      'msvs_disabled_warnings': [ 4267, ],
       'variables': {
         'webcrypto_sources': [
           'algorithm_dispatch.cc',
diff --git a/components/webcrypto/webcrypto_impl.cc b/components/webcrypto/webcrypto_impl.cc
index 6ea76539..3ccfbc9 100644
--- a/components/webcrypto/webcrypto_impl.cc
+++ b/components/webcrypto/webcrypto_impl.cc
@@ -119,7 +119,8 @@
       // theoretically this could overflow.
       CompleteWithError(Status::ErrorUnexpected(), result);
     } else {
-      result->completeWithBuffer(vector_as_array(&buffer), buffer.size());
+      result->completeWithBuffer(vector_as_array(&buffer),
+                                 static_cast<unsigned int>(buffer.size()));
     }
   }
 }
@@ -468,7 +469,7 @@
   } else {
     state->result.completeWithJson(
         reinterpret_cast<const char*>(vector_as_array(&state->buffer)),
-        state->buffer.size());
+        static_cast<unsigned int>(state->buffer.size()));
   }
 }
 
diff --git a/components/webcrypto/webcrypto_util.cc b/components/webcrypto/webcrypto_util.cc
index edc3cd5..2e80c1f 100644
--- a/components/webcrypto/webcrypto_util.cc
+++ b/components/webcrypto/webcrypto_util.cc
@@ -18,7 +18,7 @@
 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros,
 // to unsigned int.
 bool BigIntegerToUint(const uint8_t* data,
-                      unsigned int data_size,
+                      size_t data_size,
                       unsigned int* result) {
   if (data_size == 0)
     return false;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index b8066cb..3ee0cac 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -100,6 +100,7 @@
     deps += [
       "//cc",
       "//cc/surfaces",
+      "//components/scheduler:common",
       "//content/app/resources",
       "//content/app/strings",
       "//content/browser/devtools:resources",
@@ -195,12 +196,6 @@
       defines += [ "ENABLE_SCREEN_CAPTURE=1" ]
       deps += [ "//third_party/webrtc/modules/desktop_capture" ]
     }
-    if (is_linux || is_mac) {
-      sources += [
-        "renderer_host/media/video_capture_texture_wrapper.cc",
-        "renderer_host/media/video_capture_texture_wrapper.h",
-      ]
-    }
   }
 
   if (is_win) {
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 56baa3f..35bad8b 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -1,4 +1,9 @@
 include_rules = [
+  # Allow inclusion of specific components that we depend on. We may only
+  # depend on components which we share with the mojo html_viewer.
+  "+components/scheduler/common",
+  "+components/tracing",
+
   "+content/app/strings/grit",  # For generated headers
   "+content/public/browser",
   "+device/battery",  # For battery status service.
@@ -15,11 +20,6 @@
   "+ui/webui",
   "+win8/util",
 
-  # TODO(joi): This was misplaced; need to move it somewhere else,
-  # since //content shouldn't depend on //components, which is a layer
-  # 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.
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index 7444327..7b99225 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -161,6 +161,8 @@
       @"AXARIABusy",
       @"AXARIALive",
       @"AXARIARelevant",
+      @"AXARIASetSize",
+      @"AXARIAPosInSet",
       NSAccessibilityColumnIndexRangeAttribute,
       @"AXDropEffects",
       NSAccessibilityEnabledAttribute,
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 9bfd68a3..dcb723fc5 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -445,7 +445,7 @@
     case ui::AX_ROLE_LIST_ITEM:
     case ui::AX_ROLE_LIST_BOX_OPTION:
     case ui::AX_ROLE_TREE_ITEM:
-      index = GetIndexInParent();
+      index = GetIntAttribute(ui::AX_ATTR_POS_IN_SET) - 1;
       break;
     case ui::AX_ROLE_SLIDER:
     case ui::AX_ROLE_PROGRESS_INDICATOR: {
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 7db4fc7..89213b5 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -108,6 +108,8 @@
     { @"AXARIAAtomic", @"ariaAtomic" },
     { @"AXARIABusy", @"ariaBusy" },
     { @"AXARIALive", @"ariaLive" },
+    { @"AXARIASetSize", @"ariaSetSize" },
+    { @"AXARIAPosInSet", @"ariaPosInSet" },
     { @"AXARIARelevant", @"ariaRelevant" },
     { @"AXDropEffects", @"dropeffect" },
     { @"AXGrabbed", @"grabbed" },
@@ -170,6 +172,16 @@
       browserAccessibility_, ui::AX_ATTR_LIVE_RELEVANT);
 }
 
+- (NSNumber*)ariaPosInSet {
+  return [NSNumber numberWithInt:
+      browserAccessibility_->GetIntAttribute(ui::AX_ATTR_POS_IN_SET)];
+}
+
+- (NSNumber*)ariaSetSize {
+  return [NSNumber numberWithInt:
+      browserAccessibility_->GetIntAttribute(ui::AX_ATTR_SET_SIZE)];
+}
+
 // Returns an array of BrowserAccessibilityCocoa objects, representing the
 // accessibility children of this object.
 - (NSArray*)children {
@@ -1407,6 +1419,18 @@
         nil]];
   }
 
+  // Position in set and Set size
+  if (browserAccessibility_->HasIntAttribute(ui::AX_ATTR_POS_IN_SET)) {
+    [ret addObjectsFromArray:[NSArray arrayWithObjects:
+         @"AXARIAPosInSet",
+         nil]];
+  }
+  if (browserAccessibility_->HasIntAttribute(ui::AX_ATTR_SET_SIZE)) {
+    [ret addObjectsFromArray:[NSArray arrayWithObjects:
+         @"AXARIASetSize",
+         nil]];
+  }
+
   // Live regions.
   if (browserAccessibility_->HasStringAttribute(
           ui::AX_ATTR_LIVE_STATUS)) {
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index e8a82f7..b61f2f9c2 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -903,16 +903,10 @@
   if (!group_level || !similar_items_in_group || !position_in_group)
     return E_INVALIDARG;
 
-  if (GetRole() == ui::AX_ROLE_LIST_BOX_OPTION &&
-      GetParent() &&
-      GetParent()->GetRole() == ui::AX_ROLE_LIST_BOX) {
-    *group_level = 0;
-    *similar_items_in_group = GetParent()->PlatformChildCount();
-    *position_in_group = GetIndexInParent() + 1;
-    return S_OK;
-  }
-
-  return E_NOTIMPL;
+  *group_level = 0;
+  *similar_items_in_group = GetIntAttribute(ui::AX_ATTR_SET_SIZE);
+  *position_in_group = GetIntAttribute(ui::AX_ATTR_POS_IN_SET);
+  return S_OK;
 }
 
 //
@@ -3002,15 +2996,9 @@
   // Expose "level" attribute for headings, trees, etc.
   IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level");
 
-  // Expose the set size and position in set for listbox options.
-  if (GetRole() == ui::AX_ROLE_LIST_BOX_OPTION &&
-      GetParent() &&
-      GetParent()->GetRole() == ui::AX_ROLE_LIST_BOX) {
-    win_attributes_->ia2_attributes.push_back(
-        L"setsize:" + base::IntToString16(GetParent()->PlatformChildCount()));
-    win_attributes_->ia2_attributes.push_back(
-        L"setsize:" + base::IntToString16(GetIndexInParent() + 1));
-  }
+  // Expose the set size and position in set.
+  IntAttributeToIA2(ui::AX_ATTR_SET_SIZE, "setsize");
+  IntAttributeToIA2(ui::AX_ATTR_POS_IN_SET, "posinset");
 
   if (ia_role() == ROLE_SYSTEM_CHECKBUTTON ||
       ia_role() == ROLE_SYSTEM_RADIOBUTTON ||
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index f71fcd4..1057e4cd 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -413,6 +413,10 @@
   RunAriaTest(FILE_PATH_LITERAL("aria-option.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaPosinset) {
+  RunAriaTest(FILE_PATH_LITERAL("aria-posinset.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                        AccessibilityAriaPresentation) {
   RunAriaTest(FILE_PATH_LITERAL("aria-presentation.html"));
@@ -484,6 +488,10 @@
   RunAriaTest(FILE_PATH_LITERAL("aria-separator.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaSetsize) {
+  RunAriaTest(FILE_PATH_LITERAL("aria-setsize.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaSlider) {
   RunAriaTest(FILE_PATH_LITERAL("aria-slider.html"));
 }
diff --git a/content/browser/appcache/appcache_update_job.cc b/content/browser/appcache/appcache_update_job.cc
index b5d29a9..4b212861 100644
--- a/content/browser/appcache/appcache_update_job.cc
+++ b/content/browser/appcache/appcache_update_job.cc
@@ -7,11 +7,12 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/thread_task_runner_handle.h"
 #include "content/browser/appcache/appcache_group.h"
 #include "content/browser/appcache/appcache_histograms.h"
+#include "content/public/browser/browser_thread.h"
 #include "net/base/io_buffer.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
@@ -360,7 +361,8 @@
       manifest_fetcher_(NULL),
       manifest_has_valid_mime_type_(false),
       stored_state_(UNSTORED),
-      storage_(service->storage()) {
+      storage_(service->storage()),
+      weak_factory_(this) {
     service_->AddObserver(this);
 }
 
@@ -440,7 +442,10 @@
                               is_new_pending_master_entry);
   }
 
-  FetchManifest(true);
+  BrowserThread::PostAfterStartupTask(
+      FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
+      base::Bind(&AppCacheUpdateJob::FetchManifest, weak_factory_.GetWeakPtr(),
+                 true));
 }
 
 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() {
diff --git a/content/browser/appcache/appcache_update_job.h b/content/browser/appcache/appcache_update_job.h
index 4d2d896..8dfd153a 100644
--- a/content/browser/appcache/appcache_update_job.h
+++ b/content/browser/appcache/appcache_update_job.h
@@ -13,6 +13,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "content/browser/appcache/appcache.h"
 #include "content/browser/appcache/appcache_host.h"
@@ -335,6 +336,7 @@
   StoredState stored_state_;
 
   AppCacheStorage* storage_;
+  base::WeakPtrFactory<AppCacheUpdateJob> weak_factory_;
 
   FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, QueueUpdate);
 
diff --git a/content/browser/appcache/appcache_update_job_unittest.cc b/content/browser/appcache/appcache_update_job_unittest.cc
index 4955a71..b69af526 100644
--- a/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/content/browser/appcache/appcache_update_job_unittest.cc
@@ -724,9 +724,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
-
-    update->manifest_fetcher_->request()->CancelWithError(-100);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -757,9 +754,6 @@
     host2->AssociateCompleteCache(cache);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
-
-    update->manifest_fetcher_->request()->CancelWithError(-100);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -794,7 +788,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -826,7 +819,6 @@
     frontend->SetVerifyProgressEvents(true);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -864,7 +856,6 @@
     host2->AssociateCompleteCache(cache);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -895,7 +886,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -921,7 +911,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -953,7 +942,6 @@
     host2->AssociateCompleteCache(cache);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1040,7 +1028,6 @@
     host->AssociateCompleteCache(cache);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1061,7 +1048,6 @@
 
     AppCacheUpdateJob* update = group_->update_job_;
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     WaitForUpdateToFinish();
   }
@@ -1391,7 +1377,6 @@
                     AppCacheEntry(AppCacheEntry::MASTER, 111));
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1431,7 +1416,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1465,7 +1449,6 @@
     host2->AssociateCompleteCache(cache);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1533,7 +1516,6 @@
     MakeAppCacheResponseInfo(kManifestUrl, 555, kRawHeaders);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1602,7 +1584,6 @@
     frontend1->SetVerifyProgressEvents(true);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1642,7 +1623,6 @@
     frontend->SetVerifyProgressEvents(true);
 
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1681,7 +1661,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1715,7 +1694,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1750,7 +1728,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1784,7 +1761,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1817,7 +1793,6 @@
     MockFrontend* frontend = MakeMockFrontend();
     AppCacheHost* host = MakeHost(1, frontend);
     update->StartUpdate(host, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -1978,7 +1953,6 @@
     host2->AssociateCompleteCache(cache);
 
     update->StartUpdate(NULL, GURL());
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -2008,9 +1982,6 @@
     AppCacheHost* host = MakeHost(1, frontend);
     host->new_master_entry_url_ = GURL("http://failme/blah");
     update->StartUpdate(host, host->new_master_entry_url_);
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
-
-    update->manifest_fetcher_->request()->CancelWithError(-100);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -2037,7 +2008,6 @@
     AppCacheHost* host = MakeHost(1, frontend);
     host->new_master_entry_url_ = MockHttpServer::GetMockUrl("files/blah");
     update->StartUpdate(host, host->new_master_entry_url_);
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -2067,7 +2037,6 @@
     host->new_master_entry_url_ = MockHttpServer::GetMockUrl("files/blah");
 
     update->StartUpdate(host, host->new_master_entry_url_);
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -2097,7 +2066,6 @@
         MockHttpServer::GetMockUrl("files/explicit1");
 
     update->StartUpdate(host, host->new_master_entry_url_);
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up checks for when update job finishes.
     do_checks_after_update_finished_ = true;
@@ -2386,7 +2354,6 @@
     host1->new_master_entry_url_ =
         MockHttpServer::GetMockUrl("files/explicit2");
     update->StartUpdate(host1, host1->new_master_entry_url_);
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up additional updates to be started while update is in progress.
     MockFrontend* frontend2 = MakeMockFrontend();
@@ -2484,7 +2451,6 @@
     host2->new_master_entry_url_ =
         MockHttpServer::GetMockUrl("files/nosuchfile");
     update->StartUpdate(host2, host2->new_master_entry_url_);
-    EXPECT_TRUE(update->manifest_fetcher_ != NULL);
 
     // Set up additional updates to be started while update is in progress.
     MockFrontend* frontend3 = MakeMockFrontend();
diff --git a/content/browser/background_sync/background_sync.proto b/content/browser/background_sync/background_sync.proto
index b5f2e094..895117d4 100644
--- a/content/browser/background_sync/background_sync.proto
+++ b/content/browser/background_sync/background_sync.proto
@@ -36,4 +36,5 @@
 message BackgroundSyncRegistrationsProto {
   repeated BackgroundSyncRegistrationProto registration = 1;
   required int64 next_registration_id = 2;
+  required string origin = 3;
 }
\ No newline at end of file
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 4822464d..a23792f1 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -28,10 +28,7 @@
     BackgroundSyncRegistrations()
     : next_id(BackgroundSyncRegistration::kInitialId) {
 }
-BackgroundSyncManager::BackgroundSyncRegistrations::BackgroundSyncRegistrations(
-    BackgroundSyncRegistration::RegistrationId next_id)
-    : next_id(next_id) {
-}
+
 BackgroundSyncManager::BackgroundSyncRegistrations::
     ~BackgroundSyncRegistrations() {
 }
@@ -206,10 +203,10 @@
   for (const std::pair<int64, std::string>& data : user_data) {
     BackgroundSyncRegistrationsProto registrations_proto;
     if (registrations_proto.ParseFromString(data.second)) {
-      sw_to_registrations_map_[data.first] = BackgroundSyncRegistrations(
-          registrations_proto.next_registration_id());
       BackgroundSyncRegistrations* registrations =
           &sw_to_registrations_map_[data.first];
+      registrations->next_id = registrations_proto.next_registration_id();
+      registrations->origin = GURL(registrations_proto.origin());
 
       for (int i = 0, max = registrations_proto.registration_size(); i < max;
            ++i) {
@@ -262,15 +259,13 @@
     return;
   }
 
-  BackgroundSyncRegistration existing_registration;
-  if (LookupRegistration(sw_registration_id, RegistrationKey(sync_registration),
-                         &existing_registration)) {
-    if (existing_registration.Equals(sync_registration)) {
-      base::MessageLoop::current()->PostTask(
-          FROM_HERE,
-          base::Bind(callback, ERROR_TYPE_OK, existing_registration));
-      return;
-    }
+  const BackgroundSyncRegistration* existing_registration = LookupRegistration(
+      sw_registration_id, RegistrationKey(sync_registration));
+  if (existing_registration &&
+      existing_registration->Equals(sync_registration)) {
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, *existing_registration));
+    return;
   }
 
   BackgroundSyncRegistration new_registration = sync_registration;
@@ -278,10 +273,10 @@
       &sw_to_registrations_map_[sw_registration_id];
   new_registration.id = registrations->next_id++;
 
-  AddRegistrationToMap(sw_registration_id, new_registration);
+  AddRegistrationToMap(sw_registration_id, origin, new_registration);
 
   StoreRegistrations(
-      origin, sw_registration_id,
+      sw_registration_id,
       base::Bind(&BackgroundSyncManager::RegisterDidStore,
                  weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
                  new_registration, callback));
@@ -319,7 +314,7 @@
       base::BarrierClosure(user_data.size(), base::Bind(callback));
 
   for (const auto& sw_id_and_regs : user_data) {
-    service_worker_context_->context()->storage()->ClearUserData(
+    service_worker_context_->ClearRegistrationUserData(
         sw_id_and_regs.first, kBackgroundSyncUserDataKey,
         base::Bind(&BackgroundSyncManager::DisableAndClearManagerClearedOne,
                    weak_ptr_factory_.GetWeakPtr(), barrier_closure));
@@ -334,29 +329,28 @@
                                          base::Bind(barrier_closure));
 }
 
-bool BackgroundSyncManager::LookupRegistration(
+BackgroundSyncManager::BackgroundSyncRegistration*
+BackgroundSyncManager::LookupRegistration(
     int64 sw_registration_id,
-    const RegistrationKey& registration_key,
-    BackgroundSyncRegistration* existing_registration) {
+    const RegistrationKey& registration_key) {
   SWIdToRegistrationsMap::iterator it =
       sw_to_registrations_map_.find(sw_registration_id);
   if (it == sw_to_registrations_map_.end())
-    return false;
+    return nullptr;
 
-  const BackgroundSyncRegistrations& registrations = it->second;
-  const auto key_and_registration_iter =
+  BackgroundSyncRegistrations& registrations = it->second;
+  DCHECK_LE(BackgroundSyncRegistration::kInitialId, registrations.next_id);
+  DCHECK(!registrations.origin.is_empty());
+
+  auto key_and_registration_iter =
       registrations.registration_map.find(registration_key);
   if (key_and_registration_iter == registrations.registration_map.end())
-    return false;
+    return nullptr;
 
-  if (existing_registration)
-    *existing_registration = key_and_registration_iter->second;
-
-  return true;
+  return &key_and_registration_iter->second;
 }
 
 void BackgroundSyncManager::StoreRegistrations(
-    const GURL& origin,
     int64 sw_registration_id,
     const ServiceWorkerStorage::StatusCallback& callback) {
   // Serialize the data.
@@ -364,6 +358,7 @@
       sw_to_registrations_map_[sw_registration_id];
   BackgroundSyncRegistrationsProto registrations_proto;
   registrations_proto.set_next_registration_id(registrations.next_id);
+  registrations_proto.set_origin(registrations.origin.spec());
 
   for (const auto& key_and_registration : registrations.registration_map) {
     const BackgroundSyncRegistration& registration =
@@ -381,8 +376,8 @@
   bool success = registrations_proto.SerializeToString(&serialized);
   DCHECK(success);
 
-  StoreDataInBackend(sw_registration_id, origin, kBackgroundSyncUserDataKey,
-                     serialized, callback);
+  StoreDataInBackend(sw_registration_id, registrations.origin,
+                     kBackgroundSyncUserDataKey, serialized, callback);
 }
 
 void BackgroundSyncManager::RegisterDidStore(
@@ -415,7 +410,7 @@
 void BackgroundSyncManager::RemoveRegistrationFromMap(
     int64 sw_registration_id,
     const RegistrationKey& registration_key) {
-  DCHECK(LookupRegistration(sw_registration_id, registration_key, nullptr));
+  DCHECK(LookupRegistration(sw_registration_id, registration_key));
 
   BackgroundSyncRegistrations* registrations =
       &sw_to_registrations_map_[sw_registration_id];
@@ -425,12 +420,14 @@
 
 void BackgroundSyncManager::AddRegistrationToMap(
     int64 sw_registration_id,
+    const GURL& origin,
     const BackgroundSyncRegistration& sync_registration) {
   DCHECK_NE(BackgroundSyncRegistration::kInvalidRegistrationId,
             sw_registration_id);
 
   BackgroundSyncRegistrations* registrations =
       &sw_to_registrations_map_[sw_registration_id];
+  registrations->origin = origin;
 
   RegistrationKey registration_key(sync_registration);
   registrations->registration_map[registration_key] = sync_registration;
@@ -442,7 +439,7 @@
     const std::string& backend_key,
     const std::string& data,
     const ServiceWorkerStorage::StatusCallback& callback) {
-  service_worker_context_->context()->storage()->StoreUserData(
+  service_worker_context_->StoreRegistrationUserData(
       sw_registration_id, origin, backend_key, data, callback);
 }
 
@@ -452,8 +449,8 @@
         callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  service_worker_context_->context()->storage()->GetUserDataForAllRegistrations(
-      backend_key, callback);
+  service_worker_context_->GetUserDataForAllRegistrations(backend_key,
+                                                          callback);
 }
 
 void BackgroundSyncManager::UnregisterImpl(
@@ -468,10 +465,10 @@
     return;
   }
 
-  BackgroundSyncRegistration existing_registration;
-  if (!LookupRegistration(sw_registration_id, registration_key,
-                          &existing_registration) ||
-      existing_registration.id != sync_registration_id) {
+  const BackgroundSyncRegistration* existing_registration =
+      LookupRegistration(sw_registration_id, registration_key);
+  if (!existing_registration ||
+      existing_registration->id != sync_registration_id) {
     base::MessageLoop::current()->PostTask(
         FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND));
     return;
@@ -480,7 +477,7 @@
   RemoveRegistrationFromMap(sw_registration_id, registration_key);
 
   StoreRegistrations(
-      origin, sw_registration_id,
+      sw_registration_id,
       base::Bind(&BackgroundSyncManager::UnregisterDidStore,
                  weak_ptr_factory_.GetWeakPtr(), sw_registration_id, callback));
 }
@@ -520,9 +517,9 @@
     return;
   }
 
-  BackgroundSyncRegistration out_registration;
-  if (!LookupRegistration(sw_registration_id, registration_key,
-                          &out_registration)) {
+  const BackgroundSyncRegistration* out_registration =
+      LookupRegistration(sw_registration_id, registration_key);
+  if (!out_registration) {
     base::MessageLoop::current()->PostTask(
         FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND,
                               BackgroundSyncRegistration()));
@@ -530,7 +527,7 @@
   }
 
   base::MessageLoop::current()->PostTask(
-      FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, out_registration));
+      FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, *out_registration));
 }
 
 void BackgroundSyncManager::OnRegistrationDeletedImpl(
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h
index b606a451..a4d7714 100644
--- a/content/browser/background_sync/background_sync_manager.h
+++ b/content/browser/background_sync/background_sync_manager.h
@@ -56,7 +56,7 @@
     static const RegistrationId kInitialId;
     BackgroundSyncRegistration() {}
 
-    bool Equals(const BackgroundSyncRegistration& other) {
+    bool Equals(const BackgroundSyncRegistration& other) const {
       return this->tag == other.tag && this->periodicity == other.periodicity &&
              this->min_period == other.min_period &&
              network_state == other.network_state &&
@@ -157,12 +157,11 @@
         std::map<RegistrationKey, BackgroundSyncRegistration>;
 
     BackgroundSyncRegistrations();
-    explicit BackgroundSyncRegistrations(
-        BackgroundSyncRegistration::RegistrationId next_id);
     ~BackgroundSyncRegistrations();
 
     RegistrationMap registration_map;
     BackgroundSyncRegistration::RegistrationId next_id;
+    GURL origin;
   };
 
   using PermissionStatusCallback = base::Callback<void(bool)>;
@@ -183,13 +182,12 @@
 
   // Returns the existing registration in |existing_registration| if it is not
   // null.
-  bool LookupRegistration(int64 sw_registration_id,
-                          const RegistrationKey& registration_key,
-                          BackgroundSyncRegistration* existing_registration);
+  BackgroundSyncRegistration* LookupRegistration(
+      int64 sw_registration_id,
+      const RegistrationKey& registration_key);
 
   // Store all registrations for a given |sw_registration_id|.
-  void StoreRegistrations(const GURL& origin,
-                          int64 sw_registration_id,
+  void StoreRegistrations(int64 sw_registration_id,
                           const ServiceWorkerStorage::StatusCallback& callback);
 
   // Removes the registration if it is in the map.
@@ -198,6 +196,7 @@
 
   void AddRegistrationToMap(
       int64 sw_registration_id,
+      const GURL& origin,
       const BackgroundSyncRegistration& sync_registration);
 
   void InitImpl(const base::Closure& callback);
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
index f07846c..fb62188 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -31,6 +31,10 @@
   return host;
 }
 
+void BluetoothDispatcherHost::OnDestruct() const {
+  BrowserThread::DeleteOnUIThread::Destruct(this);
+}
+
 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   bool handled = true;
@@ -52,12 +56,14 @@
 }
 
 BluetoothDispatcherHost::~BluetoothDispatcherHost() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Clear adapter, releasing observer references.
   set_adapter(scoped_refptr<device::BluetoothAdapter>());
 }
 
 void BluetoothDispatcherHost::set_adapter(
     scoped_refptr<device::BluetoothAdapter> adapter) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (adapter_.get())
     adapter_->RemoveObserver(this);
   adapter_ = adapter;
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.h b/content/browser/bluetooth/bluetooth_dispatcher_host.h
index 2d00d23..a49c759 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.h
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.h
@@ -18,6 +18,10 @@
 // Intended to be instantiated by the RenderProcessHost and installed as
 // a filter on the channel. BrowserMessageFilter is refcounted and typically
 // lives as long as it is installed on a channel.
+//
+// BluetoothDispatcherHost primarily operates on the UI thread because the
+// BluetoothAdapter and related objects live there. An exception is made for
+// Receiving IPC on the IO thread.
 class BluetoothDispatcherHost : public BrowserMessageFilter,
                                 public device::BluetoothAdapter::Observer {
  public:
@@ -25,6 +29,7 @@
   static scoped_refptr<BluetoothDispatcherHost> Create();
 
   // BrowserMessageFilter:
+  void OnDestruct() const override;
   bool OnMessageReceived(const IPC::Message& message) override;
 
  protected:
@@ -32,6 +37,9 @@
   ~BluetoothDispatcherHost() override;
 
  private:
+  friend class base::DeleteHelper<BluetoothDispatcherHost>;
+  friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
+
   // Set |adapter_| to a BluetoothAdapter instance and register observers,
   // releasing references to previous |adapter_|.
   void set_adapter(scoped_refptr<device::BluetoothAdapter> adapter);
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index d485389..3dfc8bd 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -20,6 +20,7 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/timer/hi_res_timer_manager.h"
+#include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/trace_event.h"
 #include "content/browser/browser_thread_impl.h"
 #include "content/browser/device_sensors/device_inertial_sensor_service.h"
@@ -573,6 +574,8 @@
     base::MessageLoop::current()->AddTaskObserver(memory_observer_.get());
   }
 
+  base::trace_event::MemoryDumpManager::GetInstance()->Initialize();
+
 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
   trace_memory_controller_.reset(new base::trace_event::TraceMemoryController(
       base::MessageLoop::current()->message_loop_proxy(),
diff --git a/content/browser/compositor/browser_compositor_output_surface.h b/content/browser/compositor/browser_compositor_output_surface.h
index fd15e03d..615a54e3 100644
--- a/content/browser/compositor/browser_compositor_output_surface.h
+++ b/content/browser/compositor/browser_compositor_output_surface.h
@@ -41,8 +41,8 @@
 
 #if defined(OS_MACOSX)
   virtual void OnSurfaceDisplayed() = 0;
-  virtual void OnSurfaceRecycled() = 0;
-  virtual bool ShouldNotShowFramesAfterRecycle() const = 0;
+  virtual void SetSurfaceSuspendedForRecycle(bool suspended) = 0;
+  virtual bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const = 0;
 #endif
 
  protected:
diff --git a/content/browser/compositor/browser_compositor_view_mac.h b/content/browser/compositor/browser_compositor_view_mac.h
index 41e8bc2..28b824e 100644
--- a/content/browser/compositor/browser_compositor_view_mac.h
+++ b/content/browser/compositor/browser_compositor_view_mac.h
@@ -7,6 +7,7 @@
 
 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
 #include "ui/compositor/compositor.h"
+#include "ui/compositor/compositor_observer.h"
 
 namespace content {
 
@@ -14,9 +15,9 @@
 // into. This structure is used to efficiently recycle these structures across
 // tabs (because creating a new ui::Compositor for each tab would be expensive
 // in terms of time and resources).
-class BrowserCompositorMac {
+class BrowserCompositorMac : public ui::CompositorObserver {
  public:
-  ~BrowserCompositorMac();
+  virtual ~BrowserCompositorMac();
 
   // Create a compositor, or recycle a preexisting one.
   static scoped_ptr<BrowserCompositorMac> Create();
@@ -42,6 +43,15 @@
  private:
   BrowserCompositorMac();
 
+  // ui::CompositorObserver implementation:
+  void OnCompositingDidCommit(ui::Compositor* compositor) override;
+  void OnCompositingStarted(ui::Compositor* compositor,
+                            base::TimeTicks start_time) override {}
+  void OnCompositingEnded(ui::Compositor* compositor) override {}
+  void OnCompositingAborted(ui::Compositor* compositor) override {}
+  void OnCompositingLockStateChanged(ui::Compositor* compositor) override {}
+  void OnCompositingShuttingDown(ui::Compositor* compositor) override {}
+
   scoped_ptr<ui::AcceleratedWidgetMac> accelerated_widget_mac_;
   ui::Compositor compositor_;
   scoped_refptr<ui::CompositorLock> compositor_suspended_lock_;
diff --git a/content/browser/compositor/browser_compositor_view_mac.mm b/content/browser/compositor/browser_compositor_view_mac.mm
index 322183d0..472c17fa 100644
--- a/content/browser/compositor/browser_compositor_view_mac.mm
+++ b/content/browser/compositor/browser_compositor_view_mac.mm
@@ -48,9 +48,12 @@
           RenderWidgetResizeHelper::Get()->task_runner()) {
   compositor_.SetLocksWillTimeOut(false);
   Suspend();
+  compositor_.AddObserver(this);
 }
 
-BrowserCompositorMac::~BrowserCompositorMac() {}
+BrowserCompositorMac::~BrowserCompositorMac() {
+  compositor_.RemoveObserver(this);
+}
 
 void BrowserCompositorMac::Suspend() {
   compositor_suspended_lock_ = compositor_.GetCompositorLock();
@@ -60,6 +63,13 @@
   compositor_suspended_lock_ = nullptr;
 }
 
+void BrowserCompositorMac::OnCompositingDidCommit(
+    ui::Compositor* compositor_that_did_commit) {
+  DCHECK_EQ(compositor_that_did_commit, compositor());
+  content::ImageTransportFactory::GetInstance()
+      ->SetCompositorSuspendedForRecycle(compositor(), false);
+}
+
 // static
 scoped_ptr<BrowserCompositorMac> BrowserCompositorMac::Create() {
   if (g_recyclable_browser_compositor.Get())
@@ -71,8 +81,8 @@
 void BrowserCompositorMac::Recycle(
     scoped_ptr<BrowserCompositorMac> compositor) {
   DCHECK(compositor);
-  content::ImageTransportFactory::GetInstance()->OnCompositorRecycled(
-      compositor->compositor());
+  content::ImageTransportFactory::GetInstance()
+      ->SetCompositorSuspendedForRecycle(compositor->compositor(), true);
 
   // It is an error to have a browser compositor continue to exist after
   // shutdown.
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_browser_compositor_output_surface.cc
index b15d5c21..09a8b7280 100644
--- a/content/browser/compositor/gpu_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -25,7 +25,7 @@
                                      vsync_manager,
                                      overlay_candidate_validator.Pass()),
 #if defined(OS_MACOSX)
-      should_not_show_frames_(false),
+      should_show_frames_state_(SHOULD_SHOW_FRAMES),
 #endif
       swap_buffers_completion_callback_(
           base::Bind(&GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted,
@@ -85,8 +85,10 @@
   client_->DidSwapBuffers();
 
 #if defined(OS_MACOSX)
-  if (should_not_show_frames_)
-    should_not_show_frames_ = false;
+  if (should_show_frames_state_ ==
+      SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED) {
+    should_show_frames_state_ = SHOULD_SHOW_FRAMES;
+  }
 #endif
 }
 
@@ -114,25 +116,34 @@
   cc::OutputSurface::OnSwapBuffersComplete();
 }
 
-void GpuBrowserCompositorOutputSurface::OnSurfaceRecycled() {
-  // Discard the backbuffer immediately. This is necessary only when using a
-  // ImageTransportSurfaceFBO with a CALayerStorageProvider. Discarding the
-  // backbuffer results in the next frame using a new CALayer and CAContext,
-  // which guarantees that the browser will not flash stale content when adding
-  // the remote CALayer to the NSView hierarchy (it could flash stale content
-  // because the system window server is not synchronized with any signals we
-  // control or observe).
-  DiscardBackbuffer();
-  // It may be that there are frames in-flight from the GPU process back to the
-  // browser. Make sure that these frames are not displayed by ignoring them in
-  // GpuProcessHostUIShim, until the browser issues a SwapBuffers for the new
-  // content.
-  should_not_show_frames_ = true;
+void GpuBrowserCompositorOutputSurface::SetSurfaceSuspendedForRecycle(
+    bool suspended) {
+  if (suspended) {
+    // It may be that there are frames in-flight from the GPU process back to
+    // the browser. Make sure that these frames are not displayed by ignoring
+    // them in GpuProcessHostUIShim, until the browser issues a SwapBuffers for
+    // the new content.
+    should_show_frames_state_ = SHOULD_NOT_SHOW_FRAMES_SUSPENDED;
+  } else {
+    // Discard the backbuffer before drawing the new frame. This is necessary
+    // only when using a ImageTransportSurfaceFBO with a
+    // CALayerStorageProvider. Discarding the backbuffer results in the next
+    // frame using a new CALayer and CAContext, which guarantees that the
+    // browser will not flash stale content when adding the remote CALayer to
+    // the NSView hierarchy (it could flash stale content because the system
+    // window server is not synchronized with any signals we control or
+    // observe).
+    if (should_show_frames_state_ == SHOULD_NOT_SHOW_FRAMES_SUSPENDED) {
+      DiscardBackbuffer();
+      should_show_frames_state_ =
+          SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED;
+    }
+  }
 }
 
-bool GpuBrowserCompositorOutputSurface::ShouldNotShowFramesAfterRecycle()
-    const {
-  return should_not_show_frames_;
+bool GpuBrowserCompositorOutputSurface::
+    SurfaceShouldNotShowFramesAfterSuspendForRecycle() const {
+  return should_show_frames_state_ != SHOULD_SHOW_FRAMES;
 }
 #endif
 
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.h b/content/browser/compositor/gpu_browser_compositor_output_surface.h
index b5a5811..2b3d2b7 100644
--- a/content/browser/compositor/gpu_browser_compositor_output_surface.h
+++ b/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -37,9 +37,20 @@
 
 #if defined(OS_MACOSX)
   void OnSurfaceDisplayed() override;
-  void OnSurfaceRecycled() override;
-  bool ShouldNotShowFramesAfterRecycle() const override;
-  bool should_not_show_frames_;
+  void SetSurfaceSuspendedForRecycle(bool suspended) override;
+  bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override;
+  enum ShouldShowFramesState {
+    // Frames that come from the GPU process should appear on-screen.
+    SHOULD_SHOW_FRAMES,
+    // The compositor has been suspended. Any frames that come from the GPU
+    // process are for the pre-suspend content and should not be displayed.
+    SHOULD_NOT_SHOW_FRAMES_SUSPENDED,
+    // The compositor has been un-suspended, but has not yet issued a swap
+    // since being un-suspended, so any frames that come from the GPU process
+    // are for pre-suspend content and should not be displayed.
+    SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED,
+  };
+  ShouldShowFramesState should_show_frames_state_;
 #endif
 
   CommandBufferProxyImpl* GetCommandBufferProxy();
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index eff2349..f2d1b39 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -469,8 +469,9 @@
     surface->OnSurfaceDisplayed();
 }
 
-void GpuProcessTransportFactory::OnCompositorRecycled(
-    ui::Compositor* compositor) {
+void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
+    ui::Compositor* compositor,
+    bool suspended) {
   PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
   if (it == per_compositor_data_.end())
     return;
@@ -479,15 +480,15 @@
   BrowserCompositorOutputSurface* surface =
       output_surface_map_.Lookup(data->surface_id);
   if (surface)
-    surface->OnSurfaceRecycled();
+    surface->SetSurfaceSuspendedForRecycle(suspended);
 }
 
-bool GpuProcessTransportFactory::SurfaceShouldNotShowFramesAfterRecycle(
-    int surface_id) const {
+bool GpuProcessTransportFactory::
+    SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id) const {
   BrowserCompositorOutputSurface* surface =
       output_surface_map_.Lookup(surface_id);
   if (surface)
-    return surface->ShouldNotShowFramesAfterRecycle();
+    return surface->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
   return false;
 }
 #endif
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h
index 7ed1af6..54f02ef 100644
--- a/content/browser/compositor/gpu_process_transport_factory.h
+++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -68,8 +68,10 @@
   void RemoveObserver(ImageTransportFactoryObserver* observer) override;
 #if defined(OS_MACOSX)
   void OnSurfaceDisplayed(int surface_id) override;
-  void OnCompositorRecycled(ui::Compositor* compositor) override;
-  bool SurfaceShouldNotShowFramesAfterRecycle(int surface_id) const override;
+  void SetCompositorSuspendedForRecycle(ui::Compositor* compositor,
+                                        bool suspended) override;
+  bool SurfaceShouldNotShowFramesAfterSuspendForRecycle(
+      int surface_id) const override;
 #endif
 
  private:
diff --git a/content/browser/compositor/image_transport_factory.h b/content/browser/compositor/image_transport_factory.h
index 5142f24..e9aa039 100644
--- a/content/browser/compositor/image_transport_factory.h
+++ b/content/browser/compositor/image_transport_factory.h
@@ -85,13 +85,18 @@
 
 #if defined(OS_MACOSX)
   virtual void OnSurfaceDisplayed(int surface_id) = 0;
-  // Called when the ui::Compositor has been disconnected from an NSView and
-  // may be attached to another one. This ensures that content and frames
-  // intended for the old NSView will not appear in the new NSView.
-  virtual void OnCompositorRecycled(ui::Compositor* compositor) = 0;
+  // Called with |suspended| as true when the ui::Compositor has been
+  // disconnected from an NSView and may be attached to another one. Called
+  // with |suspended| as false after the ui::Compositor has been connected to
+  // a new NSView and the first commit targeted at the new NSView has
+  // completed. This ensures that content and frames intended for the old
+  // NSView will not flash in the new NSView.
+  virtual void SetCompositorSuspendedForRecycle(ui::Compositor* compositor,
+                                                bool suspended) = 0;
   // Used by GpuProcessHostUIShim to determine if a frame should not be
   // displayed because it is targetted to an NSView that has been disconnected.
-  virtual bool SurfaceShouldNotShowFramesAfterRecycle(int surface_id) const = 0;
+  virtual bool SurfaceShouldNotShowFramesAfterSuspendForRecycle(
+      int surface_id) const = 0;
 #endif
 };
 
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc
index a8de2d2..2f0c299 100644
--- a/content/browser/compositor/reflector_impl_unittest.cc
+++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -82,8 +82,10 @@
 
 #if defined(OS_MACOSX)
   void OnSurfaceDisplayed() override {}
-  void OnSurfaceRecycled() override {}
-  bool ShouldNotShowFramesAfterRecycle() const override { return false; }
+  void SetSurfaceSuspendedForRecycle(bool suspended) override {}
+  bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override {
+    return false;
+  }
 #endif
 
   gfx::Size SurfaceSize() const override { return gfx::Size(256, 256); }
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc
index 2d422c9..c2b70d4 100644
--- a/content/browser/compositor/software_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -60,11 +60,12 @@
   NOTREACHED() << "Not expected for software surfaces.";
 }
 
-void SoftwareBrowserCompositorOutputSurface::OnSurfaceRecycled() {
+void SoftwareBrowserCompositorOutputSurface::SetSurfaceSuspendedForRecycle(
+    bool suspended) {
 }
 
-bool SoftwareBrowserCompositorOutputSurface::ShouldNotShowFramesAfterRecycle()
-    const {
+bool SoftwareBrowserCompositorOutputSurface::
+    SurfaceShouldNotShowFramesAfterSuspendForRecycle() const {
   return false;
 }
 #endif
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.h b/content/browser/compositor/software_browser_compositor_output_surface.h
index 245e682..68776ca 100644
--- a/content/browser/compositor/software_browser_compositor_output_surface.h
+++ b/content/browser/compositor/software_browser_compositor_output_surface.h
@@ -33,8 +33,8 @@
 
 #if defined(OS_MACOSX)
   void OnSurfaceDisplayed() override;
-  void OnSurfaceRecycled() override;
-  bool ShouldNotShowFramesAfterRecycle() const override;
+  void SetSurfaceSuspendedForRecycle(bool suspended) override;
+  bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override;
 #endif
 
   base::WeakPtrFactory<SoftwareBrowserCompositorOutputSurface> weak_factory_;
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.cc b/content/browser/compositor/test/no_transport_image_transport_factory.cc
index baebdef0..ff56b3f3 100644
--- a/content/browser/compositor/test/no_transport_image_transport_factory.cc
+++ b/content/browser/compositor/test/no_transport_image_transport_factory.cc
@@ -61,8 +61,8 @@
 }
 
 #if defined(OS_MACOSX)
-bool NoTransportImageTransportFactory::SurfaceShouldNotShowFramesAfterRecycle(
-    int surface_id) const {
+bool NoTransportImageTransportFactory::
+    SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id) const {
   return false;
 }
 #endif
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.h b/content/browser/compositor/test/no_transport_image_transport_factory.h
index d97fb01..e67a09df 100644
--- a/content/browser/compositor/test/no_transport_image_transport_factory.h
+++ b/content/browser/compositor/test/no_transport_image_transport_factory.h
@@ -30,8 +30,10 @@
   void RemoveObserver(ImageTransportFactoryObserver* observer) override;
 #if defined(OS_MACOSX)
   void OnSurfaceDisplayed(int surface_id) override {}
-  void OnCompositorRecycled(ui::Compositor* compositor) override {}
-  bool SurfaceShouldNotShowFramesAfterRecycle(int surface_id) const override;
+  void SetCompositorSuspendedForRecycle(ui::Compositor* compositor,
+                                        bool suspended) override {}
+  bool SurfaceShouldNotShowFramesAfterSuspendForRecycle(
+      int surface_id) const override;
 #endif
 
  private:
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index 3eb6acec..cba575e 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -117,7 +117,6 @@
   }
   client_ = client;
   Attach();
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
 }
 
 void DevToolsAgentHostImpl::DetachClient() {
@@ -127,7 +126,6 @@
   scoped_refptr<DevToolsAgentHostImpl> protect(this);
   client_ = NULL;
   Detach();
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
 }
 
 bool DevToolsAgentHostImpl::IsAttached() {
@@ -164,7 +162,6 @@
   DevToolsAgentHostClient* client = client_;
   client_ = NULL;
   client->AgentHostClosed(this, false);
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
 }
 
 void DevToolsAgentHostImpl::SendMessageToClient(const std::string& message) {
@@ -190,7 +187,6 @@
       agent_host->client_ = NULL;
       client->AgentHostClosed(agent_host, true);
       agent_host->Detach();
-      DevToolsManager::GetInstance()->AgentHostChanged(protect);
     }
   }
 }
@@ -219,6 +215,7 @@
     DevToolsAgentHostImpl* agent_host, bool attached) {
   AgentStateCallbacks copy(g_callbacks.Get());
   DevToolsManager* manager = DevToolsManager::GetInstance();
+  manager->AgentHostStateChanged(agent_host, attached);
   if (manager->delegate())
     manager->delegate()->DevToolsAgentStateChanged(agent_host, attached);
   for (AgentStateCallbacks::iterator it = copy.begin(); it != copy.end(); ++it)
diff --git a/content/browser/devtools/devtools_manager.cc b/content/browser/devtools/devtools_manager.cc
index c30d3e9..1fa19d88 100644
--- a/content/browser/devtools/devtools_manager.cc
+++ b/content/browser/devtools/devtools_manager.cc
@@ -10,16 +10,9 @@
 #include "content/browser/devtools/devtools_netlog_observer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/devtools_target.h"
 
 namespace content {
 
-namespace {
-
-int kObserverThrottleInterval = 500; // ms
-
-}  // namespace
-
 // static
 DevToolsManager* DevToolsManager::GetInstance() {
   return Singleton<DevToolsManager>::get();
@@ -27,105 +20,32 @@
 
 DevToolsManager::DevToolsManager()
     : delegate_(GetContentClient()->browser()->GetDevToolsManagerDelegate()),
-      update_target_list_required_(false),
-      update_target_list_scheduled_(false),
-      update_target_list_callback_(base::Bind(
-          &DevToolsManager::UpdateTargetListThrottled,
-          base::Unretained(this))) {
+      attached_hosts_count_(0) {
 }
 
 DevToolsManager::~DevToolsManager() {
-  DCHECK(!attached_hosts_.size());
-  update_target_list_callback_.Cancel();
+  DCHECK(!attached_hosts_count_);
 }
 
-void DevToolsManager::RenderViewCreated(
-    WebContents* web_contents, RenderViewHost* rvh) {
-  if (observer_list_.might_have_observers()) {
-    // Force agent host creation.
-    DevToolsAgentHost::GetOrCreateFor(web_contents);
-  }
-}
-
-void DevToolsManager::AgentHostChanged(
-    scoped_refptr<DevToolsAgentHost> agent_host) {
-  bool was_attached =
-      attached_hosts_.find(agent_host.get()) != attached_hosts_.end();
-  if (agent_host->IsAttached() && !was_attached) {
-    if (!attached_hosts_.size()) {
+void DevToolsManager::AgentHostStateChanged(
+    DevToolsAgentHostImpl* agent_host, bool attached) {
+  if (attached) {
+    if (!attached_hosts_count_) {
       BrowserThread::PostTask(
           BrowserThread::IO,
           FROM_HERE,
           base::Bind(&DevToolsNetLogObserver::Attach));
     }
-    attached_hosts_.insert(agent_host.get());
-  } else if (!agent_host->IsAttached() && was_attached) {
-    attached_hosts_.erase(agent_host.get());
-    if (!attached_hosts_.size()) {
+    ++attached_hosts_count_;
+  } else {
+    --attached_hosts_count_;
+    if (!attached_hosts_count_) {
       BrowserThread::PostTask(
           BrowserThread::IO,
           FROM_HERE,
           base::Bind(&DevToolsNetLogObserver::Detach));
     }
   }
-
-  UpdateTargetList();
-}
-
-void DevToolsManager::AddObserver(Observer* observer) {
-  observer_list_.AddObserver(observer);
-  UpdateTargetList();
-}
-
-void DevToolsManager::RemoveObserver(Observer* observer) {
-  observer_list_.RemoveObserver(observer);
-}
-
-void DevToolsManager::UpdateTargetList() {
-  if (!observer_list_.might_have_observers())
-    return;
-
-  update_target_list_required_ = true;
-  if (!update_target_list_scheduled_)
-    UpdateTargetListThrottled();
-}
-
-void DevToolsManager::UpdateTargetListThrottled() {
-  if (!update_target_list_required_) {
-    update_target_list_scheduled_ = false;
-    return;
-  }
-
-  update_target_list_scheduled_ = true;
-  if (scheduler_.is_null()) {
-    base::MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        update_target_list_callback_.callback(),
-        base::TimeDelta::FromMilliseconds(kObserverThrottleInterval));
-  } else {
-    scheduler_.Run(update_target_list_callback_.callback());
-  }
-
-  update_target_list_required_ = false;
-  if (!delegate_) {
-    Observer::TargetList empty_list;
-    NotifyTargetListChanged(empty_list);
-    return;
-  }
-  delegate_->EnumerateTargets(base::Bind(
-      &DevToolsManager::NotifyTargetListChanged,
-      base::Unretained(this)));
-}
-
-void DevToolsManager::NotifyTargetListChanged(
-    const Observer::TargetList& targets) {
-  FOR_EACH_OBSERVER(Observer, observer_list_, TargetListChanged(targets));
-  STLDeleteContainerPointers(targets.begin(), targets.end());
-}
-
-void DevToolsManager::SetUpForTest(Scheduler scheduler) {
-  scheduler_ = scheduler;
-  delegate_.reset(GetContentClient()->browser()->GetDevToolsManagerDelegate());
 }
 
 }  // namespace content
diff --git a/content/browser/devtools/devtools_manager.h b/content/browser/devtools/devtools_manager.h
index caedf01f..3e29a7a 100644
--- a/content/browser/devtools/devtools_manager.h
+++ b/content/browser/devtools/devtools_manager.h
@@ -5,40 +5,20 @@
 #ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
 #define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
 
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/cancelable_callback.h"
 #include "base/compiler_specific.h"
 #include "base/memory/singleton.h"
-#include "base/observer_list.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/devtools_manager_delegate.h"
 
 namespace content {
 
-class DevToolsAgentHost;
-class RenderViewHost;
-class WebContents;
+class DevToolsAgentHostImpl;
 
 // This class is a singleton that manage global DevTools state for the whole
 // browser.
+// TODO(dgozman): remove this class entirely.
 class CONTENT_EXPORT DevToolsManager {
  public:
-  class Observer {
-   public:
-    virtual ~Observer() {}
-
-    typedef DevToolsManagerDelegate::TargetList TargetList;
-
-    // Called when any target information changed. Targets in the list are
-    // owned by DevToolsManager, so they should not be accessed outside of
-    // this method.
-    virtual void TargetListChanged(const TargetList& targets) {}
-  };
-
   // Returns single instance of this class. The instance is destroyed on the
   // browser main loop exit so this method MUST NOT be called after that point.
   static DevToolsManager* GetInstance();
@@ -48,29 +28,13 @@
 
   DevToolsManagerDelegate* delegate() const { return delegate_.get(); }
 
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
-
-  void RenderViewCreated(WebContents* web_contents, RenderViewHost* rvh);
-  void AgentHostChanged(scoped_refptr<DevToolsAgentHost> agent_host);
-
-  typedef base::Callback<void(base::Closure)> Scheduler;
-  void SetUpForTest(Scheduler scheduler);
+  void AgentHostStateChanged(DevToolsAgentHostImpl* agent_host, bool attached);
 
  private:
   friend struct DefaultSingletonTraits<DevToolsManager>;
 
-  void UpdateTargetList();
-  void UpdateTargetListThrottled();
-  void NotifyTargetListChanged(const Observer::TargetList& targets);
-
   scoped_ptr<DevToolsManagerDelegate> delegate_;
-  ObserverList<Observer> observer_list_;
-  std::set<DevToolsAgentHost*> attached_hosts_;
-  bool update_target_list_required_;
-  bool update_target_list_scheduled_;
-  base::CancelableClosure update_target_list_callback_;
-  Scheduler scheduler_;
+  int attached_hosts_count_;
 
   DISALLOW_COPY_AND_ASSIGN(DevToolsManager);
 };
diff --git a/content/browser/devtools/devtools_manager_unittest.cc b/content/browser/devtools/devtools_manager_unittest.cc
index ec5013bc..5231d5e1 100644
--- a/content/browser/devtools/devtools_manager_unittest.cc
+++ b/content/browser/devtools/devtools_manager_unittest.cc
@@ -168,31 +168,6 @@
   }
 };
 
-class TestDevToolsManagerObserver : public DevToolsManager::Observer {
- public:
-  TestDevToolsManagerObserver()
-      : updates_count_(0) {}
-  ~TestDevToolsManagerObserver() override {}
-
-  int updates_count() { return updates_count_; }
-  const std::vector<scoped_refptr<DevToolsAgentHost>> hosts() {
-    return hosts_;
-  }
-
-  void TargetListChanged(const TargetList& targets) override {
-    updates_count_++;
-    hosts_.clear();
-    for (TargetList::const_iterator it = targets.begin();
-         it != targets.end(); ++it) {
-      hosts_.push_back((*it)->GetAgentHost());
-    }
-  }
-
- private:
-  int updates_count_;
-  std::vector<scoped_refptr<DevToolsAgentHost>> hosts_;
-};
-
 }  // namespace
 
 class DevToolsManagerTest : public RenderViewHostImplTestHarness {
@@ -205,12 +180,10 @@
     RenderViewHostImplTestHarness::SetUp();
     TestDevToolsClientHost::ResetCounters();
     old_browser_client_ = SetBrowserClientForTesting(&browser_client_);
-    DevToolsManager::GetInstance()->SetUpForTest(DevToolsManager::Scheduler());
   }
 
   void TearDown() override {
     SetBrowserClientForTesting(old_browser_client_);
-    DevToolsManager::GetInstance()->SetUpForTest(DevToolsManager::Scheduler());
     RenderViewHostImplTestHarness::TearDown();
   }
 
@@ -357,109 +330,4 @@
   client_host.Close();
 }
 
-class TestDevToolsManagerScheduler {
- public:
-  DevToolsManager::Scheduler callback() {
-    return base::Bind(&TestDevToolsManagerScheduler::Schedule,
-                      base::Unretained(this));
-  }
-
-  void Run() {
-    ASSERT_FALSE(closure_.is_null());
-    base::Closure copy = closure_;
-    closure_.Reset();
-    copy.Run();
-  }
-
-  bool IsEmpty() {
-    return closure_.is_null();
-  }
-
- private:
-  void Schedule(base::Closure closure) {
-    EXPECT_TRUE(closure_.is_null());
-    closure_ = closure;
-  }
-
-  base::Closure closure_;
-};
-
-TEST_F(DevToolsManagerTest, TestObserver) {
-  GURL url1("data:text/html,<body>Body1</body>");
-  GURL url2("data:text/html,<body>Body2</body>");
-  GURL url3("data:text/html,<body>Body3</body>");
-
-  TestDevToolsManagerScheduler scheduler;
-  DevToolsManager* manager = DevToolsManager::GetInstance();
-  manager->SetUpForTest(scheduler.callback());
-
-  contents()->NavigateAndCommit(url1);
-  RunAllPendingInMessageLoop();
-
-  scoped_ptr<TestDevToolsManagerObserver> observer(
-      new TestDevToolsManagerObserver());
-  manager->AddObserver(observer.get());
-  // Added observer should get an update.
-  EXPECT_EQ(1, observer->updates_count());
-  ASSERT_EQ(1u, observer->hosts().size());
-  EXPECT_EQ(contents(), observer->hosts()[0]->GetWebContents());
-  EXPECT_EQ(url1.spec(), observer->hosts()[0]->GetURL().spec());
-
-  contents()->NavigateAndCommit(url2);
-  RunAllPendingInMessageLoop();
-  contents()->NavigateAndCommit(url3);
-  scheduler.Run();
-  // Updates should be coalesced.
-  EXPECT_EQ(2, observer->updates_count());
-  ASSERT_EQ(1u, observer->hosts().size());
-  EXPECT_EQ(contents(), observer->hosts()[0]->GetWebContents());
-  EXPECT_EQ(url3.spec(), observer->hosts()[0]->GetURL().spec());
-
-  // Check there were no extra updates.
-  scheduler.Run();
-  EXPECT_TRUE(scheduler.IsEmpty());
-  EXPECT_EQ(2, observer->updates_count());
-
-  scoped_ptr<WorkerStoragePartition> partition(new WorkerStoragePartition(
-      browser_context()->GetRequestContext(),
-      NULL, NULL, NULL, NULL, NULL, NULL, NULL));
-  WorkerStoragePartitionId partition_id(*partition.get());
-
-  GURL shared_worker_url("http://example.com/shared_worker.js");
-  SharedWorkerInstance shared_worker(
-      shared_worker_url,
-      base::string16(),
-      base::string16(),
-      blink::WebContentSecurityPolicyTypeReport,
-      browser_context()->GetResourceContext(),
-      partition_id);
-  SharedWorkerDevToolsManager::GetInstance()->WorkerCreated(
-      1, 1, shared_worker);
-  contents()->NavigateAndCommit(url2);
-
-  EXPECT_EQ(3, observer->updates_count());
-  ASSERT_EQ(2u, observer->hosts().size());
-  EXPECT_EQ(contents(), observer->hosts()[0]->GetWebContents());
-  EXPECT_EQ(url2.spec(), observer->hosts()[0]->GetURL().spec());
-  EXPECT_EQ(DevToolsAgentHost::TYPE_SHARED_WORKER,
-            observer->hosts()[1]->GetType());
-  EXPECT_EQ(shared_worker_url.spec(), observer->hosts()[1]->GetURL().spec());
-
-  SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(1, 1);
-  scheduler.Run();
-  EXPECT_EQ(4, observer->updates_count());
-  ASSERT_EQ(1u, observer->hosts().size());
-  EXPECT_EQ(contents(), observer->hosts()[0]->GetWebContents());
-  EXPECT_EQ(url2.spec(), observer->hosts()[0]->GetURL().spec());
-
-  // Check there were no extra updates.
-  scheduler.Run();
-  EXPECT_TRUE(scheduler.IsEmpty());
-  EXPECT_EQ(4, observer->updates_count());
-
-  manager->RemoveObserver(observer.get());
-
-  EXPECT_TRUE(scheduler.IsEmpty());
-}
-
 }  // namespace content
diff --git a/content/browser/devtools/devtools_netlog_observer.cc b/content/browser/devtools/devtools_netlog_observer.cc
index cb6b84f2d..f20ef34 100644
--- a/content/browser/devtools/devtools_netlog_observer.cc
+++ b/content/browser/devtools/devtools_netlog_observer.cc
@@ -169,7 +169,8 @@
   net::NetLog* net_log = GetContentClient()->browser()->GetNetLog();
   if (net_log) {
     instance_ = new DevToolsNetLogObserver();
-    net_log->DeprecatedAddObserver(instance_, net::NetLog::LOG_ALL_BUT_BYTES);
+    net_log->DeprecatedAddObserver(
+        instance_, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
   }
 }
 
diff --git a/content/browser/devtools/ipc_devtools_agent_host.cc b/content/browser/devtools/ipc_devtools_agent_host.cc
index 4fa45eb..dc3eebe 100644
--- a/content/browser/devtools/ipc_devtools_agent_host.cc
+++ b/content/browser/devtools/ipc_devtools_agent_host.cc
@@ -8,7 +8,7 @@
 
 void IPCDevToolsAgentHost::Attach() {
   SendMessageToAgent(new DevToolsAgentMsg_Attach(MSG_ROUTING_NONE, GetId()));
-  OnClientAttached();
+  OnClientAttached(false);
 }
 
 void IPCDevToolsAgentHost::Detach() {
@@ -41,7 +41,7 @@
 void IPCDevToolsAgentHost::Reattach() {
   SendMessageToAgent(new DevToolsAgentMsg_Reattach(
       MSG_ROUTING_NONE, GetId(), state_cookie_));
-  OnClientAttached();
+  OnClientAttached(true);
 }
 
 void IPCDevToolsAgentHost::ProcessChunkedMessageFromAgent(
diff --git a/content/browser/devtools/ipc_devtools_agent_host.h b/content/browser/devtools/ipc_devtools_agent_host.h
index 754be5ee..1f910784 100644
--- a/content/browser/devtools/ipc_devtools_agent_host.h
+++ b/content/browser/devtools/ipc_devtools_agent_host.h
@@ -30,7 +30,7 @@
   void ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
 
   virtual void SendMessageToAgent(IPC::Message* msg) = 0;
-  virtual void OnClientAttached() = 0;
+  virtual void OnClientAttached(bool reattached) = 0;
   virtual void OnClientDetached() = 0;
 
  private:
diff --git a/content/browser/devtools/protocol/service_worker_handler.cc b/content/browser/devtools/protocol/service_worker_handler.cc
index 939b993..6f426f4 100644
--- a/content/browser/devtools/protocol/service_worker_handler.cc
+++ b/content/browser/devtools/protocol/service_worker_handler.cc
@@ -13,7 +13,6 @@
 #include "content/browser/frame_host/frame_tree.h"
 #include "content/browser/frame_host/frame_tree_node.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_watcher.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_version.h"
@@ -151,11 +150,8 @@
 
 void StopServiceWorkerOnIO(scoped_refptr<ServiceWorkerContextWrapper> context,
                            int64 version_id) {
-  ServiceWorkerContextCore* context_core = context->context();
-  if (!context_core)
-    return;
   if (content::ServiceWorkerVersion* version =
-          context_core->GetLiveVersion(version_id)) {
+          context->GetLiveVersion(version_id)) {
     version->StopWorker(base::Bind(&StatusNoOp));
   }
 }
@@ -164,11 +160,8 @@
     scoped_refptr<ServiceWorkerContextWrapper> context,
     int64 version_id,
     const base::Callback<void(int, int)>& callback) {
-  ServiceWorkerContextCore* context_core = context->context();
-  if (!context_core)
-    return;
   if (content::ServiceWorkerVersion* version =
-          context_core->GetLiveVersion(version_id)) {
+          context->GetLiveVersion(version_id)) {
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
         base::Bind(
@@ -458,7 +451,8 @@
 void ServiceWorkerHandler::WorkerCreated(
     ServiceWorkerDevToolsAgentHost* host) {
   auto hosts = GetMatchingServiceWorkers(urls_);
-  if (hosts.find(host->GetId()) != hosts.end() && !host->IsAttached())
+  if (hosts.find(host->GetId()) != hosts.end() && !host->IsAttached() &&
+      !host->IsPausedForDebugOnStart())
     host->PauseForDebugOnStart();
 }
 
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 9fe66ae..9d09b98 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -9,7 +9,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/devtools/devtools_frame_trace_recorder.h"
-#include "content/browser/devtools/devtools_manager.h"
 #include "content/browser/devtools/protocol/devtools_protocol_handler.h"
 #include "content/browser/devtools/protocol/dom_handler.h"
 #include "content/browser/devtools/protocol/emulation_handler.h"
@@ -129,8 +128,7 @@
   RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(pending);
   if (!agent_host)
     return;
-  agent_host->DisconnectRenderFrameHost();
-  agent_host->ConnectRenderFrameHost(current);
+  agent_host->ReattachToRenderFrameHost(current);
 }
 
 RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(RenderFrameHost* rfh)
@@ -168,7 +166,6 @@
   SetRenderFrameHost(rfh);
   g_instances.Get().push_back(this);
   AddRef();  // Balanced in RenderFrameHostDestroyed.
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
 }
 
 BrowserContext* RenderFrameDevToolsAgentHost::GetBrowserContext() {
@@ -187,7 +184,7 @@
   render_frame_host_->Send(msg);
 }
 
-void RenderFrameDevToolsAgentHost::OnClientAttached() {
+void RenderFrameDevToolsAgentHost::OnClientAttached(bool reattached) {
   if (!render_frame_host_)
     return;
 
@@ -323,9 +320,10 @@
 void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
   DCHECK(render_frame_host_);
   scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
+  if (IsAttached())
+    OnClientDetached();
   HostClosed();
   ClearRenderFrameHost();
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
   Release();
 }
 
@@ -390,16 +388,6 @@
     page_handler_->DidDetachInterstitialPage();
 }
 
-void RenderFrameDevToolsAgentHost::TitleWasSet(
-    NavigationEntry* entry, bool explicit_set) {
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
-}
-
-void RenderFrameDevToolsAgentHost::NavigationEntryCommitted(
-    const LoadCommittedDetails& load_details) {
-  DevToolsManager::GetInstance()->AgentHostChanged(this);
-}
-
 void RenderFrameDevToolsAgentHost::DidCommitProvisionalLoadForFrame(
     RenderFrameHost* render_frame_host,
     const GURL& url,
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h
index 1808211..a77cdbe 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -78,7 +78,7 @@
 
   // IPCDevToolsAgentHost overrides.
   void SendMessageToAgent(IPC::Message* msg) override;
-  void OnClientAttached() override;
+  void OnClientAttached(bool reattached) override;
   void OnClientDetached() override;
 
   // WebContentsObserver overrides.
@@ -93,9 +93,6 @@
   bool OnMessageReceived(const IPC::Message& message) override;
   void DidAttachInterstitialPage() override;
   void DidDetachInterstitialPage() override;
-  void TitleWasSet(NavigationEntry* entry, bool explicit_set) override;
-  void NavigationEntryCommitted(
-      const LoadCommittedDetails& load_details) override;
   void DidCommitProvisionalLoadForFrame(
       RenderFrameHost* render_frame_host,
       const GURL& url,
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.cc b/content/browser/devtools/service_worker_devtools_agent_host.cc
index a8cc6a2..5a36ba1 100644
--- a/content/browser/devtools/service_worker_devtools_agent_host.cc
+++ b/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -92,8 +92,8 @@
                   service_worker_->version_id()));
 }
 
-void ServiceWorkerDevToolsAgentHost::OnClientAttached() {
-  WorkerDevToolsAgentHost::OnClientAttached();
+void ServiceWorkerDevToolsAgentHost::OnClientAttached(bool reattached) {
+  WorkerDevToolsAgentHost::OnClientAttached(reattached);
   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
       base::Bind(&SetDevToolsAttachedOnIO,
                   service_worker_->context_weak(),
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.h b/content/browser/devtools/service_worker_devtools_agent_host.h
index 4e6ce3a..b0535cc 100644
--- a/content/browser/devtools/service_worker_devtools_agent_host.h
+++ b/content/browser/devtools/service_worker_devtools_agent_host.h
@@ -33,7 +33,7 @@
   bool Close() override;
 
   // IPCDevToolsAgentHost override.
-  void OnClientAttached() override;
+  void OnClientAttached(bool reattached) override;
   void OnClientDetached() override;
 
   bool Matches(const ServiceWorkerIdentifier& other);
diff --git a/content/browser/devtools/service_worker_devtools_manager.cc b/content/browser/devtools/service_worker_devtools_manager.cc
index a423066..f6eb93b 100644
--- a/content/browser/devtools/service_worker_devtools_manager.cc
+++ b/content/browser/devtools/service_worker_devtools_manager.cc
@@ -4,7 +4,6 @@
 
 #include "content/browser/devtools/service_worker_devtools_manager.h"
 
-#include "content/browser/devtools/devtools_manager.h"
 #include "content/browser/devtools/ipc_devtools_agent_host.h"
 #include "content/browser/devtools/service_worker_devtools_agent_host.h"
 #include "content/public/browser/browser_thread.h"
@@ -78,7 +77,6 @@
             id, service_worker_id);
     workers_[id] = host.get();
     FOR_EACH_OBSERVER(Observer, observer_list_, WorkerCreated(host.get()));
-    DevToolsManager::GetInstance()->AgentHostChanged(host.get());
     if (debug_service_worker_on_start_)
         host->PauseForDebugOnStart();
     return host->IsPausedForDebugOnStart();
@@ -89,7 +87,6 @@
   agent_host->WorkerRestarted(id);
   workers_.erase(it);
   workers_[id] = agent_host;
-  DevToolsManager::GetInstance()->AgentHostChanged(agent_host);
 
   return agent_host->IsAttached();
 }
@@ -128,7 +125,6 @@
   DCHECK(it != workers_.end());
   scoped_refptr<WorkerDevToolsAgentHost> agent_host(it->second);
   agent_host->WorkerDestroyed();
-  DevToolsManager::GetInstance()->AgentHostChanged(agent_host);
   FOR_EACH_OBSERVER(Observer, observer_list_, WorkerDestroyed(it->second));
 }
 
diff --git a/content/browser/devtools/shared_worker_devtools_manager.cc b/content/browser/devtools/shared_worker_devtools_manager.cc
index 3fb2cf1..3490e80 100644
--- a/content/browser/devtools/shared_worker_devtools_manager.cc
+++ b/content/browser/devtools/shared_worker_devtools_manager.cc
@@ -4,7 +4,6 @@
 
 #include "content/browser/devtools/shared_worker_devtools_manager.h"
 
-#include "content/browser/devtools/devtools_manager.h"
 #include "content/browser/devtools/shared_worker_devtools_agent_host.h"
 #include "content/browser/shared_worker/shared_worker_instance.h"
 #include "content/public/browser/browser_thread.h"
@@ -44,7 +43,6 @@
       FindExistingWorkerAgentHost(instance);
   if (it == workers_.end()) {
     workers_[id] = new SharedWorkerDevToolsAgentHost(id, instance);
-    DevToolsManager::GetInstance()->AgentHostChanged(workers_[id]);
     return false;
   }
 
@@ -53,7 +51,6 @@
   agent_host->WorkerRestarted(id);
   workers_.erase(it);
   workers_[id] = agent_host;
-  DevToolsManager::GetInstance()->AgentHostChanged(agent_host);
   return true;
 }
 
@@ -76,7 +73,6 @@
   DCHECK(it != workers_.end());
   scoped_refptr<SharedWorkerDevToolsAgentHost> agent_host(it->second);
   agent_host->WorkerDestroyed();
-  DevToolsManager::GetInstance()->AgentHostChanged(agent_host);
 }
 
 void SharedWorkerDevToolsManager::RemoveInspectedWorkerData(WorkerId id) {
diff --git a/content/browser/devtools/worker_devtools_agent_host.cc b/content/browser/devtools/worker_devtools_agent_host.cc
index fcf8dd7..a0c1fc6 100644
--- a/content/browser/devtools/worker_devtools_agent_host.cc
+++ b/content/browser/devtools/worker_devtools_agent_host.cc
@@ -35,8 +35,9 @@
   IPCDevToolsAgentHost::Attach();
 }
 
-void WorkerDevToolsAgentHost::OnClientAttached() {
-  DevToolsAgentHostImpl::NotifyCallbacks(this, true);
+void WorkerDevToolsAgentHost::OnClientAttached(bool reattached) {
+  if (!reattached)
+    DevToolsAgentHostImpl::NotifyCallbacks(this, true);
 }
 
 void WorkerDevToolsAgentHost::OnClientDetached() {
diff --git a/content/browser/devtools/worker_devtools_agent_host.h b/content/browser/devtools/worker_devtools_agent_host.h
index 7bd5128..30fee5a 100644
--- a/content/browser/devtools/worker_devtools_agent_host.h
+++ b/content/browser/devtools/worker_devtools_agent_host.h
@@ -24,7 +24,7 @@
   // IPCDevToolsAgentHost implementation.
   void SendMessageToAgent(IPC::Message* message) override;
   void Attach() override;
-  void OnClientAttached() override;
+  void OnClientAttached(bool reattached) override;
   void OnClientDetached() override;
 
   // IPC::Listener implementation.
diff --git a/content/browser/dom_storage/dom_storage_area.cc b/content/browser/dom_storage/dom_storage_area.cc
index 9ff7bfb..56a1fd00 100644
--- a/content/browser/dom_storage/dom_storage_area.cc
+++ b/content/browser/dom_storage/dom_storage_area.cc
@@ -20,6 +20,7 @@
 #include "content/browser/dom_storage/session_storage_database_adapter.h"
 #include "content/common/dom_storage/dom_storage_map.h"
 #include "content/common/dom_storage/dom_storage_types.h"
+#include "content/public/browser/browser_thread.h"
 #include "storage/browser/database/database_util.h"
 #include "storage/common/database/database_identifier.h"
 #include "storage/common/fileapi/file_system_util.h"
@@ -364,19 +365,28 @@
   DCHECK(!is_shutdown_);
   if (!commit_batch_) {
     commit_batch_.reset(new CommitBatch());
-
-    // Start a timer to commit any changes that accrue in the batch, but only if
-    // no commits are currently in flight. In that case the timer will be
-    // started after the commits have happened.
-    if (!commit_batches_in_flight_) {
-      task_runner_->PostDelayedTask(
-          FROM_HERE, base::Bind(&DOMStorageArea::OnCommitTimer, this),
-          ComputeCommitDelay());
-    }
+    BrowserThread::PostAfterStartupTask(
+        FROM_HERE, task_runner_,
+        base::Bind(&DOMStorageArea::StartCommitTimer, this));
   }
   return commit_batch_.get();
 }
 
+void DOMStorageArea::StartCommitTimer() {
+  if (is_shutdown_ || !commit_batch_)
+    return;
+
+  // Start a timer to commit any changes that accrue in the batch, but only if
+  // no commits are currently in flight. In that case the timer will be
+  // started after the commits have happened.
+  if (commit_batches_in_flight_)
+    return;
+
+  task_runner_->PostDelayedTask(
+      FROM_HERE, base::Bind(&DOMStorageArea::OnCommitTimer, this),
+      ComputeCommitDelay());
+}
+
 base::TimeDelta DOMStorageArea::ComputeCommitDelay() const {
   base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_;
   base::TimeDelta delay = std::max(
diff --git a/content/browser/dom_storage/dom_storage_area.h b/content/browser/dom_storage/dom_storage_area.h
index d094789..3a4b166 100644
--- a/content/browser/dom_storage/dom_storage_area.h
+++ b/content/browser/dom_storage/dom_storage_area.h
@@ -144,6 +144,7 @@
   // disk on the commit sequence, and to call back on the primary
   // task sequence when complete.
   CommitBatch* CreateCommitBatchIfNeeded();
+  void StartCommitTimer();
   void OnCommitTimer();
   void PostCommitTask();
   void CommitChanges(const CommitBatch* commit_batch);
diff --git a/content/browser/dom_storage/dom_storage_area_unittest.cc b/content/browser/dom_storage/dom_storage_area_unittest.cc
index 11155909..aa5653da 100644
--- a/content/browser/dom_storage/dom_storage_area_unittest.cc
+++ b/content/browser/dom_storage/dom_storage_area_unittest.cc
@@ -6,8 +6,8 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/time/time.h"
 #include "content/browser/dom_storage/dom_storage_area.h"
@@ -16,6 +16,7 @@
 #include "content/browser/dom_storage/dom_storage_task_runner.h"
 #include "content/browser/dom_storage/local_storage_database_adapter.h"
 #include "content/common/dom_storage/dom_storage_types.h"
+#include "content/public/browser/browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::ASCIIToUTF16;
@@ -39,7 +40,20 @@
   const base::string16 kValue2;
 
   // Method used in the CommitTasks test case.
-  void InjectedCommitSequencingTask(DOMStorageArea* area) {
+  void InjectedCommitSequencingTask1(
+      const scoped_refptr<DOMStorageArea>& area) {
+    // At this point the StartCommitTimer task has run and
+    // the OnCommitTimer task is queued. We want to inject after
+    // that.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&DOMStorageAreaTest::InjectedCommitSequencingTask2,
+                   base::Unretained(this),
+                   area));
+  }
+
+  void InjectedCommitSequencingTask2(
+      const scoped_refptr<DOMStorageArea>& area) {
     // At this point the OnCommitTimer has run.
     // Verify that it put a commit in flight.
     EXPECT_EQ(1, area->commit_batches_in_flight_);
@@ -261,13 +275,14 @@
   // those will also get committed.
   EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
   EXPECT_TRUE(area->HasUncommittedChanges());
-  // At this point the OnCommitTimer task has been posted. We inject
-  // another task in the queue that will execute after the timer task,
-  // but before the CommitChanges task. From within our injected task,
-  // we'll make an additional SetItem() call.
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&DOMStorageAreaTest::InjectedCommitSequencingTask,
+  // At this point the StartCommitTimer task has been posted to the after
+  // startup task queue. We inject another task in the queue that will
+  // execute when the CommitChanges task is inflight. From within our
+  // injected task, we'll make an additional SetItem() call and verify
+  // that a new commit batch is created for that additional change.
+  BrowserThread::PostAfterStartupTask(
+      FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
+      base::Bind(&DOMStorageAreaTest::InjectedCommitSequencingTask1,
                  base::Unretained(this),
                  area));
   base::MessageLoop::current()->RunUntilIdle();
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc
index 203c689..4c8203d 100644
--- a/content/browser/download/download_file_impl.cc
+++ b/content/browser/download/download_file_impl.cc
@@ -337,7 +337,7 @@
             &DownloadDestinationObserver::DestinationCompleted,
             observer_, hash));
   }
-  if (bound_net_log_.IsLogging()) {
+  if (bound_net_log_.GetCaptureMode().enabled()) {
     bound_net_log_.AddEvent(
         net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED,
         base::Bind(&FileStreamDrainedNetLogCallback, total_incoming_data_size,
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc
index a0dea56..dbcf7c4 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -1055,7 +1055,7 @@
   if (received_bytes_ > total_bytes_)
     total_bytes_ = 0;
 
-  if (bound_net_log_.IsLogging()) {
+  if (bound_net_log_.GetCaptureMode().enabled()) {
     bound_net_log_.AddEvent(
         net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED,
         net::NetLog::Int64Callback("bytes_so_far", received_bytes_));
@@ -1106,8 +1106,8 @@
       file_name = GetURL().ExtractFileName();
   }
 
-  base::Callback<base::Value*(net::NetLog::LogLevel)> active_data = base::Bind(
-      &ItemActivatedNetLogCallback, this, download_type, &file_name);
+  net::NetLog::ParametersCallback active_data =
+      base::Bind(&ItemActivatedNetLogCallback, this, download_type, &file_name);
   if (active) {
     bound_net_log_.BeginEvent(
         net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data);
diff --git a/content/browser/download/download_net_log_parameters.cc b/content/browser/download/download_net_log_parameters.cc
index 8fe755c..8d04ae1 100644
--- a/content/browser/download/download_net_log_parameters.cc
+++ b/content/browser/download/download_net_log_parameters.cc
@@ -41,11 +41,10 @@
 
 }  // namespace
 
-base::Value* ItemActivatedNetLogCallback(
-    const DownloadItem* download_item,
-    DownloadType download_type,
-    const std::string* file_name,
-    net::NetLog::LogLevel log_level) {
+base::Value* ItemActivatedNetLogCallback(const DownloadItem* download_item,
+                                         DownloadType download_type,
+                                         const std::string* file_name,
+                                         net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("type", download_type_names[download_type]);
@@ -62,9 +61,8 @@
   return dict;
 }
 
-base::Value* ItemCheckedNetLogCallback(
-    DownloadDangerType danger_type,
-    net::NetLog::LogLevel log_level) {
+base::Value* ItemCheckedNetLogCallback(DownloadDangerType danger_type,
+                                       net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("danger_type", download_danger_names[danger_type]);
@@ -74,7 +72,7 @@
 
 base::Value* ItemRenamedNetLogCallback(const base::FilePath* old_filename,
                                        const base::FilePath* new_filename,
-                                       net::NetLog::LogLevel log_level) {
+                                       net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("old_filename", old_filename->AsUTF8Unsafe());
@@ -83,10 +81,11 @@
   return dict;
 }
 
-base::Value* ItemInterruptedNetLogCallback(DownloadInterruptReason reason,
-                                           int64 bytes_so_far,
-                                           const std::string* hash_state,
-                                           net::NetLog::LogLevel log_level) {
+base::Value* ItemInterruptedNetLogCallback(
+    DownloadInterruptReason reason,
+    int64 bytes_so_far,
+    const std::string* hash_state,
+    net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason));
@@ -101,7 +100,7 @@
                                         DownloadInterruptReason reason,
                                         int64 bytes_so_far,
                                         const std::string* hash_state,
-                                        net::NetLog::LogLevel log_level) {
+                                        net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("user_initiated", user_initiated ? "true" : "false");
@@ -115,7 +114,7 @@
 
 base::Value* ItemCompletingNetLogCallback(int64 bytes_so_far,
                                           const std::string* final_hash,
-                                          net::NetLog::LogLevel log_level) {
+                                          net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far));
@@ -126,7 +125,7 @@
 }
 
 base::Value* ItemFinishedNetLogCallback(bool auto_opened,
-                                        net::NetLog::LogLevel log_level) {
+                                        net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("auto_opened", auto_opened ? "yes" : "no");
@@ -136,7 +135,7 @@
 
 base::Value* ItemCanceledNetLogCallback(int64 bytes_so_far,
                                         const std::string* hash_state,
-                                        net::NetLog::LogLevel log_level) {
+                                        net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far));
@@ -148,7 +147,7 @@
 
 base::Value* FileOpenedNetLogCallback(const base::FilePath* file_name,
                                       int64 start_offset,
-                                      net::NetLog::LogLevel log_level) {
+                                      net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("file_name", file_name->AsUTF8Unsafe());
@@ -157,9 +156,10 @@
   return dict;
 }
 
-base::Value* FileStreamDrainedNetLogCallback(size_t stream_size,
-                                             size_t num_buffers,
-                                             net::NetLog::LogLevel log_level) {
+base::Value* FileStreamDrainedNetLogCallback(
+    size_t stream_size,
+    size_t num_buffers,
+    net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetInteger("stream_size", static_cast<int>(stream_size));
@@ -170,7 +170,7 @@
 
 base::Value* FileRenamedNetLogCallback(const base::FilePath* old_filename,
                                        const base::FilePath* new_filename,
-                                       net::NetLog::LogLevel log_level) {
+                                       net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("old_filename", old_filename->AsUTF8Unsafe());
@@ -181,7 +181,7 @@
 
 base::Value* FileErrorNetLogCallback(const char* operation,
                                      net::Error net_error,
-                                     net::NetLog::LogLevel log_level) {
+                                     net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("operation", operation);
@@ -190,10 +190,11 @@
   return dict;
 }
 
-base::Value* FileInterruptedNetLogCallback(const char* operation,
-                                           int os_error,
-                                           DownloadInterruptReason reason,
-                                           net::NetLog::LogLevel log_level) {
+base::Value* FileInterruptedNetLogCallback(
+    const char* operation,
+    int os_error,
+    DownloadInterruptReason reason,
+    net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("operation", operation);
diff --git a/content/browser/download/download_net_log_parameters.h b/content/browser/download/download_net_log_parameters.h
index 6d027cf..de0c957 100644
--- a/content/browser/download/download_net_log_parameters.h
+++ b/content/browser/download/download_net_log_parameters.h
@@ -26,74 +26,73 @@
 };
 
 // Returns NetLog parameters when a DownloadItem is activated.
-base::Value* ItemActivatedNetLogCallback(
-    const DownloadItem* download_item,
-    DownloadType download_type,
-    const std::string* file_name,
-    net::NetLog::LogLevel log_level);
+base::Value* ItemActivatedNetLogCallback(const DownloadItem* download_item,
+                                         DownloadType download_type,
+                                         const std::string* file_name,
+                                         net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is checked for danger.
-base::Value* ItemCheckedNetLogCallback(
-    DownloadDangerType danger_type,
-    net::NetLog::LogLevel log_level);
+base::Value* ItemCheckedNetLogCallback(DownloadDangerType danger_type,
+                                       net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is renamed.
 base::Value* ItemRenamedNetLogCallback(const base::FilePath* old_filename,
                                        const base::FilePath* new_filename,
-                                       net::NetLog::LogLevel log_level);
+                                       net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is interrupted.
 base::Value* ItemInterruptedNetLogCallback(DownloadInterruptReason reason,
                                            int64 bytes_so_far,
                                            const std::string* hash_state,
-                                           net::NetLog::LogLevel log_level);
+                                           net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is resumed.
 base::Value* ItemResumingNetLogCallback(bool user_initiated,
                                         DownloadInterruptReason reason,
                                         int64 bytes_so_far,
                                         const std::string* hash_state,
-                                        net::NetLog::LogLevel log_level);
+                                        net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is completing.
 base::Value* ItemCompletingNetLogCallback(int64 bytes_so_far,
                                           const std::string* final_hash,
-                                          net::NetLog::LogLevel log_level);
+                                          net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is finished.
 base::Value* ItemFinishedNetLogCallback(bool auto_opened,
-                                        net::NetLog::LogLevel log_level);
+                                        net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadItem is canceled.
 base::Value* ItemCanceledNetLogCallback(int64 bytes_so_far,
                                         const std::string* hash_state,
-                                        net::NetLog::LogLevel log_level);
+                                        net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadFile is opened.
 base::Value* FileOpenedNetLogCallback(const base::FilePath* file_name,
                                       int64 start_offset,
-                                      net::NetLog::LogLevel log_level);
+                                      net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadFile is opened.
-base::Value* FileStreamDrainedNetLogCallback(size_t stream_size,
-                                             size_t num_buffers,
-                                             net::NetLog::LogLevel log_level);
+base::Value* FileStreamDrainedNetLogCallback(
+    size_t stream_size,
+    size_t num_buffers,
+    net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a DownloadFile is renamed.
 base::Value* FileRenamedNetLogCallback(const base::FilePath* old_filename,
                                        const base::FilePath* new_filename,
-                                       net::NetLog::LogLevel log_level);
+                                       net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters when a File has an error.
 base::Value* FileErrorNetLogCallback(const char* operation,
                                      net::Error net_error,
-                                     net::NetLog::LogLevel log_level);
+                                     net::NetLogCaptureMode capture_mode);
 
 // Returns NetLog parameters for a download interruption.
 base::Value* FileInterruptedNetLogCallback(const char* operation,
                                            int os_error,
                                            DownloadInterruptReason reason,
-                                           net::NetLog::LogLevel log_level);
+                                           net::NetLogCaptureMode capture_mode);
 
 }  // namespace content
 
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h
index 8771dd2..3a27601e 100644
--- a/content/browser/frame_host/navigator.h
+++ b/content/browser/frame_host/navigator.h
@@ -101,6 +101,7 @@
                               const GURL& url,
                               SiteInstance* source_site_instance,
                               const Referrer& referrer,
+                              ui::PageTransition page_transition,
                               WindowOpenDisposition disposition,
                               bool should_replace_current_entry,
                               bool user_gesture) {}
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 0bbd2bd..a00f9723d 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -38,6 +38,7 @@
 #include "content/public/common/resource_response.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
+#include "net/base/net_errors.h"
 
 namespace content {
 
@@ -517,6 +518,7 @@
                                    const GURL& url,
                                    SiteInstance* source_site_instance,
                                    const Referrer& referrer,
+                                   ui::PageTransition page_transition,
                                    WindowOpenDisposition disposition,
                                    bool should_replace_current_entry,
                                    bool user_gesture) {
@@ -538,9 +540,9 @@
   // redirects.  http://crbug.com/311721.
   std::vector<GURL> redirect_chain;
   RequestTransferURL(render_frame_host, url, source_site_instance,
-                     redirect_chain, referrer, ui::PAGE_TRANSITION_LINK,
-                     disposition, GlobalRequestID(),
-                     should_replace_current_entry, user_gesture);
+                     redirect_chain, referrer, page_transition, disposition,
+                     GlobalRequestID(), should_replace_current_entry,
+                     user_gesture);
 }
 
 void NavigatorImpl::RequestTransferURL(
@@ -729,6 +731,12 @@
   NavigationRequest* navigation_request = frame_tree_node->navigation_request();
   DCHECK(navigation_request);
 
+  // If the request was canceled by the user do not show an error page.
+  if (error_code == net::ERR_ABORTED) {
+    frame_tree_node->ResetNavigationRequest(false);
+    return;
+  }
+
   // Select an appropriate renderer to show the error page.
   RenderFrameHostImpl* render_frame_host =
       frame_tree_node->render_manager()->GetFrameHostForNavigation(
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h
index 7dd2a02..95ad6a7 100644
--- a/content/browser/frame_host/navigator_impl.h
+++ b/content/browser/frame_host/navigator_impl.h
@@ -57,6 +57,7 @@
                       const GURL& url,
                       SiteInstance* source_site_instance,
                       const Referrer& referrer,
+                      ui::PageTransition page_transition,
                       WindowOpenDisposition disposition,
                       bool should_replace_current_entry,
                       bool user_gesture) override;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index fae00d89..57ba8e25 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -67,6 +67,10 @@
 #include "ui/accessibility/ax_tree_update.h"
 #include "url/gurl.h"
 
+#if defined(OS_ANDROID)
+#include "content/browser/mojo/service_registrar_android.h"
+#endif
+
 #if defined(OS_MACOSX)
 #include "content/browser/frame_host/popup_menu_helper_mac.h"
 #endif
@@ -1668,8 +1672,14 @@
 
   TRACE_EVENT1("navigation", "RenderFrameHostImpl::OpenURL", "url",
                validated_url.possibly_invalid_spec());
+  ui::PageTransition transition = ui::PAGE_TRANSITION_LINK;
+  if (frame_tree_node_->parent()) {
+    transition = params.should_replace_current_entry
+                     ? ui::PAGE_TRANSITION_AUTO_SUBFRAME
+                     : ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
+  }
   frame_tree_node_->navigator()->RequestOpenURL(
-      this, validated_url, source_site_instance, params.referrer,
+      this, validated_url, source_site_instance, params.referrer, transition,
       params.disposition, params.should_replace_current_entry,
       params.user_gesture);
 }
@@ -1830,6 +1840,8 @@
 #if defined(OS_ANDROID)
   service_registry_android_.reset(
       new ServiceRegistryAndroid(service_registry_.get()));
+  ServiceRegistrarAndroid::RegisterFrameHostServices(
+      service_registry_android_.get());
 #endif
 }
 
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 865543a..b134423 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -352,6 +352,13 @@
         CancelPending();
       }
 
+      // PlzNavigate: clean up the speculative RenderFrameHost if there is one.
+      if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kEnableBrowserSideNavigation) &&
+          speculative_render_frame_host_) {
+        CleanUpNavigation();
+      }
+
       // This is not a cross-process navigation; the tab is being closed.
       render_frame_host_->render_view_host()->ClosePage();
     }
@@ -819,6 +826,17 @@
                         MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) {
       return nullptr;
     }
+
+    if (navigation_rfh == render_frame_host_) {
+      // TODO(nasko): This is a very ugly hack. The Chrome extensions process
+      // manager still uses NotificationService and expects to see a
+      // RenderViewHost changed notification after WebContents and
+      // RenderFrameHostManager are completely initialized. This should be
+      // removed once the process manager moves away from NotificationService.
+      // See https://crbug.com/462682.
+      delegate_->NotifyMainFrameSwappedFromRenderManager(
+          nullptr, render_frame_host_->render_view_host());
+    }
   }
 
   return navigation_rfh;
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index cfadba5..c5ea0e6 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -489,7 +489,6 @@
   TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame();
 
   // Send an update favicon message and make sure it works.
-  const base::string16 ntp_title = base::ASCIIToUTF16("NTP Title");
   {
     PluginFaviconMessageObserver observer(contents());
     EXPECT_TRUE(ntp_rfh->GetRenderViewHost()->OnMessageReceived(
@@ -502,7 +501,6 @@
   // site.
   ntp_rfh->GetSiteInstance()->increment_active_frame_count();
 
-
   // Navigate to a cross-site URL.
   NavigateActiveAndCommit(kDestUrl);
   TestRenderFrameHost* dest_rfh = contents()->GetMainFrame();
@@ -510,7 +508,6 @@
   EXPECT_NE(ntp_rfh, dest_rfh);
 
   // The new RVH should be able to update its favicon.
-  const base::string16 dest_title = base::ASCIIToUTF16("Google");
   {
     PluginFaviconMessageObserver observer(contents());
     EXPECT_TRUE(
@@ -571,6 +568,61 @@
   EXPECT_TRUE(ntp_process_host->sink().GetUniqueMessageMatching(IPC_REPLY_ID));
 }
 
+// Test that the ViewHostMsg_UpdateFaviconURL IPC message is ignored if the
+// renderer is in the STATE_PENDING_SWAP_OUT_STATE. The favicon code assumes
+// that it only gets ViewHostMsg_UpdateFaviconURL messages for the most recently
+// committed navigation for each WebContentsImpl.
+TEST_F(RenderFrameHostManagerTest, UpdateFaviconURLWhilePendingSwapOut) {
+  const GURL kChromeURL("chrome://foo");
+  const GURL kDestUrl("http://www.google.com/");
+  std::vector<FaviconURL> icons;
+
+  // Navigate our first tab to a chrome url and then to the destination.
+  NavigateActiveAndCommit(kChromeURL);
+  TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
+
+  // Send an update favicon message and make sure it works.
+  {
+    PluginFaviconMessageObserver observer(contents());
+    EXPECT_TRUE(rfh1->GetRenderViewHost()->OnMessageReceived(
+                    ViewHostMsg_UpdateFaviconURL(
+                        rfh1->GetRenderViewHost()->GetRoutingID(), icons)));
+    EXPECT_TRUE(observer.favicon_received());
+  }
+
+  // Create one more frame in the same SiteInstance where |rfh1| exists so that
+  // it doesn't get deleted on navigation to another site.
+  rfh1->GetSiteInstance()->increment_active_frame_count();
+
+  // Navigate to a cross-site URL and commit the new page.
+  controller().LoadURL(
+      kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
+  contents()->GetMainFrame()->PrepareForCommit();
+  TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
+  contents()->TestDidNavigate(rfh2, 1, kDestUrl, ui::PAGE_TRANSITION_TYPED);
+  EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state());
+  EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh1->rfh_state());
+
+  // The new RVH should be able to update its favicons.
+  {
+    PluginFaviconMessageObserver observer(contents());
+    EXPECT_TRUE(rfh2->GetRenderViewHost()->OnMessageReceived(
+        ViewHostMsg_UpdateFaviconURL(rfh2->GetRenderViewHost()->GetRoutingID(),
+                                     icons)));
+    EXPECT_TRUE(observer.favicon_received());
+  }
+
+  // The old renderer, being slow, now updates its favicons. The message should
+  // be ignored.
+  {
+    PluginFaviconMessageObserver observer(contents());
+    EXPECT_TRUE(rfh1->GetRenderViewHost()->OnMessageReceived(
+        ViewHostMsg_UpdateFaviconURL(rfh1->GetRenderViewHost()->GetRoutingID(),
+                                     icons)));
+    EXPECT_FALSE(observer.favicon_received());
+  }
+}
+
 // Ensure that frames aren't added to the frame tree, if the message is coming
 // from a process different than the parent frame's current RenderFrameHost
 // process. Otherwise it is possible to have collisions of routing ids, as they
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc
index 96f55ec..d446057 100644
--- a/content/browser/geofencing/geofencing_manager.cc
+++ b/content/browser/geofencing/geofencing_manager.cc
@@ -110,7 +110,7 @@
 
   // Look up service worker.
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration) {
     callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_NO_SERVICE_WORKER);
@@ -146,7 +146,7 @@
 
   // Look up service worker.
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration) {
     callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_NO_SERVICE_WORKER);
@@ -185,7 +185,7 @@
 
   // Look up service worker.
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration) {
     return GEOFENCING_STATUS_OPERATION_FAILED_NO_SERVICE_WORKER;
@@ -358,7 +358,7 @@
     return;
   }
 
-  service_worker_context_->context()->storage()->FindRegistrationForId(
+  service_worker_context_->FindRegistrationForId(
       registration->service_worker_registration_id,
       registration->service_worker_origin,
       base::Bind(&GeofencingManager::DeliverGeofencingEvent,
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index bafd049..1df45fc8 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -288,7 +288,7 @@
   // it to the GPU process immediately, so we can proceed to the next frame.
   bool should_not_show_frame =
       content::ImageTransportFactory::GetInstance()
-          ->SurfaceShouldNotShowFramesAfterRecycle(params.surface_id);
+          ->SurfaceShouldNotShowFramesAfterSuspendForRecycle(params.surface_id);
   if (should_not_show_frame) {
     OnSurfaceDisplayedCallback(params.surface_id);
   } else {
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index 21f6ad6..9ad5b4d 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -492,22 +492,14 @@
   //       => IndexedDBBackingStore::SetUpMetadata
   //   #2: IndexedDBBackingStore::OpenBackingStore
   //       => IndexedDBBackingStore::CleanUpBlobJournal (no-op)
-  // * Then deletes the database:
-  //   #3: IndexedDBFactoryImpl::DeleteDatabase
-  //       => IndexedDBDatabase::Create
-  //       => IndexedDBBackingStore::CreateIDBDatabaseMetaData
-  //   #4: IndexedDBFactoryImpl::DeleteDatabase
-  //       => IndexedDBDatabase::DeleteDatabase
-  //       => IndexedDBBackingStore::DeleteDatabase
-  //       => IndexedDBBackingStore::CleanUpBlobJournal (no-op)
   // * The test calls open(), to create a new database:
-  //   #5: IndexedDBFactoryImpl::Open
+  //   #3: IndexedDBFactoryImpl::Open
   //       => IndexedDBDatabase::Create
   //       => IndexedDBBackingStore::CreateIDBDatabaseMetaData
-  //   #6: IndexedDBTransaction::Commit - initial "versionchange" transaction
+  //   #4: IndexedDBTransaction::Commit - initial "versionchange" transaction
   // * Once the connection is opened, the test runs:
-  //   #7: IndexedDBTransaction::Commit - the test's "readwrite" transaction)
-  const int instance_num = 7;
+  //   #5: IndexedDBTransaction::Commit - the test's "readwrite" transaction)
+  const int instance_num = 5;
   const int call_num = 1;
   FailOperation(FAIL_CLASS_LEVELDB_TRANSACTION, FAIL_METHOD_COMMIT_DISK_FULL,
                 instance_num, call_num);
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index b72ee73b..860fc0c0 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -11,6 +11,7 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -37,6 +38,34 @@
 
 namespace content {
 
+namespace {
+
+// Used for WebCore.IndexedDB.Schema.ObjectStore.KeyPathType and
+// WebCore.IndexedDB.Schema.Index.KeyPathType histograms. Do not
+// modify (delete, re-order, renumber) these values other than
+// the _MAX value.
+enum HistogramIDBKeyPathType {
+  KEY_PATH_TYPE_NONE = 0,
+  KEY_PATH_TYPE_STRING = 1,
+  KEY_PATH_TYPE_ARRAY = 2,
+  KEY_PATH_TYPE_MAX = 3,  // Keep as last/max entry, for histogram range.
+};
+
+HistogramIDBKeyPathType HistogramKeyPathType(const IndexedDBKeyPath& key_path) {
+  switch (key_path.type()) {
+    case blink::WebIDBKeyPathTypeNull:
+      return KEY_PATH_TYPE_NONE;
+    case blink::WebIDBKeyPathTypeString:
+      return KEY_PATH_TYPE_STRING;
+    case blink::WebIDBKeyPathTypeArray:
+      return KEY_PATH_TYPE_ARRAY;
+  }
+  NOTREACHED();
+  return KEY_PATH_TYPE_NONE;
+}
+
+}  // namespace
+
 // PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the
 // in-progress connection.
 class IndexedDBDatabase::PendingUpgradeCall {
@@ -280,6 +309,11 @@
     return;
   }
 
+  UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType",
+                            HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX);
+  UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement",
+                        auto_increment);
+
   // Store creation is done synchronously, as it may be followed by
   // index creation (also sync) since preemptive OpenCursor/SetIndexKeys
   // may follow.
@@ -349,6 +383,12 @@
   if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id))
     return;
 
+  UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType",
+                            HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX);
+  UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique);
+  UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry",
+                        multi_entry);
+
   // Index creation is done synchronously since preemptive
   // OpenCursor/SetIndexKeys may follow.
   const IndexedDBIndexMetadata index_metadata(
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc
index f818f3f..039cbddf 100644
--- a/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -257,6 +257,26 @@
     return;
   }
 
+  std::vector<base::string16> names = backing_store->GetDatabaseNames(&s);
+  if (!s.ok()) {
+    DLOG(ERROR) << "Internal error getting database names";
+    IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
+                                 "Internal error opening backing store for "
+                                 "indexedDB.deleteDatabase.");
+    callbacks->OnError(error);
+    backing_store = NULL;
+    if (s.IsCorruption())
+      HandleBackingStoreCorruption(origin_url, error);
+    return;
+  }
+  if (!ContainsValue(names, name)) {
+    const int64 version = 0;
+    callbacks->OnSuccess(version);
+    backing_store = NULL;
+    ReleaseBackingStore(origin_url, false /* immediate */);
+    return;
+  }
+
   scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create(
       name, backing_store.get(), this, unique_identifier, &s);
   if (!database.get()) {
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 9631a50..8c86bc9 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -2182,11 +2182,6 @@
   if (info_map->empty())
     return;
 
-  // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is
-  // fixed.
-  tracked_objects::ScopedTracker tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("455952 BrowserThread::PostTask()"));
-
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread,
diff --git a/content/browser/media/capture/content_video_capture_device_core.cc b/content/browser/media/capture/content_video_capture_device_core.cc
index 3c507c6f..757db4a 100644
--- a/content/browser/media/capture/content_video_capture_device_core.cc
+++ b/content/browser/media/capture/content_video_capture_device_core.cc
@@ -75,9 +75,9 @@
   const gfx::Size coded_size((visible_size.width() + 15) & ~15,
                              (visible_size.height() + 15) & ~15);
 
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer =
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
       client_->ReserveOutputBuffer(params_.requested_format.pixel_format,
-                                   coded_size);
+                                   coded_size));
   const bool should_capture =
       oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time);
   const char* event_name =
@@ -134,7 +134,7 @@
   *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame,
                          this,
                          frame_number,
-                         output_buffer,
+                         base::Passed(&output_buffer),
                          capture_begin_time);
   return true;
 }
@@ -180,7 +180,7 @@
 
 void ThreadSafeCaptureOracle::DidCaptureFrame(
     int frame_number,
-    const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
+    scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
     base::TimeTicks capture_begin_time,
     const scoped_refptr<media::VideoFrame>& frame,
     base::TimeTicks timestamp,
@@ -202,7 +202,7 @@
           media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, capture_begin_time);
       frame->metadata()->SetTimeTicks(
           media::VideoFrameMetadata::CAPTURE_END_TIME, base::TimeTicks::Now());
-      client_->OnIncomingCapturedVideoFrame(buffer, frame, timestamp);
+      client_->OnIncomingCapturedVideoFrame(buffer.Pass(), frame, timestamp);
     }
   }
 }
diff --git a/content/browser/media/capture/content_video_capture_device_core.h b/content/browser/media/capture/content_video_capture_device_core.h
index 00ac6249d..f477a15 100644
--- a/content/browser/media/capture/content_video_capture_device_core.h
+++ b/content/browser/media/capture/content_video_capture_device_core.h
@@ -86,7 +86,7 @@
   // Callback invoked on completion of all captures.
   void DidCaptureFrame(
       int frame_number,
-      const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
+      scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
       base::TimeTicks capture_begin_time,
       const scoped_refptr<media::VideoFrame>& frame,
       base::TimeTicks timestamp,
diff --git a/content/browser/media/capture/desktop_capture_device_aura_unittest.cc b/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
index 4c69a57..054c933 100644
--- a/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
+++ b/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
@@ -51,14 +51,28 @@
                      const media::VideoCaptureFormat& frame_format,
                      int clockwise_rotation,
                      const base::TimeTicks& timestamp));
-  MOCK_METHOD2(ReserveOutputBuffer,
-               scoped_refptr<Buffer>(media::VideoPixelFormat format,
-                                     const gfx::Size& dimensions));
-  MOCK_METHOD3(OnIncomingCapturedVideoFrame,
-               void(const scoped_refptr<Buffer>& buffer,
-                    const scoped_refptr<media::VideoFrame>& frame,
-                    const base::TimeTicks& timestamp));
+  MOCK_METHOD0(DoReserveOutputBuffer, void(void));
+  MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
+  MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
   MOCK_METHOD1(OnError, void(const std::string& reason));
+
+  // Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
+  scoped_ptr<Buffer> ReserveOutputBuffer(media::VideoPixelFormat format,
+                                         const gfx::Size& dimensions) override {
+    DoReserveOutputBuffer();
+    return scoped_ptr<Buffer>();
+  }
+  void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer,
+                                const media::VideoCaptureFormat& frame_format,
+                                const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedBuffer();
+  }
+  void OnIncomingCapturedVideoFrame(
+      scoped_ptr<Buffer> buffer,
+      const scoped_refptr<media::VideoFrame>& frame,
+      const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedVideoFrame();
+  }
 };
 
 // Test harness that sets up a minimal environment with necessary stubs.
diff --git a/content/browser/media/capture/desktop_capture_device_unittest.cc b/content/browser/media/capture/desktop_capture_device_unittest.cc
index 1a874f4..c86ddd38 100644
--- a/content/browser/media/capture/desktop_capture_device_unittest.cc
+++ b/content/browser/media/capture/desktop_capture_device_unittest.cc
@@ -69,14 +69,28 @@
                      const media::VideoCaptureFormat& frame_format,
                      int clockwise_rotation,
                      const base::TimeTicks& timestamp));
-  MOCK_METHOD2(ReserveOutputBuffer,
-               scoped_refptr<Buffer>(media::VideoPixelFormat format,
-                                     const gfx::Size& dimensions));
-  MOCK_METHOD3(OnIncomingCapturedVideoFrame,
-               void(const scoped_refptr<Buffer>& buffer,
-                    const scoped_refptr<media::VideoFrame>& frame,
-                    const base::TimeTicks& timestamp));
+  MOCK_METHOD0(DoReserveOutputBuffer, void(void));
+  MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
+  MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
   MOCK_METHOD1(OnError, void(const std::string& reason));
+
+  // Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
+  scoped_ptr<Buffer> ReserveOutputBuffer(media::VideoPixelFormat format,
+                                         const gfx::Size& dimensions) override {
+    DoReserveOutputBuffer();
+    return scoped_ptr<Buffer>();
+  }
+  void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer,
+                                const media::VideoCaptureFormat& frame_format,
+                                const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedBuffer();
+  }
+  void OnIncomingCapturedVideoFrame(
+      scoped_ptr<Buffer> buffer,
+      const scoped_refptr<media::VideoFrame>& frame,
+      const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedVideoFrame();
+  }
 };
 
 // Creates a DesktopFrame that has the first pixel bytes set to
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 8b24ed79..14fa1ff 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
@@ -30,6 +30,7 @@
 #include "media/base/video_util.h"
 #include "media/base/yuv_convert.h"
 #include "skia/ext/platform_canvas.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/display.h"
@@ -315,27 +316,26 @@
   }
   ~StubClient() override {}
 
-  void OnIncomingCapturedData(const uint8* data,
-                              int length,
-                              const media::VideoCaptureFormat& frame_format,
-                              int rotation,
-                              const base::TimeTicks& timestamp) override {
-    FAIL();
-  }
+  MOCK_METHOD5(OnIncomingCapturedData,
+               void(const uint8* data,
+                    int length,
+                    const media::VideoCaptureFormat& frame_format,
+                    int rotation,
+                    const base::TimeTicks& timestamp));
+  MOCK_METHOD9(OnIncomingCapturedYuvData,
+               void (const uint8* y_data,
+                     const uint8* u_data,
+                     const uint8* v_data,
+                     size_t y_stride,
+                     size_t u_stride,
+                     size_t v_stride,
+                     const media::VideoCaptureFormat& frame_format,
+                     int clockwise_rotation,
+                     const base::TimeTicks& timestamp));
 
-  void OnIncomingCapturedYuvData(const uint8* y_data,
-                                 const uint8* u_data,
-                                 const uint8* v_data,
-                                 size_t y_stride,
-                                 size_t u_stride,
-                                 size_t v_stride,
-                                 const media::VideoCaptureFormat& frame_format,
-                                 int clockwise_rotation,
-                                 const base::TimeTicks& timestamp) override {
-    FAIL();
-  }
+  MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
 
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer(
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer(
       media::VideoPixelFormat format,
       const gfx::Size& dimensions) override {
     CHECK_EQ(format, media::PIXEL_FORMAT_I420);
@@ -344,15 +344,20 @@
                                                      &buffer_id_to_drop);
     if (buffer_id == VideoCaptureBufferPool::kInvalidId)
       return NULL;
-    void* data;
-    size_t size;
-    buffer_pool_->GetBufferInfo(buffer_id, &data, &size);
-    return scoped_refptr<media::VideoCaptureDevice::Client::Buffer>(
-        new AutoReleaseBuffer(buffer_pool_, buffer_id, data, size));
+
+    return scoped_ptr<media::VideoCaptureDevice::Client::Buffer>(
+        new AutoReleaseBuffer(
+            buffer_pool_, buffer_pool_->GetBufferHandle(buffer_id), buffer_id));
+  }
+  // Trampoline method to workaround GMOCK problems with scoped_ptr<>.
+  void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer,
+                                const media::VideoCaptureFormat& frame_format,
+                                const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedBuffer();
   }
 
   void OnIncomingCapturedVideoFrame(
-      const scoped_refptr<Buffer>& buffer,
+      scoped_ptr<Buffer> buffer,
       const scoped_refptr<media::VideoFrame>& frame,
       const base::TimeTicks& timestamp) override {
     EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), frame->visible_rect().size());
@@ -376,27 +381,26 @@
  private:
   class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
    public:
-    AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool,
-               int buffer_id,
-               void* data,
-               size_t size)
-        : pool_(pool),
-          id_(buffer_id),
-          data_(data),
-          size_(size) {
+    AutoReleaseBuffer(
+        const scoped_refptr<VideoCaptureBufferPool>& pool,
+        scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle,
+        int buffer_id)
+        : id_(buffer_id),
+          pool_(pool),
+          buffer_handle_(buffer_handle.Pass()) {
       DCHECK(pool_.get());
     }
     int id() const override { return id_; }
-    void* data() const override { return data_; }
-    size_t size() const override { return size_; }
+    size_t size() const override { return buffer_handle_->size(); }
+    void* data() override { return buffer_handle_->data(); }
+    ClientBuffer AsClientBuffer() override { return nullptr; }
 
    private:
     ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); }
 
-    const scoped_refptr<VideoCaptureBufferPool> pool_;
     const int id_;
-    void* const data_;
-    const size_t size_;
+    const scoped_refptr<VideoCaptureBufferPool> pool_;
+    const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_;
   };
 
   scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
diff --git a/content/browser/media/cdm/browser_cdm_manager.cc b/content/browser/media/cdm/browser_cdm_manager.cc
index 3eb55f1..88cf526 100644
--- a/content/browser/media/cdm/browser_cdm_manager.cc
+++ b/content/browser/media/cdm/browser_cdm_manager.cc
@@ -36,13 +36,6 @@
 
 namespace {
 
-// Maximum lengths for various EME API parameters. These are checks to
-// prevent unnecessarily large parameters from being passed around, and the
-// lengths are somewhat arbitrary as the EME spec doesn't specify any limits.
-const size_t kMaxInitDataLength = 64 * 1024;  // 64 KB
-const size_t kMaxSessionResponseLength = 64 * 1024;  // 64 KB
-const size_t kMaxKeySystemLength = 256;
-
 // The ID used in this class is a concatenation of |render_frame_id| and
 // |cdm_id|, i.e. (render_frame_id << 32) + cdm_id.
 
@@ -300,7 +293,7 @@
                                         int cdm_id,
                                         const std::string& key_system,
                                         const GURL& security_origin) {
-  if (key_system.size() > kMaxKeySystemLength) {
+  if (key_system.size() > media::limits::kMaxKeySystemLength) {
     // This failure will be discovered and reported by OnCreateSession()
     // as GetCdm() will return null.
     NOTREACHED() << "Invalid key system: " << key_system;
@@ -346,7 +339,7 @@
   scoped_ptr<NewSessionPromise> promise(
       new NewSessionPromise(this, render_frame_id, cdm_id, promise_id));
 
-  if (init_data.size() > kMaxInitDataLength) {
+  if (init_data.size() > media::limits::kMaxInitDataLength) {
     LOG(WARNING) << "InitData for ID: " << cdm_id
                  << " too long: " << init_data.size();
     promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Init data too long.");
@@ -400,7 +393,7 @@
     return;
   }
 
-  if (response.size() > kMaxSessionResponseLength) {
+  if (response.size() > media::limits::kMaxSessionResponseLength) {
     LOG(WARNING) << "Response for ID " << cdm_id
                  << " is too long: " << response.size();
     promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Response too long.");
diff --git a/content/browser/media/media_internals_proxy.cc b/content/browser/media/media_internals_proxy.cc
index 2181caa..05f4dd82 100644
--- a/content/browser/media/media_internals_proxy.cc
+++ b/content/browser/media/media_internals_proxy.cc
@@ -122,7 +122,8 @@
   MediaInternals::GetInstance()->AddUpdateCallback(update_callback_);
   if (GetContentClient()->browser()->GetNetLog()) {
     net::NetLog* net_log = GetContentClient()->browser()->GetNetLog();
-    net_log->DeprecatedAddObserver(this, net::NetLog::LOG_ALL_BUT_BYTES);
+    net_log->DeprecatedAddObserver(
+        this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
   }
 }
 
diff --git a/content/browser/mojo/service_registrar_android.cc b/content/browser/mojo/service_registrar_android.cc
index 6e6928983..30ea74210 100644
--- a/content/browser/mojo/service_registrar_android.cc
+++ b/content/browser/mojo/service_registrar_android.cc
@@ -23,4 +23,11 @@
       env, registry->GetObj().obj(), base::android::GetApplicationContext());
 }
 
+// static
+void ServiceRegistrarAndroid::RegisterFrameHostServices(
+    ServiceRegistryAndroid* registry) {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_ServiceRegistrar_registerFrameHostServices(
+      env, registry->GetObj().obj(), base::android::GetApplicationContext());
+}
 }  // namespace content
diff --git a/content/browser/mojo/service_registrar_android.h b/content/browser/mojo/service_registrar_android.h
index ae81646..fdf62d4f 100644
--- a/content/browser/mojo/service_registrar_android.h
+++ b/content/browser/mojo/service_registrar_android.h
@@ -17,6 +17,7 @@
  public:
   static bool Register(JNIEnv* env);
   static void RegisterProcessHostServices(ServiceRegistryAndroid* registry);
+  static void RegisterFrameHostServices(ServiceRegistryAndroid* registry);
 };
 
 }  // namespace content
diff --git a/content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc b/content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
index 7f7d350..17ee080 100644
--- a/content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
+++ b/content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
@@ -83,7 +83,7 @@
   for (const auto& port : sent_message_ports)
     MessagePortService::GetInstance()->HoldMessages(port.id);
 
-  service_worker_context_->context()->storage()->FindRegistrationForId(
+  service_worker_context_->FindRegistrationForId(
       service_worker_registration_id_, service_worker_registration_origin_,
       base::Bind(&NavigatorConnectServiceWorkerService::DeliverMessage,
                  weak_factory_.GetWeakPtr(), message.message_as_string,
@@ -143,7 +143,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   // Find the right service worker to service this connection.
-  service_worker_context_->context()->storage()->FindRegistrationForDocument(
+  service_worker_context_->FindRegistrationForDocument(
       client.target_url,
       base::Bind(&NavigatorConnectServiceWorkerServiceFactory::
                      GotServiceWorkerRegistration,
diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc
index 60b7cff7..5da609b 100644
--- a/content/browser/net/sqlite_persistent_cookie_store.cc
+++ b/content/browser/net/sqlite_persistent_cookie_store.cc
@@ -139,6 +139,10 @@
   ~Backend() {
     DCHECK(!db_.get()) << "Close should have already been called.";
     DCHECK(num_pending_ == 0 && pending_.empty());
+
+    for (net::CanonicalCookie* cookie : cookies_) {
+      delete cookie;
+    }
   }
 
   // Database upgrade statements.
@@ -249,6 +253,8 @@
   // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce
   // the number of messages sent to the client runner. Sent back in response to
   // individual load requests for domain keys or when all loading completes.
+  // Ownership of the cookies in this vector is transferred to the client in
+  // response to individual load requests or when all loading completes.
   std::vector<net::CanonicalCookie*> cookies_;
 
   // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB.
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc
index b111961..78d2a85 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -134,7 +134,7 @@
     return;
   }
 
-  service_worker_context->context()->storage()->FindRegistrationForId(
+  service_worker_context->FindRegistrationForId(
       notification_database_data.service_worker_registration_id,
       origin,
       base::Bind(&DispatchNotificationClickEventOnRegistration,
diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc
index 2817d544..939a761 100644
--- a/content/browser/push_messaging/push_messaging_message_filter.cc
+++ b/content/browser/push_messaging/push_messaging_message_filter.cc
@@ -225,7 +225,7 @@
   data.user_visible = user_visible;
 
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration ||
       !service_worker_registration->active_version()) {
@@ -234,7 +234,7 @@
   }
   data.requesting_origin = service_worker_registration->pattern().GetOrigin();
 
-  service_worker_context_->context()->storage()->StoreUserData(
+  service_worker_context_->StoreRegistrationUserData(
       service_worker_registration_id,
       data.requesting_origin,
       kPushSenderIdServiceWorkerKey,
@@ -255,7 +255,7 @@
   data.user_visible = user_visible;
 
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration) {
     SendRegisterError(data, PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER);
@@ -282,7 +282,7 @@
     const RegisterData& data,
     const std::string& sender_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  service_worker_context_->context()->storage()->GetUserData(
+  service_worker_context_->GetRegistrationUserData(
       data.service_worker_registration_id,
       kPushRegistrationIdServiceWorkerKey,
       base::Bind(&PushMessagingMessageFilter::DidCheckForExistingRegistration,
@@ -311,7 +311,7 @@
         base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()),
                    data, sender_id));
   } else {
-    service_worker_context_->context()->storage()->GetUserData(
+    service_worker_context_->GetRegistrationUserData(
         data.service_worker_registration_id,
         kPushSenderIdServiceWorkerKey,
         base::Bind(&PushMessagingMessageFilter::DidGetSenderIdFromStorage,
@@ -403,7 +403,7 @@
     const RegisterData& data,
     const std::string& push_registration_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  service_worker_context_->context()->storage()->StoreUserData(
+  service_worker_context_->StoreRegistrationUserData(
       data.service_worker_registration_id,
       data.requesting_origin,
       kPushRegistrationIdServiceWorkerKey,
@@ -474,14 +474,14 @@
     int request_id, int64_t service_worker_registration_id) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration) {
     DidUnregister(request_id, PUSH_UNREGISTRATION_STATUS_NO_SERVICE_WORKER);
     return;
   }
 
-  service_worker_context_->context()->storage()->GetUserData(
+  service_worker_context_->GetRegistrationUserData(
       service_worker_registration_id,
       kPushRegistrationIdServiceWorkerKey,
       base::Bind(
@@ -500,7 +500,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   if (service_worker_status == SERVICE_WORKER_OK) {
-    service_worker_context_->context()->storage()->GetUserData(
+    service_worker_context_->GetRegistrationUserData(
         service_worker_registration_id,
         kPushSenderIdServiceWorkerKey,
         base::Bind(
@@ -625,7 +625,7 @@
     PushUnregistrationStatus unregistration_status) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  service_worker_context_->context()->storage()->ClearUserData(
+  service_worker_context_->ClearRegistrationUserData(
       service_worker_registration_id,
       kPushRegistrationIdServiceWorkerKey,
       base::Bind(&PushMessagingMessageFilter::DidClearRegistrationData,
@@ -686,7 +686,7 @@
     int64_t service_worker_registration_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   // TODO(johnme): Validate arguments?
-  service_worker_context_->context()->storage()->GetUserData(
+  service_worker_context_->GetRegistrationUserData(
       service_worker_registration_id,
       kPushRegistrationIdServiceWorkerKey,
       base::Bind(&PushMessagingMessageFilter::DidGetRegistration,
@@ -754,7 +754,7 @@
     bool user_visible) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   ServiceWorkerRegistration* service_worker_registration =
-      service_worker_context_->context()->GetLiveRegistration(
+      service_worker_context_->GetLiveRegistration(
           service_worker_registration_id);
   if (!service_worker_registration) {
     Send(new PushMessagingMsg_GetPermissionStatusError(request_id));
diff --git a/content/browser/push_messaging/push_messaging_router.cc b/content/browser/push_messaging/push_messaging_router.cc
index 0c789147..76de068 100644
--- a/content/browser/push_messaging/push_messaging_router.cc
+++ b/content/browser/push_messaging/push_messaging_router.cc
@@ -49,7 +49,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   // Try to acquire the registration from storage. If it's already live we'll
   // receive it right away. If not, it will be revived from storage.
-  service_worker_context->context()->storage()->FindRegistrationForId(
+  service_worker_context->FindRegistrationForId(
       service_worker_registration_id,
       origin,
       base::Bind(&PushMessagingRouter::FindServiceWorkerRegistrationCallback,
diff --git a/content/browser/quota_dispatcher_host.cc b/content/browser/quota_dispatcher_host.cc
index 2ea8a5ec..3cbfee2 100644
--- a/content/browser/quota_dispatcher_host.cc
+++ b/content/browser/quota_dispatcher_host.cc
@@ -118,8 +118,7 @@
     DCHECK(dispatcher_host());
 
     DCHECK(params_.storage_type == storage::kStorageTypeTemporary ||
-           params_.storage_type == storage::kStorageTypePersistent ||
-           params_.storage_type == storage::kStorageTypeSyncable);
+           params_.storage_type == storage::kStorageTypePersistent);
     if (params_.storage_type == storage::kStorageTypePersistent) {
       quota_manager()->GetUsageAndQuotaForWebApps(
           params_.origin_url, params_.storage_type,
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
index 0ecaaea..3569b40b 100644
--- a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
+++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
@@ -319,9 +319,11 @@
         1);
   }
 
-  latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
-                            latency_component_id_, ++last_event_id_);
-  latency->TraceEventType(WebInputEventTraits::GetName(event.type));
+  latency->AddLatencyNumberWithTraceName(
+      ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
+      latency_component_id_, ++last_event_id_,
+      WebInputEventTraits::GetName(event.type));
+
   UpdateLatencyCoordinates(event, device_scale_factor_, latency);
 
   if (event.type == blink::WebInputEvent::GestureScrollBegin) {
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool.cc b/content/browser/renderer_host/media/video_capture_buffer_pool.cc
index a336a7e..c5298c1 100644
--- a/content/browser/renderer_host/media/video_capture_buffer_pool.cc
+++ b/content/browser/renderer_host/media/video_capture_buffer_pool.cc
@@ -7,6 +7,10 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "media/base/video_frame.h"
 
 using media::VideoFrame;
 
@@ -21,8 +25,8 @@
     VideoFrame::Format frame_format;
   } const kVideoPixelFormatToVideoFrameFormat[] = {
       {media::PIXEL_FORMAT_I420, VideoFrame::I420},
-      {media::PIXEL_FORMAT_ARGB, VideoFrame::ARGB},
       {media::PIXEL_FORMAT_TEXTURE, VideoFrame::NATIVE_TEXTURE},
+      {media::PIXEL_FORMAT_GPUMEMORYBUFFER, VideoFrame::NATIVE_TEXTURE},
   };
 
   for (const auto& format_pair : kVideoPixelFormatToVideoFrameFormat) {
@@ -34,15 +38,60 @@
   return VideoFrame::UNKNOWN;
 }
 
+// A simple holder of a memory-backed buffer and accesors to it.
+class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle {
+ public:
+  SimpleBufferHandle(void* data, size_t size) : data_(data), size_(size) {}
+  ~SimpleBufferHandle() override {}
+
+  size_t size() const override { return size_; }
+  void* data() override { return data_; }
+  ClientBuffer AsClientBuffer() override { return nullptr; }
+
+ private:
+  void* const data_;
+  const size_t size_;
+};
+
+// A holder of a GpuMemoryBuffer-backed buffer, Map()ed on ctor and Unmap()ed on
+// dtor. Holds a weak reference to its GpuMemoryBuffer.
+// TODO(mcasas) Map()ed on ctor, or on first use?
+class GpuMemoryBufferBufferHandle
+    final : public VideoCaptureBufferPool::BufferHandle {
+ public:
+  GpuMemoryBufferBufferHandle(gfx::GpuMemoryBuffer* gmb, size_t size)
+      : gmb_(gmb),
+        data_(new void* [GpuMemoryBufferImpl::
+                             NumberOfPlanesForGpuMemoryBufferFormat(
+                                 gmb_->GetFormat())]),
+        size_(size) {
+    DCHECK(gmb && !gmb_->IsMapped());
+    gmb_->Map(data_.get());
+  }
+  ~GpuMemoryBufferBufferHandle() override { gmb_->Unmap(); }
+
+  size_t size() const override { return size_; }
+  void* data() override { return data_[0]; }
+  ClientBuffer AsClientBuffer() override { return gmb_->AsClientBuffer(); }
+
+ private:
+  gfx::GpuMemoryBuffer* const gmb_;
+  scoped_ptr<void*[]> data_;
+  const size_t size_;
+};
+
 // Tracker specifics for SharedMemory.
 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker {
  public:
   SharedMemTracker();
-
   bool Init(VideoFrame::Format format, const gfx::Size& dimensions) override;
-  void* storage() override { return shared_memory_.memory(); }
-  size_t requested_size() override { return shared_memory_.requested_size(); }
-  size_t mapped_size() override { return shared_memory_.mapped_size(); }
+
+  size_t mapped_size() const override { return shared_memory_.mapped_size(); }
+
+  scoped_ptr<BufferHandle> GetBufferHandle() override {
+    return make_scoped_ptr(
+        new SimpleBufferHandle(shared_memory_.memory(), mapped_size()));
+  }
 
   bool ShareToProcess(base::ProcessHandle process_handle,
                       base::SharedMemoryHandle* new_handle) override {
@@ -54,23 +103,84 @@
   base::SharedMemory shared_memory_;
 };
 
-VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker()
-    : Tracker() {}
+// Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its
+// associated pixel dimensions.
+class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker {
+ public:
+  GpuMemoryBufferTracker();
+  bool Init(VideoFrame::Format format, const gfx::Size& dimensions) override;
+  ~GpuMemoryBufferTracker() override;
+
+  size_t mapped_size() const override { return packed_size_; }
+  scoped_ptr<BufferHandle> GetBufferHandle() override {
+    return make_scoped_ptr(new GpuMemoryBufferBufferHandle(
+        gpu_memory_buffer_.get(), packed_size_));
+  }
+
+  bool ShareToProcess(base::ProcessHandle process_handle,
+                      base::SharedMemoryHandle* new_handle) override {
+    return true;
+  }
+
+ private:
+  size_t packed_size_;
+  scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
+};
+
+VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {
+}
 
 bool VideoCaptureBufferPool::SharedMemTracker::Init(
     VideoFrame::Format format,
     const gfx::Size& dimensions) {
+  DVLOG(2) << "allocating ShMem of " << dimensions.ToString();
   // Input |dimensions| can be 0x0 for trackers that do not require memory
   // backing. The allocated size is calculated using VideoFrame methods since
   // this will be the abstraction used to wrap the underlying data.
-  return shared_memory_.CreateAndMapAnonymous(
-      VideoFrame::AllocationSize(format, dimensions));
+  set_pixel_count(dimensions.GetArea());
+  const size_t byte_count = VideoFrame::AllocationSize(format, dimensions);
+  if (!byte_count)
+    return true;
+  return shared_memory_.CreateAndMapAnonymous(byte_count);
+}
+
+VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker()
+    : Tracker(), gpu_memory_buffer_(nullptr) {}
+
+VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() {
+  if (gpu_memory_buffer_->IsMapped())
+    gpu_memory_buffer_->Unmap();
+}
+
+bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init(
+    VideoFrame::Format format,
+    const gfx::Size& dimensions) {
+  DVLOG(2) << "allocating GMB for " << dimensions.ToString();
+  // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread.
+  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserGpuMemoryBufferManager::current());
+  set_pixel_count(dimensions.GetArea());
+  gpu_memory_buffer_ =
+      BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer(
+          dimensions,
+          gfx::GpuMemoryBuffer::BGRA_8888,
+          gfx::GpuMemoryBuffer::MAP);
+  DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer";
+  if (!gpu_memory_buffer_.get())
+    return false;
+  int plane_sizes;
+  gpu_memory_buffer_->GetStride(&plane_sizes);
+  packed_size_ = plane_sizes * dimensions.height();
+  return true;
 }
 
 //static
 scoped_ptr<VideoCaptureBufferPool::Tracker>
-VideoCaptureBufferPool::Tracker::CreateTracker() {
-  return make_scoped_ptr(new SharedMemTracker());
+VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) {
+  if (!use_gmb)
+    return make_scoped_ptr(new SharedMemTracker());
+  else
+    return make_scoped_ptr(new GpuMemoryBufferTracker());
 }
 
 VideoCaptureBufferPool::Tracker::~Tracker() {}
@@ -101,25 +211,22 @@
     *memory_size = tracker->mapped_size();
     return remote_handle;
   }
-  DPLOG(ERROR) << "Error mapping Shared Memory.";
+  DPLOG(ERROR) << "Error mapping Shared Memory";
   return base::SharedMemoryHandle();
 }
 
-bool VideoCaptureBufferPool::GetBufferInfo(int buffer_id,
-                                           void** storage,
-                                           size_t* size) {
+scoped_ptr<VideoCaptureBufferPool::BufferHandle>
+VideoCaptureBufferPool::GetBufferHandle(int buffer_id) {
   base::AutoLock lock(lock_);
 
   Tracker* tracker = GetTracker(buffer_id);
   if (!tracker) {
     NOTREACHED() << "Invalid buffer_id.";
-    return false;
+    return scoped_ptr<BufferHandle>();
   }
 
   DCHECK(tracker->held_by_producer());
-  *storage = tracker->storage();
-  *size = tracker->mapped_size();
-  return true;
+  return tracker->GetBufferHandle();
 }
 
 int VideoCaptureBufferPool::ReserveForProducer(media::VideoPixelFormat format,
@@ -177,30 +284,28 @@
     const gfx::Size& dimensions,
     int* buffer_id_to_drop) {
   DCHECK(format == media::PIXEL_FORMAT_I420 ||
-         format == media::PIXEL_FORMAT_ARGB ||
-         format == media::PIXEL_FORMAT_TEXTURE);
+         format == media::PIXEL_FORMAT_TEXTURE ||
+         format == media::PIXEL_FORMAT_GPUMEMORYBUFFER );
   lock_.AssertAcquired();
-  const media::VideoFrame::Format frame_format =
-      VideoPixelFormatToVideoFrameFormat(format);
-  const size_t size_in_bytes =
-      VideoFrame::AllocationSize(frame_format, dimensions);
+  *buffer_id_to_drop = kInvalidId;
 
+  const size_t size_in_pixels = dimensions.GetArea();
   // Look for a tracker that's allocated, big enough, and not in use. Track the
   // largest one that's not big enough, in case we have to reallocate a tracker.
   *buffer_id_to_drop = kInvalidId;
-  size_t realloc_size = 0;
+  size_t largest_size_in_pixels = 0;
   TrackerMap::iterator tracker_to_drop = trackers_.end();
   for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end();
        ++it) {
     Tracker* const tracker = it->second;
     if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) {
-      if (tracker->requested_size() >= size_in_bytes) {
+      if (tracker->pixel_count() >= size_in_pixels) {
         // Existing tracker is big enough. Reuse it.
         tracker->set_held_by_producer(true);
         return it->first;
       }
-      if (tracker->requested_size() > realloc_size) {
-        realloc_size = tracker->requested_size();
+      if (tracker->pixel_count() > largest_size_in_pixels) {
+        largest_size_in_pixels = tracker->pixel_count();
         tracker_to_drop = it;
       }
     }
@@ -220,9 +325,13 @@
 
   // Create the new tracker.
   const int buffer_id = next_buffer_id_++;
-  scoped_ptr<Tracker> tracker = Tracker::CreateTracker();
-  if (!tracker->Init(frame_format, dimensions))
+
+  scoped_ptr<Tracker> tracker =
+      Tracker::CreateTracker(format == media::PIXEL_FORMAT_GPUMEMORYBUFFER);
+  if (!tracker->Init(VideoPixelFormatToVideoFrameFormat(format), dimensions)) {
+    DLOG(ERROR) << "Error initializing Tracker";
     return kInvalidId;
+  }
   tracker->set_held_by_producer(true);
   trackers_[buffer_id] = tracker.release();
 
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool.h b/content/browser/renderer_host/media/video_capture_buffer_pool.h
index 2546499..f3c22f7 100644
--- a/content/browser/renderer_host/media/video_capture_buffer_pool.h
+++ b/content/browser/renderer_host/media/video_capture_buffer_pool.h
@@ -9,7 +9,6 @@
 
 #include "base/basictypes.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/shared_memory.h"
 #include "base/process/process.h"
 #include "base/synchronization/lock.h"
@@ -17,13 +16,14 @@
 #include "media/base/video_capture_types.h"
 #include "media/base/video_frame.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/gpu_memory_buffer.h"
 
 namespace content {
 
 // A thread-safe class that does the bookkeeping and lifetime management for a
 // pool of pixel buffers cycled between an in-process producer (e.g. a
 // VideoCaptureDevice) and a set of out-of-process consumers. The pool is
-// intended to be orchestrated by a VideoCaptureController, but is designed
+// intended to be orchestrated by a VideoCaptureDevice::Client, but is designed
 // to outlive the controller if necessary. The pixel buffers may be backed by a
 // SharedMemory, but this is not compulsory.
 //
@@ -44,6 +44,16 @@
     : public base::RefCountedThreadSafe<VideoCaptureBufferPool> {
  public:
   static const int kInvalidId;
+
+  // Abstraction of a pool's buffer data buffer and size for clients.
+  class BufferHandle {
+   public:
+    virtual ~BufferHandle() {}
+    virtual size_t size() const = 0;
+    virtual void* data() = 0;
+    virtual ClientBuffer AsClientBuffer() = 0;
+  };
+
   explicit VideoCaptureBufferPool(int count);
 
   // One-time (per client/per-buffer) initialization to share a particular
@@ -53,9 +63,8 @@
                                           base::ProcessHandle process_handle,
                                           size_t* memory_size);
 
-  // Query the memory parameters of |buffer_id|. Fills in parameters in the
-  // pointer arguments, and returns true iff the buffer exists.
-  bool GetBufferInfo(int buffer_id, void** storage, size_t* size);
+  // Try and obtain a BufferHandle for |buffer_id|.
+  scoped_ptr<BufferHandle> GetBufferHandle(int buffer_id);
 
   // Reserve or allocate a buffer to support a packed frame of |dimensions| of
   // pixel |format| and return its id. This will fail (returning kInvalidId) if
@@ -90,35 +99,37 @@
   void RelinquishConsumerHold(int buffer_id, int num_clients);
 
  private:
+  class GpuMemoryBufferTracker;
   class SharedMemTracker;
   // Generic class to keep track of the state of a given mappable resource.
   class Tracker {
    public:
-    static scoped_ptr<Tracker> CreateTracker();
+    static scoped_ptr<Tracker> CreateTracker(bool use_gmb);
 
-    Tracker() : held_by_producer_(false), consumer_hold_count_(0) {}
+    Tracker()
+        : pixel_count_(0), held_by_producer_(false), consumer_hold_count_(0) {}
     virtual bool Init(media::VideoFrame::Format format,
                       const gfx::Size& dimensions) = 0;
     virtual ~Tracker();
 
+    size_t pixel_count() const { return pixel_count_; }
+    void set_pixel_count(size_t count) { pixel_count_ = count; }
     bool held_by_producer() const { return held_by_producer_; }
     void set_held_by_producer(bool value) { held_by_producer_ = value; }
     int consumer_hold_count() const { return consumer_hold_count_; }
     void set_consumer_hold_count(int value) { consumer_hold_count_ = value; }
 
-    // Returns a void* to the underlying storage, be that a memory block for
-    // Shared Memory, or a GpuMemoryBuffer.
-    virtual void* storage() = 0;
-    // Amount of bytes requested when first created. Can be zero if it does not
-    // need RAM, e.g. is allocated in GPU memory.
-    virtual size_t requested_size() = 0;
+    // Returns a handle to the underlying storage, be that a block of Shared
+    // Memory, or a GpuMemoryBuffer.
+    virtual scoped_ptr<BufferHandle> GetBufferHandle() = 0;
     // The actual size of the underlying backing resource.
-    virtual size_t mapped_size() = 0;
+    virtual size_t mapped_size() const = 0;
 
     virtual bool ShareToProcess(base::ProcessHandle process_handle,
                                 base::SharedMemoryHandle* new_handle) = 0;
 
    private:
+    size_t pixel_count_;
     // Indicates whether this Tracker is currently referenced by the producer.
     bool held_by_producer_;
     // Number of consumer processes which hold this Tracker.
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc b/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
index e8f446f..ab3814ae 100644
--- a/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
@@ -9,139 +9,245 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "cc/test/test_context_provider.h"
+#include "cc/test/test_web_graphics_context_3d.h"
+#include "content/browser/compositor/buffer_queue.h"
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
 #include "content/browser/renderer_host/media/video_capture_controller.h"
 #include "media/base/video_frame.h"
 #include "media/base/video_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
-class VideoCaptureBufferPoolTest : public testing::Test {
+static const media::VideoPixelFormat kCaptureFormats[] = {
+  media::PIXEL_FORMAT_I420,
+  media::PIXEL_FORMAT_TEXTURE,
+#if !defined(OS_ANDROID)
+  media::PIXEL_FORMAT_GPUMEMORYBUFFER
+#endif
+};
+
+class VideoCaptureBufferPoolTest
+    : public testing::TestWithParam<media::VideoPixelFormat> {
  protected:
+  // A GpuMemoryBuffer Mock to provide a trivial RGBA buffer as Map() backing.
+  // We need to allocate on ctor and deallocate on dtor so that consecutive
+  // Map()-Unmap() cycles yield the same underlying data pointer.
+  class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer {
+   public:
+    explicit MockGpuMemoryBuffer(const gfx::Size& size)
+        : size_(size), data_(new uint8[size_.GetArea() * 4]), mapped_(false) {}
+    ~MockGpuMemoryBuffer() override { delete[] data_; }
+
+    bool Map(void** data) override {
+      EXPECT_EQ(mapped_, false);
+      mapped_ = true;
+      data[0] = static_cast<void*>(data_);
+      return true;
+    }
+    void Unmap() override {
+      EXPECT_EQ(mapped_, true);
+      mapped_ = false;
+    }
+    bool IsMapped() const override { return mapped_; }
+    Format GetFormat() const override { return BGRA_8888; }
+    void GetStride(int* stride) const override {
+      *stride = size_.width() * 4;
+      return;
+    }
+    gfx::GpuMemoryBufferHandle GetHandle() const override {
+      return gfx::GpuMemoryBufferHandle();
+    }
+    ClientBuffer AsClientBuffer() override { return nullptr; }
+
+   private:
+    const gfx::Size size_;
+    uint8* const data_;
+    bool mapped_;
+  };
+
+#if !defined(OS_ANDROID)
+  // The next two classes are needed to replicate the GpuMemoryBuffer allocation
+  // on Browser side.
+  class StubBrowserGpuMemoryBufferManager
+      : public BrowserGpuMemoryBufferManager {
+   public:
+    StubBrowserGpuMemoryBufferManager()
+        : BrowserGpuMemoryBufferManager(nullptr, 1) {}
+
+    scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
+        const gfx::Size& size,
+        gfx::GpuMemoryBuffer::Format format,
+        gfx::GpuMemoryBuffer::Usage usage) override {
+      return make_scoped_ptr(new MockGpuMemoryBuffer(size));
+    }
+  };
+  class MockBufferQueue : public BufferQueue {
+   public:
+    MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
+                    BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager,
+                    unsigned int internalformat)
+        : BufferQueue(context_provider,
+                      internalformat,
+                      nullptr,
+                      gpu_memory_buffer_manager,
+                      1) {}
+    MOCK_METHOD4(CopyBufferDamage,
+                 void(int, int, const gfx::Rect&, const gfx::Rect&));
+  };
+#endif
+
+  // This is a generic Buffer tracker
   class Buffer {
    public:
     Buffer(const scoped_refptr<VideoCaptureBufferPool> pool,
-           int id,
-           void* data,
-           size_t size)
-        : pool_(pool), id_(id), data_(data), size_(size) {}
+           scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle,
+           int id)
+        : id_(id), pool_(pool), buffer_handle_(buffer_handle.Pass()) {}
     ~Buffer() { pool_->RelinquishProducerReservation(id()); }
     int id() const { return id_; }
-    void* data() const { return data_; }
-    size_t size() const { return size_; }
+    size_t size() { return buffer_handle_->size(); }
+    void* data() { return buffer_handle_->data(); }
 
    private:
-    const scoped_refptr<VideoCaptureBufferPool> pool_;
     const int id_;
-    void* const data_;
-    const size_t size_;
+    const scoped_refptr<VideoCaptureBufferPool> pool_;
+    const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_;
   };
+
   VideoCaptureBufferPoolTest()
       : expected_dropped_id_(0),
         pool_(new VideoCaptureBufferPool(3)) {}
 
+#if !defined(OS_ANDROID)
+  void SetUp() override {
+    scoped_refptr<cc::TestContextProvider> context_provider =
+        cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create());
+    context_provider->BindToCurrentThread();
+    gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager);
+    output_surface_.reset(new MockBufferQueue(
+        context_provider, gpu_memory_buffer_manager_.get(), GL_RGBA));
+    output_surface_->Initialize();
+  }
+#endif
+
   void ExpectDroppedId(int expected_dropped_id) {
     expected_dropped_id_ = expected_dropped_id;
   }
 
-  scoped_ptr<Buffer> ReserveI420Buffer(const gfx::Size& dimensions) {
-    // To verify that ReserveI420Buffer always sets |buffer_id_to_drop|,
+  scoped_ptr<Buffer> ReserveBuffer(const gfx::Size& dimensions,
+                                   media::VideoPixelFormat pixel_format) {
+    // To verify that ReserveBuffer always sets |buffer_id_to_drop|,
     // initialize it to something different than the expected value.
     int buffer_id_to_drop = ~expected_dropped_id_;
-    int buffer_id = pool_->ReserveForProducer(media::PIXEL_FORMAT_I420,
-                                              dimensions, &buffer_id_to_drop);
+    DVLOG(1) << media::VideoCaptureFormat::PixelFormatToString(pixel_format)
+             << " " << dimensions.ToString();
+    int buffer_id =
+        pool_->ReserveForProducer(pixel_format, dimensions, &buffer_id_to_drop);
     if (buffer_id == VideoCaptureBufferPool::kInvalidId)
       return scoped_ptr<Buffer>();
-
-    void* memory;
-    size_t size;
-    pool_->GetBufferInfo(buffer_id, &memory, &size);
     EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop);
-    return scoped_ptr<Buffer>(new Buffer(pool_, buffer_id, memory, size));
+
+    scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle =
+        pool_->GetBufferHandle(buffer_id);
+    return scoped_ptr<Buffer>(
+        new Buffer(pool_, buffer_handle.Pass(), buffer_id));
   }
 
   int expected_dropped_id_;
   scoped_refptr<VideoCaptureBufferPool> pool_;
 
  private:
+#if !defined(OS_ANDROID)
+  scoped_ptr<StubBrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_;
+  scoped_ptr<MockBufferQueue> output_surface_;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest);
 };
 
-TEST_F(VideoCaptureBufferPoolTest, BufferPool) {
-  const gfx::Size size_lo = gfx::Size(640, 480);
-  const gfx::Size size_hi = gfx::Size(1024, 768);
-  scoped_refptr<media::VideoFrame> non_pool_frame =
-      media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo,
-                                     gfx::Rect(size_lo), size_lo,
-                                     base::TimeDelta());
+TEST_P(VideoCaptureBufferPoolTest, BufferPool) {
+  const gfx::Size size_lo = gfx::Size(10, 10);
+  const gfx::Size size_hi = gfx::Size(21, 33);
+  const media::VideoCaptureFormat format_lo(size_lo, 0.0, GetParam());
+  const media::VideoCaptureFormat format_hi(size_hi, 0.0, GetParam());
 
   // Reallocation won't happen for the first part of the test.
   ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
 
-  scoped_ptr<Buffer> buffer1 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer1.get());
-  ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
-            buffer1->size());
-  scoped_ptr<Buffer> buffer2 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer2.get());
-  ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
-            buffer2->size());
-  scoped_ptr<Buffer> buffer3 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer3.get());
-  ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
-            buffer3->size());
+  scoped_ptr<Buffer> buffer1 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer1.get());
+  ASSERT_LE(format_lo.ImageAllocationSize(), buffer1->size());
+  scoped_ptr<Buffer> buffer2 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer2.get());
+  ASSERT_LE(format_lo.ImageAllocationSize(), buffer2->size());
+  scoped_ptr<Buffer> buffer3 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer3.get());
+  ASSERT_LE(format_lo.ImageAllocationSize(), buffer3->size());
 
+  // Texture backed Frames cannot be manipulated via mapping.
+  if (GetParam() != media::PIXEL_FORMAT_TEXTURE) {
+    ASSERT_NE(nullptr, buffer1->data());
+    ASSERT_NE(nullptr, buffer2->data());
+    ASSERT_NE(nullptr, buffer3->data());
+
+  }
   // Touch the memory.
-  memset(buffer1->data(), 0x11, buffer1->size());
-  memset(buffer2->data(), 0x44, buffer2->size());
-  memset(buffer3->data(), 0x77, buffer3->size());
+  if (buffer1->data() != nullptr)
+    memset(buffer1->data(), 0x11, buffer1->size());
+  if (buffer2->data() != nullptr)
+    memset(buffer2->data(), 0x44, buffer2->size());
+  if (buffer3->data() != nullptr)
+    memset(buffer3->data(), 0x77, buffer3->size());
 
   // Fourth buffer should fail.
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   // Release 1st buffer and retry; this should succeed.
   buffer1.reset();
-  scoped_ptr<Buffer> buffer4 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer4.get());
+  scoped_ptr<Buffer> buffer4 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer4.get());
 
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
-  ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_hi, GetParam())) << "Pool should be empty";
 
   // Validate the IDs
   int buffer_id2 = buffer2->id();
   ASSERT_EQ(1, buffer_id2);
-  int buffer_id3 = buffer3->id();
+  const int buffer_id3 = buffer3->id();
   ASSERT_EQ(2, buffer_id3);
-  void* const memory_pointer3 = buffer3->data();
-  int buffer_id4 = buffer4->id();
+  const int buffer_id4 = buffer4->id();
   ASSERT_EQ(0, buffer_id4);
+  void* const memory_pointer3 = buffer3->data();
 
   // Deliver a buffer.
   pool_->HoldForConsumers(buffer_id3, 2);
 
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   buffer3.reset();  // Old producer releases buffer. Should be a noop.
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
-  ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_hi, GetParam())) << "Pool should be empty";
 
   buffer2.reset();  // Active producer releases buffer. Should free a buffer.
 
-  buffer1 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer1.get());
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  buffer1 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer1.get());
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   // First consumer finishes.
   pool_->RelinquishConsumerHold(buffer_id3, 1);
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   // Second consumer finishes. This should free that buffer.
   pool_->RelinquishConsumerHold(buffer_id3, 1);
-  buffer3 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer3.get());
+  buffer3 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer3.get());
   ASSERT_EQ(buffer_id3, buffer3->id()) << "Buffer ID should be reused.";
   ASSERT_EQ(memory_pointer3, buffer3->data());
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   // Now deliver & consume buffer1, but don't release the buffer.
   int buffer_id1 = buffer1->id();
@@ -153,35 +259,33 @@
   // be re-allocated to the producer, because |buffer1| still references it. But
   // when |buffer1| goes away, we should be able to re-reserve the buffer (and
   // the ID ought to be the same).
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
   buffer1.reset();  // Should free the buffer.
-  buffer2 = ReserveI420Buffer(size_lo);
-  ASSERT_TRUE(NULL != buffer2.get());
+  buffer2 = ReserveBuffer(size_lo, GetParam());
+  ASSERT_NE(nullptr, buffer2.get());
   ASSERT_EQ(buffer_id1, buffer2->id());
   buffer_id2 = buffer_id1;
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   // Now try reallocation with different resolutions. We expect reallocation
   // to occur only when the old buffer is too small.
   buffer2.reset();
   ExpectDroppedId(buffer_id2);
-  buffer2 = ReserveI420Buffer(size_hi);
-  ASSERT_TRUE(NULL != buffer2.get());
-  ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_hi),
-            buffer2->size());
+  buffer2 = ReserveBuffer(size_hi, GetParam());
+  ASSERT_NE(nullptr, buffer2.get());
+  ASSERT_LE(format_hi.ImageAllocationSize(), buffer2->size());
   ASSERT_EQ(3, buffer2->id());
   void* const memory_pointer_hi = buffer2->data();
   buffer2.reset();  // Frees it.
   ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
-  buffer2 = ReserveI420Buffer(size_lo);
+  buffer2 = ReserveBuffer(size_lo, GetParam());
   void* const memory_pointer_lo = buffer2->data();
   ASSERT_EQ(memory_pointer_hi, memory_pointer_lo)
       << "Decrease in resolution should not reallocate buffer";
-  ASSERT_TRUE(NULL != buffer2.get());
+  ASSERT_NE(nullptr, buffer2.get());
   ASSERT_EQ(3, buffer2->id());
-  ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
-            buffer2->size());
-  ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
+  ASSERT_LE(format_lo.ImageAllocationSize(), buffer2->size());
+  ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
 
   // Tear down the pool_, writing into the buffers. The buffer should preserve
   // the lifetime of the underlying memory.
@@ -189,13 +293,19 @@
   pool_ = NULL;
 
   // Touch the memory.
-  memset(buffer2->data(), 0x22, buffer2->size());
-  memset(buffer4->data(), 0x55, buffer4->size());
-
+  if (buffer2->data() != nullptr)
+    memset(buffer2->data(), 0x22, buffer2->size());
+  if (buffer4->data() != nullptr)
+    memset(buffer4->data(), 0x55, buffer4->size());
   buffer2.reset();
 
-  memset(buffer4->data(), 0x77, buffer4->size());
+  if (buffer4->data() != nullptr)
+    memset(buffer4->data(), 0x77, buffer4->size());
   buffer4.reset();
 }
 
+INSTANTIATE_TEST_CASE_P(,
+                        VideoCaptureBufferPoolTest,
+                        testing::ValuesIn(kCaptureFormats));
+
 } // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index a2c4b193..56b281be 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -26,10 +26,6 @@
 #include "content/browser/compositor/image_transport_factory.h"
 #endif
 
-#if defined(ENABLE_WEBRTC) && (defined(OS_LINUX) || defined(OS_MACOSX))
-#include "content/browser/renderer_host/media/video_capture_texture_wrapper.h"
-#endif
-
 using media::VideoCaptureFormat;
 using media::VideoFrame;
 
@@ -141,21 +137,10 @@
 
 scoped_ptr<media::VideoCaptureDevice::Client>
 VideoCaptureController::NewDeviceClient(
-    const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner,
-    const media::VideoCaptureFormat& format) {
+    const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-#if defined(ENABLE_WEBRTC) && (defined(OS_LINUX) || defined(OS_MACOSX))
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableWebRtcCaptureToTexture)) {
-    return make_scoped_ptr(new VideoCaptureTextureWrapper(
-        this->GetWeakPtrForIOThread(), buffer_pool_, capture_task_runner,
-        format));
-    DVLOG(1) << "TextureWrapper, format " << format.ToString();
-  }
-#endif
-  return make_scoped_ptr(
-      new VideoCaptureDeviceClient(this->GetWeakPtrForIOThread(),
-                                   buffer_pool_));
+  return make_scoped_ptr(new VideoCaptureDeviceClient(
+      this->GetWeakPtrForIOThread(), buffer_pool_, capture_task_runner));
 }
 
 void VideoCaptureController::AddClient(
@@ -287,11 +272,12 @@
 }
 
 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread(
-    const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
+    scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
     const scoped_refptr<VideoFrame>& frame,
     const base::TimeTicks& timestamp) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId);
+  const int buffer_id = buffer->id();
+  DCHECK_NE(buffer_id, VideoCaptureBufferPool::kInvalidId);
 
   int count = 0;
   if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
@@ -316,24 +302,24 @@
         DCHECK(frame->coded_size() == frame->visible_rect().size())
             << "Textures are always supposed to be tightly packed.";
         client->event_handler->OnMailboxBufferReady(client->controller_id,
-                                                    buffer->id(),
+                                                    buffer_id,
                                                     *frame->mailbox_holder(),
                                                     frame->coded_size(),
                                                     timestamp,
                                                     copy_of_metadata.Pass());
       } else if (frame->format() == media::VideoFrame::I420) {
-        bool is_new_buffer = client->known_buffers.insert(buffer->id()).second;
+        bool is_new_buffer = client->known_buffers.insert(buffer_id).second;
         if (is_new_buffer) {
           // On the first use of a buffer on a client, share the memory handle.
           size_t memory_size = 0;
           base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess(
-              buffer->id(), client->render_process_handle, &memory_size);
+              buffer_id, client->render_process_handle, &memory_size);
           client->event_handler->OnBufferCreated(
-              client->controller_id, remote_handle, memory_size, buffer->id());
+              client->controller_id, remote_handle, memory_size, buffer_id);
         }
 
         client->event_handler->OnBufferReady(
-            client->controller_id, buffer->id(), frame->coded_size(),
+            client->controller_id, buffer_id, frame->coded_size(),
             frame->visible_rect(), timestamp, copy_of_metadata.Pass());
       } else {
         // VideoFrame format not supported.
@@ -342,9 +328,9 @@
       }
 
       bool inserted =
-          client->active_buffers.insert(std::make_pair(buffer->id(), frame))
+          client->active_buffers.insert(std::make_pair(buffer_id, frame))
               .second;
-      DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id();
+      DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer_id;
       count++;
     }
   }
@@ -365,7 +351,7 @@
     has_received_frames_ = true;
   }
 
-  buffer_pool_->HoldForConsumers(buffer->id(), count);
+  buffer_pool_->HoldForConsumers(buffer_id, count);
 }
 
 void VideoCaptureController::DoErrorOnIOThread() {
diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h
index 2954688b..0dd8684 100644
--- a/content/browser/renderer_host/media/video_capture_controller.h
+++ b/content/browser/renderer_host/media/video_capture_controller.h
@@ -72,8 +72,7 @@
   // instance. Some device clients need to allocate resources for the given
   // capture |format| and/or work on Capture Thread (|capture_task_runner|).
   scoped_ptr<media::VideoCaptureDevice::Client> NewDeviceClient(
-      const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner,
-      const media::VideoCaptureFormat& format);
+      const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner);
 
   // Start video capturing and try to use the resolution specified in |params|.
   // Buffers will be shared to the client as necessary. The client will continue
@@ -121,7 +120,7 @@
 
   // Worker functions on IO thread. Called by the VideoCaptureDeviceClient.
   void DoIncomingCapturedVideoFrameOnIOThread(
-      const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
+      scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
       const scoped_refptr<media::VideoFrame>& frame,
       const base::TimeTicks& timestamp);
   void DoErrorOnIOThread();
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index 2e6299a..ad9ecd4 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "content/browser/renderer_host/media/media_stream_provider.h"
 #include "content/browser/renderer_host/media/video_capture_controller.h"
 #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
@@ -122,8 +123,7 @@
   void SetUp() override {
     controller_.reset(new VideoCaptureController(kPoolSize));
     device_ = controller_->NewDeviceClient(
-        base::MessageLoopProxy::current(),
-        controller_->GetVideoCaptureFormat());
+        base::ThreadTaskRunnerHandle::Get());
     client_a_.reset(new MockVideoCaptureControllerEventHandler(
         controller_.get()));
     client_b_.reset(new MockVideoCaptureControllerEventHandler(
@@ -132,15 +132,14 @@
 
   void TearDown() override { base::RunLoop().RunUntilIdle(); }
 
-  scoped_refptr<media::VideoFrame> WrapI420Buffer(
-      const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
-      gfx::Size dimensions) {
+  scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions,
+                                                  uint8* data) {
     return media::VideoFrame::WrapExternalPackedMemory(
         media::VideoFrame::I420,
         dimensions,
         gfx::Rect(dimensions),
         dimensions,
-        reinterpret_cast<uint8*>(buffer->data()),
+        data,
         media::VideoFrame::AllocationSize(media::VideoFrame::I420, dimensions),
         base::SharedMemory::NULLHandle(),
         0,
@@ -325,9 +324,9 @@
   // Now, simulate an incoming captured buffer from the capture device. As a
   // side effect this will cause the first buffer to be shared with clients.
   uint8 buffer_no = 1;
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer;
-  buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                        capture_resolution);
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
+      device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
+                                   capture_resolution));
   ASSERT_TRUE(buffer.get());
   memset(buffer->data(), buffer_no++, buffer->size());
   {
@@ -345,11 +344,10 @@
     EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1);
     EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1);
   }
-  device_->OnIncomingCapturedVideoFrame(
-      buffer,
-      WrapI420Buffer(buffer, capture_resolution),
-      base::TimeTicks());
-  buffer = NULL;
+  scoped_refptr<media::VideoFrame> video_frame =
+      WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
+  device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+                                        base::TimeTicks());
 
   base::RunLoop().RunUntilIdle();
   Mock::VerifyAndClearExpectations(client_a_.get());
@@ -358,15 +356,15 @@
   // Second buffer which ought to use the same shared memory buffer. In this
   // case pretend that the Buffer pointer is held by the device for a long
   // delay. This shouldn't affect anything.
-  buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                        capture_resolution);
-  ASSERT_TRUE(buffer.get());
-  memset(buffer->data(), buffer_no++, buffer->size());
-  device_->OnIncomingCapturedVideoFrame(
-      buffer,
-      WrapI420Buffer(buffer, capture_resolution),
-      base::TimeTicks());
-  buffer = NULL;
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 =
+      device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
+                                   capture_resolution);
+  ASSERT_TRUE(buffer2.get());
+  memset(buffer2->data(), buffer_no++, buffer2->size());
+  video_frame =
+      WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer2->data()));
+  device_->OnIncomingCapturedVideoFrame(buffer2.Pass(), video_frame,
+                                        base::TimeTicks());
 
   // The buffer should be delivered to the clients in any order.
   EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1);
@@ -386,15 +384,15 @@
 
   // Third, fourth, and fifth buffers. Pretend they all arrive at the same time.
   for (int i = 0; i < kPoolSize; i++) {
-    buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                          capture_resolution);
+    scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
+        device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
+                                     capture_resolution);
     ASSERT_TRUE(buffer.get());
     memset(buffer->data(), buffer_no++, buffer->size());
-    device_->OnIncomingCapturedVideoFrame(
-        buffer,
-        WrapI420Buffer(buffer, capture_resolution),
-        base::TimeTicks());
-    buffer = NULL;
+    video_frame =
+        WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
+    device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+                                          base::TimeTicks());
   }
   // ReserveOutputBuffer ought to fail now, because the pool is depleted.
   ASSERT_FALSE(device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
@@ -423,30 +421,31 @@
   EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1);
   controller_->StopSession(300);
   // Queue up another buffer.
-  buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                        capture_resolution);
-  ASSERT_TRUE(buffer.get());
-  memset(buffer->data(), buffer_no++, buffer->size());
-  device_->OnIncomingCapturedVideoFrame(
-      buffer,
-      WrapI420Buffer(buffer, capture_resolution),
-      base::TimeTicks());
-  buffer = NULL;
-  buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                        capture_resolution);
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 =
+      device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
+                                   capture_resolution);
+  ASSERT_TRUE(buffer3.get());
+  memset(buffer3->data(), buffer_no++, buffer3->size());
+  video_frame =
+      WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer3->data()));
+  device_->OnIncomingCapturedVideoFrame(buffer3.Pass(), video_frame,
+                                        base::TimeTicks());
+
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 =
+      device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
+                                   capture_resolution);
   {
     // Kill A2 via session close (posts a task to disconnect, but A2 must not
     // be sent either of these two buffers).
     EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1);
     controller_->StopSession(200);
   }
-  ASSERT_TRUE(buffer.get());
-  memset(buffer->data(), buffer_no++, buffer->size());
-  device_->OnIncomingCapturedVideoFrame(
-      buffer,
-      WrapI420Buffer(buffer, capture_resolution),
-      base::TimeTicks());
-  buffer = NULL;
+  ASSERT_TRUE(buffer4.get());
+  memset(buffer4->data(), buffer_no++, buffer4->size());
+  video_frame =
+      WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer4->data()));
+  device_->OnIncomingCapturedVideoFrame(buffer4.Pass(), video_frame,
+                                        base::TimeTicks());
   // B2 is the only client left, and is the only one that should
   // get the buffer.
   EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(2);
@@ -469,32 +468,32 @@
   }
 
   for (int i = 0; i < shm_buffers; ++i) {
-    buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                          capture_resolution);
+    scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
+        device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
+                                     capture_resolution);
     ASSERT_TRUE(buffer.get());
-    device_->OnIncomingCapturedVideoFrame(
-        buffer,
-        WrapI420Buffer(buffer, capture_resolution),
-        base::TimeTicks());
-    buffer = NULL;
+    video_frame =
+        WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
+    device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+                                          base::TimeTicks());
   }
   std::vector<uint32> mailbox_syncpoints(mailbox_buffers);
   std::vector<uint32> release_syncpoints(mailbox_buffers);
   for (int i = 0; i < mailbox_buffers; ++i) {
-    buffer = device_->ReserveOutputBuffer(media::PIXEL_FORMAT_TEXTURE,
-                                          capture_resolution);
+    scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
+        device_->ReserveOutputBuffer(media::PIXEL_FORMAT_TEXTURE,
+                                     capture_resolution);
     ASSERT_TRUE(buffer.get());
 #if !defined(OS_ANDROID)
     mailbox_syncpoints[i] = gl_helper->InsertSyncPoint();
 #endif
     device_->OnIncomingCapturedVideoFrame(
-        buffer,
+        buffer.Pass(),
         WrapMailboxBuffer(make_scoped_ptr(new gpu::MailboxHolder(
                               gpu::Mailbox(), 0, mailbox_syncpoints[i])),
                           base::Bind(&CacheSyncPoint, &release_syncpoints[i]),
                           capture_resolution),
         base::TimeTicks());
-    buffer = NULL;
   }
   // ReserveOutputBuffers ought to fail now regardless of buffer format, because
   // the pool is depleted.
@@ -549,16 +548,14 @@
   base::RunLoop().RunUntilIdle();
   Mock::VerifyAndClearExpectations(client_b_.get());
 
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer =
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
       device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420,
-                                   capture_resolution);
+                                   capture_resolution));
   ASSERT_TRUE(buffer.get());
-
-  device_->OnIncomingCapturedVideoFrame(
-      buffer,
-      WrapI420Buffer(buffer, capture_resolution),
-      base::TimeTicks());
-  buffer = NULL;
+  scoped_refptr<media::VideoFrame> video_frame =
+      WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
+  device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+                                        base::TimeTicks());
 
   base::RunLoop().RunUntilIdle();
 }
@@ -587,16 +584,15 @@
   Mock::VerifyAndClearExpectations(client_a_.get());
 
   const gfx::Size dims(320, 240);
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer =
-      device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420, dims);
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
+      device_->ReserveOutputBuffer(media::PIXEL_FORMAT_I420, dims));
   ASSERT_TRUE(buffer.get());
 
-  device_->OnError("Test error");
-  device_->OnIncomingCapturedVideoFrame(
-      buffer,
-      WrapI420Buffer(buffer, dims),
-      base::TimeTicks());
-  buffer = NULL;
+  scoped_refptr<media::VideoFrame> video_frame =
+      WrapI420Buffer(dims, static_cast<uint8*>(buffer->data()));
+  device_->OnError("Test Error");
+  device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+                                        base::TimeTicks());
 
   EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
   base::RunLoop().RunUntilIdle();
diff --git a/content/browser/renderer_host/media/video_capture_device_client.cc b/content/browser/renderer_host/media/video_capture_device_client.cc
index 66b7fdb..7310963 100644
--- a/content/browser/renderer_host/media/video_capture_device_client.cc
+++ b/content/browser/renderer_host/media/video_capture_device_client.cc
@@ -7,12 +7,23 @@
 #include "base/bind.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
+#include "content/browser/compositor/image_transport_factory.h"
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
+#include "content/browser/gpu/gpu_data_manager_impl.h"
 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
 #include "content/browser/renderer_host/media/video_capture_controller.h"
+#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/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
 #include "content/public/browser/browser_thread.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/video_capture_types.h"
 #include "media/base/video_frame.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
 #include "third_party/libyuv/include/libyuv.h"
 
 using media::VideoCaptureFormat;
@@ -20,39 +31,173 @@
 
 namespace content {
 
+namespace {
+
+#if !defined(OS_ANDROID)
+// Modelled after GpuProcessTransportFactory::CreateContextCommon().
+scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> CreateContextCommon(
+    scoped_refptr<content::GpuChannelHost> gpu_channel_host,
+    int surface_id) {
+  if (!content::GpuDataManagerImpl::GetInstance()->
+        CanUseGpuBrowserCompositor()) {
+    DLOG(ERROR) << "No accelerated graphics found. Check chrome://gpu";
+    return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
+  }
+  blink::WebGraphicsContext3D::Attributes attrs;
+  attrs.shareResources = true;
+  attrs.depth = false;
+  attrs.stencil = false;
+  attrs.antialias = false;
+  attrs.noAutomaticFlushes = true;
+
+  if (!gpu_channel_host.get()) {
+    DLOG(ERROR) << "Failed to establish GPU channel.";
+    return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
+  }
+  GURL url("chrome://gpu/GpuProcessTransportFactory::CreateCaptureContext");
+  return make_scoped_ptr(
+      new WebGraphicsContext3DCommandBufferImpl(
+          surface_id,
+          url,
+          gpu_channel_host.get(),
+          attrs,
+          true  /* lose_context_when_out_of_memory */,
+          content::WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
+          NULL));
+}
+
+// Modelled after
+// GpuProcessTransportFactory::CreateOffscreenCommandBufferContext().
+scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>
+CreateOffscreenCommandBufferContext() {
+  content::CauseForGpuLaunch cause = content::CAUSE_FOR_GPU_LAUNCH_CANVAS_2D;
+  // Android does not support synchronous opening of GPU channels. Should use
+  // EstablishGpuChannel() instead.
+  if (!content::BrowserGpuChannelHostFactory::instance())
+    return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
+  scoped_refptr<content::GpuChannelHost> gpu_channel_host(
+      content::BrowserGpuChannelHostFactory::instance()->
+          EstablishGpuChannelSync(cause));
+  DCHECK(gpu_channel_host);
+  return CreateContextCommon(gpu_channel_host, 0);
+}
+#endif
+
+typedef base::Callback<void(scoped_refptr<ContextProviderCommandBuffer>)>
+    ProcessContextCallback;
+
+void CreateContextOnUIThread(ProcessContextCallback bottom_half) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+#if !defined(OS_ANDROID)
+  bottom_half.Run(ContextProviderCommandBuffer::Create(
+      CreateOffscreenCommandBufferContext(), "Offscreen-CaptureThread"));
+  return;
+#endif
+}
+
+void ResetLostContextCallback(
+    const scoped_refptr<ContextProviderCommandBuffer>& capture_thread_context) {
+  capture_thread_context->SetLostContextCallback(
+      cc::ContextProvider::LostContextCallback());
+}
+
+}  // anonymous namespace
+
 // Class combining a Client::Buffer interface implementation and a pool buffer
 // implementation to guarantee proper cleanup on destruction on our side.
 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
  public:
   AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool,
-                    int buffer_id,
-                    void* data,
-                    size_t size)
-      : pool_(pool),
-        id_(buffer_id),
-        data_(data),
-        size_(size) {
+                    int buffer_id)
+      : id_(buffer_id),
+        pool_(pool),
+        buffer_handle_(pool_->GetBufferHandle(buffer_id).Pass()) {
     DCHECK(pool_.get());
   }
   int id() const override { return id_; }
-  void* data() const override { return data_; }
-  size_t size() const override { return size_; }
+  size_t size() const override { return buffer_handle_->size(); }
+  void* data() override { return buffer_handle_->data(); }
+  ClientBuffer AsClientBuffer() override {
+    return buffer_handle_->AsClientBuffer();
+  }
 
  private:
   ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); }
 
-  const scoped_refptr<VideoCaptureBufferPool> pool_;
   const int id_;
-  void* const data_;
-  const size_t size_;
+  const scoped_refptr<VideoCaptureBufferPool> pool_;
+  const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_;
+};
+
+// Internal ref-counted class wrapping an incoming GpuMemoryBuffer into a
+// Texture backed VideoFrame. This VideoFrame creation is balanced by a waiting
+// on the associated |sync_point|. After VideoFrame consumption the inserted
+// ReleaseCallback() will be called, where the Texture is destroyed.
+//
+// This class jumps between threads due to GPU-related thread limitations, i.e.
+// some objects cannot be accessed from IO Thread whereas others need to be
+// constructed on UI Thread. For this reason most of the operations are carried
+// out on Capture Thread (|capture_task_runner_|).
+class VideoCaptureDeviceClient::TextureWrapHelper final
+    : public base::RefCountedThreadSafe<TextureWrapHelper> {
+ public:
+  TextureWrapHelper(
+      const base::WeakPtr<VideoCaptureController>& controller,
+      const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner);
+
+  // Wraps the GpuMemoryBuffer-backed |buffer| into a Texture, and sends it to
+  // |controller_| wrapped in a VideoFrame.
+  void OnIncomingCapturedGpuMemoryBuffer(
+      scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
+      const media::VideoCaptureFormat& frame_format,
+      const base::TimeTicks& timestamp);
+
+ private:
+  friend class base::RefCountedThreadSafe<TextureWrapHelper>;
+  ~TextureWrapHelper();
+
+  // Creates some necessary members in |capture_task_runner_|.
+  void Init();
+  // Runs the bottom half of the GlHelper creation.
+  void CreateGlHelper(
+      scoped_refptr<ContextProviderCommandBuffer> capture_thread_context);
+
+  // Recycles |memory_buffer|, deletes Image and Texture on VideoFrame release.
+  void ReleaseCallback(GLuint image_id,
+                       GLuint texture_id,
+                       uint32 sync_point);
+
+  // The Command Buffer lost the GL context, f.i. GPU process crashed. Signal
+  // error to our owner so the capture can be torn down.
+  void LostContextCallback();
+
+  // Prints the error |message| and notifies |controller_| of an error.
+  void OnError(const std::string& message);
+
+  // |controller_| should only be used on IO thread.
+  const base::WeakPtr<VideoCaptureController> controller_;
+  const scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
+
+  // Command buffer reference, needs to be destroyed when unused. It is created
+  // on UI Thread and bound to Capture Thread. In particular, it cannot be used
+  // from IO Thread.
+  scoped_refptr<ContextProviderCommandBuffer> capture_thread_context_;
+  // Created and used from Capture Thread. Cannot be used from IO Thread.
+  scoped_ptr<GLHelper> gl_helper_;
+
+  DISALLOW_COPY_AND_ASSIGN(TextureWrapHelper);
 };
 
 VideoCaptureDeviceClient::VideoCaptureDeviceClient(
     const base::WeakPtr<VideoCaptureController>& controller,
-    const scoped_refptr<VideoCaptureBufferPool>& buffer_pool)
+    const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
+    const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner)
     : controller_(controller),
       buffer_pool_(buffer_pool),
-      last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {}
+      capture_task_runner_(capture_task_runner),
+      last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
 
 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {}
 
@@ -105,8 +250,8 @@
     return;
   }
 
-  scoped_refptr<Buffer> buffer =
-      ReserveOutputBuffer(media::PIXEL_FORMAT_I420, dimensions);
+  scoped_ptr<Buffer> buffer(
+      ReserveOutputBuffer(media::PIXEL_FORMAT_I420, dimensions));
   if (!buffer.get())
     return;
 
@@ -201,31 +346,12 @@
                          frame_format.pixel_format);
     return;
   }
-  scoped_refptr<VideoFrame> frame =
-      VideoFrame::WrapExternalPackedMemory(
-          VideoFrame::I420,
-          dimensions,
-          gfx::Rect(dimensions),
-          dimensions,
-          yplane,
-          VideoFrame::AllocationSize(VideoFrame::I420, dimensions),
-          base::SharedMemory::NULLHandle(),
-          0,
-          base::TimeDelta(),
-          base::Closure());
-  DCHECK(frame.get());
-  frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
-                               frame_format.frame_rate);
 
-  BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(
-          &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
-          controller_,
-          buffer,
-          frame,
-          timestamp));
+  OnIncomingCapturedBuffer(buffer.Pass(),
+                           media::VideoCaptureFormat(dimensions,
+                                                     frame_format.frame_rate,
+                                                     media::PIXEL_FORMAT_I420),
+                           timestamp);
 }
 
 void
@@ -243,8 +369,8 @@
   DCHECK_EQ(frame_format.pixel_format, media::PIXEL_FORMAT_I420);
   DCHECK_EQ(clockwise_rotation, 0) << "Rotation not supported";
 
-  scoped_refptr<Buffer> buffer =
-      ReserveOutputBuffer(frame_format.pixel_format, frame_format.frame_size);
+  scoped_ptr<Buffer> buffer(
+      ReserveOutputBuffer(frame_format.pixel_format, frame_format.frame_size));
   if (!buffer.get())
     return;
 
@@ -280,46 +406,31 @@
     return;
   }
 
-  scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalYuvData(
-      VideoFrame::I420, frame_format.frame_size,
-      gfx::Rect(frame_format.frame_size), frame_format.frame_size, y_stride,
-      u_stride, v_stride, dst_y, dst_u, dst_v, base::TimeDelta(),
-      base::Closure());
-  DCHECK(video_frame.get());
-  video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
-                                     frame_format.frame_rate);
-
-  BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(
-          &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
-          controller_,
-          buffer,
-          video_frame,
-          timestamp));
+  OnIncomingCapturedBuffer(buffer.Pass(), frame_format, timestamp);
 };
 
-scoped_refptr<media::VideoCaptureDevice::Client::Buffer>
+scoped_ptr<media::VideoCaptureDevice::Client::Buffer>
 VideoCaptureDeviceClient::ReserveOutputBuffer(media::VideoPixelFormat format,
                                               const gfx::Size& dimensions) {
-  DCHECK(format == media::PIXEL_FORMAT_TEXTURE ||
-         format == media::PIXEL_FORMAT_I420 ||
-         format == media::PIXEL_FORMAT_ARGB);
+  DCHECK(format == media::PIXEL_FORMAT_I420 ||
+         format == media::PIXEL_FORMAT_TEXTURE ||
+         format == media::PIXEL_FORMAT_GPUMEMORYBUFFER);
   DCHECK_GT(dimensions.width(), 0);
   DCHECK_GT(dimensions.height(), 0);
 
+  if (format == media::PIXEL_FORMAT_GPUMEMORYBUFFER && !texture_wrap_helper_) {
+    texture_wrap_helper_ =
+        new TextureWrapHelper(controller_, capture_task_runner_);
+  }
+
   int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId;
   const int buffer_id =
       buffer_pool_->ReserveForProducer(format, dimensions, &buffer_id_to_drop);
   if (buffer_id == VideoCaptureBufferPool::kInvalidId)
     return NULL;
-  void* data;
-  size_t size;
-  buffer_pool_->GetBufferInfo(buffer_id, &data, &size);
 
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
-      new AutoReleaseBuffer(buffer_pool_, buffer_id, data, size));
+  scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
+      new AutoReleaseBuffer(buffer_pool_, buffer_id));
 
   if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) {
     BrowserThread::PostTask(BrowserThread::IO,
@@ -328,12 +439,45 @@
                    controller_, buffer_id_to_drop));
   }
 
-  return output_buffer;
+  return output_buffer.Pass();
 }
 
-void
-VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
-    const scoped_refptr<Buffer>& buffer,
+void VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
+    scoped_ptr<Buffer> buffer,
+    const media::VideoCaptureFormat& frame_format,
+    const base::TimeTicks& timestamp) {
+  if (frame_format.pixel_format == media::PIXEL_FORMAT_GPUMEMORYBUFFER) {
+    capture_task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&TextureWrapHelper::OnIncomingCapturedGpuMemoryBuffer,
+                   texture_wrap_helper_,
+                   base::Passed(&buffer),
+                   frame_format,
+                   timestamp));
+  } else {
+    DCHECK_EQ(frame_format.pixel_format, media::PIXEL_FORMAT_I420);
+    scoped_refptr<VideoFrame> video_frame =
+        VideoFrame::WrapExternalPackedMemory(
+            VideoFrame::I420,
+            frame_format.frame_size,
+            gfx::Rect(frame_format.frame_size),
+            frame_format.frame_size,
+            reinterpret_cast<uint8*>(buffer->data()),
+            VideoFrame::AllocationSize(VideoFrame::I420,
+                                       frame_format.frame_size),
+            base::SharedMemory::NULLHandle(),
+            0  /* shared_memory_offset */,
+            base::TimeDelta(),
+            base::Closure());
+    DCHECK(video_frame.get());
+    video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
+                                       frame_format.frame_rate);
+    OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, timestamp);
+  }
+}
+
+void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
+    scoped_ptr<Buffer> buffer,
     const scoped_refptr<VideoFrame>& frame,
     const base::TimeTicks& timestamp) {
   BrowserThread::PostTask(
@@ -342,7 +486,7 @@
       base::Bind(
           &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
           controller_,
-          buffer,
+          base::Passed(&buffer),
           frame,
           timestamp));
 }
@@ -368,4 +512,162 @@
                                      controller_, message));
 }
 
+VideoCaptureDeviceClient::TextureWrapHelper::TextureWrapHelper(
+    const base::WeakPtr<VideoCaptureController>& controller,
+    const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner)
+  : controller_(controller),
+    capture_task_runner_(capture_task_runner) {
+  capture_task_runner_->PostTask(FROM_HERE,
+      base::Bind(&TextureWrapHelper::Init, this));
+}
+
+void
+VideoCaptureDeviceClient::TextureWrapHelper::OnIncomingCapturedGpuMemoryBuffer(
+        scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
+        const media::VideoCaptureFormat& frame_format,
+        const base::TimeTicks& timestamp) {
+  DCHECK(capture_task_runner_->BelongsToCurrentThread());
+  DCHECK_EQ(frame_format.pixel_format, media::PIXEL_FORMAT_GPUMEMORYBUFFER);
+  if (!gl_helper_) {
+    // |gl_helper_| might not exist due to asynchronous initialization not
+    // finished or due to termination in process after a context loss.
+    DVLOG(1) << " Skipping ingress frame, no GL context.";
+    return;
+  }
+
+  gpu::gles2::GLES2Interface* gl = capture_thread_context_->ContextGL();
+  GLuint image_id = gl->CreateImageCHROMIUM(buffer->AsClientBuffer(),
+                                            frame_format.frame_size.width(),
+                                            frame_format.frame_size.height(),
+                                            GL_BGRA_EXT);
+  DCHECK(image_id);
+
+  GLuint texture_id = gl_helper_->CreateTexture();
+  DCHECK(texture_id);
+  {
+    content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_id);
+    gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
+  }
+
+  scoped_ptr<gpu::MailboxHolder> mailbox_holder(new gpu::MailboxHolder(
+      gl_helper_->ProduceMailboxHolderFromTexture(texture_id)));
+  DCHECK(!mailbox_holder->mailbox.IsZero());
+  DCHECK(mailbox_holder->mailbox.Verify());
+  DCHECK(mailbox_holder->texture_target);
+  DCHECK(mailbox_holder->sync_point);
+
+  scoped_refptr<media::VideoFrame> video_frame =
+      media::VideoFrame::WrapNativeTexture(
+          mailbox_holder.Pass(),
+          media::BindToCurrentLoop(
+              base::Bind(&VideoCaptureDeviceClient::TextureWrapHelper::
+                             ReleaseCallback,
+                         this, image_id, texture_id)),
+          frame_format.frame_size,
+          gfx::Rect(frame_format.frame_size),
+          frame_format.frame_size,
+          base::TimeDelta(),
+          true /* allow_overlay */);
+  video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
+                                     frame_format.frame_rate);
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(
+          &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
+          controller_, base::Passed(&buffer), video_frame, timestamp));
+}
+
+VideoCaptureDeviceClient::TextureWrapHelper::~TextureWrapHelper() {
+  // Might not be running on capture_task_runner_'s thread. Ensure owned objects
+  // are destroyed on the correct threads.
+  if (gl_helper_)
+    capture_task_runner_->DeleteSoon(FROM_HERE, gl_helper_.release());
+
+  if (capture_thread_context_) {
+    capture_task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&ResetLostContextCallback, capture_thread_context_));
+    capture_thread_context_->AddRef();
+    ContextProviderCommandBuffer* raw_capture_thread_context =
+        capture_thread_context_.get();
+    capture_thread_context_ = nullptr;
+    capture_task_runner_->ReleaseSoon(FROM_HERE, raw_capture_thread_context);
+  }
+}
+
+void VideoCaptureDeviceClient::TextureWrapHelper::Init() {
+  DCHECK(capture_task_runner_->BelongsToCurrentThread());
+
+  // In threaded compositing mode, we have to create our own context for Capture
+  // to avoid using the GPU command queue from multiple threads. Context
+  // creation must happen on UI thread; then the context needs to be bound to
+  // the appropriate thread, which is done in CreateGlHelper().
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::Bind(
+          &CreateContextOnUIThread,
+          media::BindToCurrentLoop(base::Bind(
+              &VideoCaptureDeviceClient::TextureWrapHelper::CreateGlHelper,
+              this))));
+}
+
+void VideoCaptureDeviceClient::TextureWrapHelper::CreateGlHelper(
+    scoped_refptr<ContextProviderCommandBuffer> capture_thread_context) {
+  DCHECK(capture_task_runner_->BelongsToCurrentThread());
+
+  if (!capture_thread_context.get()) {
+    DLOG(ERROR) << "No offscreen GL Context!";
+    return;
+  }
+  // This may not happen in IO Thread. The destructor resets the context lost
+  // callback, so base::Unretained is safe; otherwise it'd be a circular ref
+  // counted dependency.
+  capture_thread_context->SetLostContextCallback(media::BindToCurrentLoop(
+      base::Bind(
+          &VideoCaptureDeviceClient::TextureWrapHelper::LostContextCallback,
+          base::Unretained(this))));
+  if (!capture_thread_context->BindToCurrentThread()) {
+    capture_thread_context = NULL;
+    DLOG(ERROR) << "Couldn't bind the Capture Context to the Capture Thread.";
+    return;
+  }
+  DCHECK(capture_thread_context);
+  capture_thread_context_ = capture_thread_context;
+
+  // At this point, |capture_thread_context| is a cc::ContextProvider. Creation
+  // of our GLHelper should happen on Capture Thread.
+  gl_helper_.reset(new GLHelper(capture_thread_context->ContextGL(),
+                                capture_thread_context->ContextSupport()));
+  DCHECK(gl_helper_);
+}
+
+void VideoCaptureDeviceClient::TextureWrapHelper::ReleaseCallback(
+    GLuint image_id,
+    GLuint texture_id,
+    uint32 sync_point) {
+  DCHECK(capture_task_runner_->BelongsToCurrentThread());
+
+  if (gl_helper_) {
+    gl_helper_->DeleteTexture(texture_id);
+    capture_thread_context_->ContextGL()->DestroyImageCHROMIUM(image_id);
+  }
+}
+
+void VideoCaptureDeviceClient::TextureWrapHelper::LostContextCallback() {
+  DCHECK(capture_task_runner_->BelongsToCurrentThread());
+  // Prevent incoming frames from being processed while OnError gets groked.
+  gl_helper_.reset();
+  OnError("GLContext lost");
+}
+
+void VideoCaptureDeviceClient::TextureWrapHelper::OnError(
+    const std::string& message) {
+  DCHECK(capture_task_runner_->BelongsToCurrentThread());
+  DLOG(ERROR) << message;
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_device_client.h b/content/browser/renderer_host/media/video_capture_device_client.h
index 7da95da..afb6954 100644
--- a/content/browser/renderer_host/media/video_capture_device_client.h
+++ b/content/browser/renderer_host/media/video_capture_device_client.h
@@ -24,12 +24,18 @@
 // often be called on some auxiliary thread depending on the platform and the
 // device type; including, for example, the DirectShow thread on Windows, the
 // v4l2_thread on Linux, and the UI thread for tab capture.
+//
+// It has an internal ref counted TextureWrapHelper class used to wrap incoming
+// GpuMemoryBuffers into Texture backed VideoFrames. This class creates and
+// manages the necessary entities to interact with the GPU process, notably an
+// offscreen Context to avoid janking the UI thread.
 class CONTENT_EXPORT VideoCaptureDeviceClient
     : public media::VideoCaptureDevice::Client {
  public:
   VideoCaptureDeviceClient(
       const base::WeakPtr<VideoCaptureController>& controller,
-      const scoped_refptr<VideoCaptureBufferPool>& buffer_pool);
+      const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
+      const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner);
   ~VideoCaptureDeviceClient() override;
 
   // VideoCaptureDevice::Client implementation.
@@ -47,11 +53,13 @@
                                  const media::VideoCaptureFormat& frame_format,
                                  int clockwise_rotation,
                                  const base::TimeTicks& timestamp) override;
-  scoped_refptr<Buffer> ReserveOutputBuffer(
-      media::VideoPixelFormat format,
-      const gfx::Size& dimensions) override;
+  scoped_ptr<Buffer> ReserveOutputBuffer(media::VideoPixelFormat format,
+                                         const gfx::Size& dimensions) override;
+  void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer,
+                                const media::VideoCaptureFormat& frame_format,
+                                const base::TimeTicks& timestamp) override;
   void OnIncomingCapturedVideoFrame(
-      const scoped_refptr<Buffer>& buffer,
+      scoped_ptr<Buffer> buffer,
       const scoped_refptr<media::VideoFrame>& frame,
       const base::TimeTicks& timestamp) override;
   void OnError(const std::string& reason) override;
@@ -64,6 +72,13 @@
   // The pool of shared-memory buffers used for capturing.
   const scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
 
+  // Internal delegate for GpuMemoryBuffer-into-VideoFrame wrapping.
+  class TextureWrapHelper;
+  scoped_refptr<TextureWrapHelper> texture_wrap_helper_;
+  // Reference to Capture Thread task runner, where |texture_wrap_helper_|
+  // lives.
+  const scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
+
   media::VideoPixelFormat last_captured_pixel_format_;
 
   DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceClient);
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index f1c14ebc..a213a564 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -332,7 +332,7 @@
           entry->stream_type,
           request->params(),
           base::Passed(entry->video_capture_controller()->NewDeviceClient(
-              device_task_runner_, request->params().requested_format))),
+              device_task_runner_))),
       base::Bind(&VideoCaptureManager::OnDeviceStarted, this,
                  request->serial_id()));
 }
diff --git a/content/browser/renderer_host/media/video_capture_texture_wrapper.cc b/content/browser/renderer_host/media/video_capture_texture_wrapper.cc
deleted file mode 100644
index 339596e..0000000
--- a/content/browser/renderer_host/media/video_capture_texture_wrapper.cc
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/media/video_capture_texture_wrapper.h"
-
-#include "base/bind.h"
-#include "content/browser/compositor/image_transport_factory.h"
-#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
-#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
-#include "content/browser/gpu/gpu_data_manager_impl.h"
-#include "content/browser/renderer_host/media/video_capture_controller.h"
-#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/webgraphicscontext3d_command_buffer_impl.h"
-#include "content/common/gpu/gpu_process_launch_causes.h"
-#include "content/public/browser/browser_thread.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/video_capture_types.h"
-#include "media/base/video_frame.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/libyuv/include/libyuv.h"
-
-namespace content {
-
-namespace {
-
-// VideoCaptureController has at most 3 capture frames in flight.
-const size_t kNumGpuMemoryBuffers = 3;
-
-uint32 VideoPixelFormatToFourCC(media::VideoPixelFormat pixel_format) {
-  switch (pixel_format) {
-    // I420 is needed by Fake and FileVideoCaptureDevice
-    case media::PIXEL_FORMAT_I420:
-      return libyuv::FOURCC_I420;
-    case media::PIXEL_FORMAT_UYVY:
-      return libyuv::FOURCC_UYVY;
-    case media::PIXEL_FORMAT_YUY2:
-      return libyuv::FOURCC_YUY2;
-    case media::PIXEL_FORMAT_MJPEG:
-      return libyuv::FOURCC_MJPG;
-    default:
-      NOTREACHED() << "Bad captured pixel format: "
-          << media::VideoCaptureFormat::PixelFormatToString(pixel_format);
-  }
-  return libyuv::FOURCC_ANY;
-}
-
-// Modelled after GpuProcessTransportFactory::CreateContextCommon().
-scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> CreateContextCommon(
-    scoped_refptr<content::GpuChannelHost> gpu_channel_host,
-    int surface_id) {
-  if (!content::GpuDataManagerImpl::GetInstance()->
-        CanUseGpuBrowserCompositor()) {
-    DLOG(ERROR) << "No accelerated graphics found. Check chrome://gpu";
-    return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
-  }
-  blink::WebGraphicsContext3D::Attributes attrs;
-  attrs.shareResources = true;
-  attrs.depth = false;
-  attrs.stencil = false;
-  attrs.antialias = false;
-  attrs.noAutomaticFlushes = true;
-
-  if (!gpu_channel_host.get()) {
-    DLOG(ERROR) << "Failed to establish GPU channel.";
-    return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
-  }
-  GURL url("chrome://gpu/GpuProcessTransportFactory::CreateCaptureContext");
-  return make_scoped_ptr(
-      new WebGraphicsContext3DCommandBufferImpl(
-          surface_id,
-          url,
-          gpu_channel_host.get(),
-          attrs,
-          true  /* lose_context_when_out_of_memory */,
-          content::WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
-          NULL));
-}
-
-// Modelled after
-// GpuProcessTransportFactory::CreateOffscreenCommandBufferContext().
-scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>
-CreateOffscreenCommandBufferContext() {
-  content::CauseForGpuLaunch cause = content::CAUSE_FOR_GPU_LAUNCH_CANVAS_2D;
-  scoped_refptr<content::GpuChannelHost> gpu_channel_host(
-      content::BrowserGpuChannelHostFactory::instance()->
-          EstablishGpuChannelSync(cause));
-  DCHECK(gpu_channel_host);
-  return CreateContextCommon(gpu_channel_host, 0);
-}
-
-typedef base::Callback<void(scoped_refptr<ContextProviderCommandBuffer>)>
-    ProcessContextCallback;
-
-void CreateContextOnUIThread(ProcessContextCallback bottom_half) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  bottom_half.Run(ContextProviderCommandBuffer::Create(
-      CreateOffscreenCommandBufferContext(), "Offscreen-CaptureThread"));
-  return;
-}
-
-void ResetLostContextCallback(
-    const scoped_refptr<ContextProviderCommandBuffer>& capture_thread_context) {
-  capture_thread_context->SetLostContextCallback(
-      cc::ContextProvider::LostContextCallback());
-}
-
-}  // anonymous namespace
-
-// Internal ref-counted class to manage a pool of GpuMemoryBuffers. The contents
-// of an incoming captured frame are_copied_ into the first available buffer
-// from the pool and sent to our client ultimately wrapped into a VideoFrame.
-// This VideoFrame creation is balanced by a waiting on the associated
-// |sync_point|. After VideoFrame consumption the inserted ReleaseCallback()
-// will be called, where the GpuMemoryBuffer is recycled.
-//
-// This class jumps between threads due to GPU-related thread limitations, i.e.
-// some objects cannot be accessed from IO Thread, where we are constructed,
-// others need to be constructed on UI Thread. For this reason most of the
-// operations are carried out on Capture Thread (|capture_task_runner_|).
-//
-// TODO(mcasas): ctor |frame_format| is used for early GpuMemoryBuffer pool
-// allocation, but VideoCaptureDevices might provide a different resolution when
-// calling OnIncomingCapturedData(), be that due to driver preferences or to
-// its ResolutionChangePolicy. Make the GpuMemoryBuffer allocated on demand.
-class VideoCaptureTextureWrapper::TextureWrapperDelegate final
-    : public base::RefCountedThreadSafe<TextureWrapperDelegate> {
- public:
-  TextureWrapperDelegate(
-      const base::WeakPtr<VideoCaptureController>& controller,
-      const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner,
-      const media::VideoCaptureFormat& capture_format);
-
-  // Copy-converts the incoming data into a GpuMemoruBuffer backed Texture, and
-  // sends it to |controller_| wrapped in a VideoFrame, with |buffer| as storage
-  // backend.
-  void OnIncomingCapturedData(
-      const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>&
-          texture_buffer,
-      const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>&
-          argb_buffer,
-      const gfx::Size& frame_size,
-      const base::TimeTicks& timestamp);
-
- private:
-  friend class base::RefCountedThreadSafe<TextureWrapperDelegate>;
-  ~TextureWrapperDelegate();
-
-  // Creates some necessary members in |capture_task_runner_|.
-  void Init(const media::VideoCaptureFormat& capture_format);
-  // Runs the bottom half of the GlHelper creation.
-  void CreateGlHelper(
-      scoped_refptr<ContextProviderCommandBuffer> capture_thread_context);
-
-  // Recycles |memory_buffer|, deletes Image and Texture on VideoFrame release.
-  void ReleaseCallback(GLuint image_id,
-                       GLuint texture_id,
-                       linked_ptr<gfx::GpuMemoryBuffer> memory_buffer,
-                       uint32 sync_point);
-
-  // The Command Buffer lost the GL context, f.i. GPU process crashed. Signal
-  // error to our owner so the capture can be torn down.
-  void LostContextCallback();
-
-  // Prints the error |message| and notifies |controller_| of an error.
-  void OnError(const std::string& message);
-
-  const base::WeakPtr<VideoCaptureController> controller_;
-  const scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
-
-  // Command buffer reference, needs to be destroyed when unused. It is created
-  // on UI Thread and bound to Capture Thread. In particular, it cannot be used
-  // from IO Thread.
-  scoped_refptr<ContextProviderCommandBuffer> capture_thread_context_;
-  // Created and used from Capture Thread. Cannot be used from IO Thread.
-  scoped_ptr<GLHelper> gl_helper_;
-
-  // A pool of GpuMemoryBuffers that are used to wrap incoming captured frames;
-  // recycled via ReleaseCallback().
-  std::queue<linked_ptr<gfx::GpuMemoryBuffer>> gpu_memory_buffers_;
-
-  DISALLOW_COPY_AND_ASSIGN(TextureWrapperDelegate);
-};
-
-VideoCaptureTextureWrapper::VideoCaptureTextureWrapper(
-    const base::WeakPtr<VideoCaptureController>& controller,
-    const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
-    const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner,
-    const media::VideoCaptureFormat& capture_format)
-    : VideoCaptureDeviceClient(controller, buffer_pool),
-      wrapper_delegate_(new TextureWrapperDelegate(controller,
-                                                   capture_task_runner,
-                                                   capture_format)),
-      capture_task_runner_(capture_task_runner)  {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-}
-
-VideoCaptureTextureWrapper::~VideoCaptureTextureWrapper() {
-}
-
-void VideoCaptureTextureWrapper::OnIncomingCapturedData(
-    const uint8* data,
-    int length,
-    const media::VideoCaptureFormat& frame_format,
-    int clockwise_rotation,
-    const base::TimeTicks& timestamp) {
-
-  // Reserve a temporary Buffer for conversion to ARGB.
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> argb_buffer =
-      ReserveOutputBuffer(media::PIXEL_FORMAT_ARGB, frame_format.frame_size);
-  DVLOG_IF(1, !argb_buffer) << "Couldn't allocate ARGB Buffer";
-  if (!argb_buffer)
-    return;
-
-  DCHECK(argb_buffer->data());
-  // TODO(mcasas): Take |rotation| into acount.
-  int ret = libyuv::ConvertToARGB(data,
-                                  length,
-                                  reinterpret_cast<uint8*>(argb_buffer->data()),
-                                  frame_format.frame_size.width() * 4,
-                                  0,
-                                  0,
-                                  frame_format.frame_size.width(),
-                                  frame_format.frame_size.height(),
-                                  frame_format.frame_size.width(),
-                                  frame_format.frame_size.height(),
-                                  libyuv::kRotate0,
-                                  VideoPixelFormatToFourCC(
-                                      frame_format.pixel_format));
-  DLOG_IF(ERROR, ret != 0) << "Error converting incoming frame";
-  if (ret != 0)
-    return;
-
-  // Reserve output buffer for the texture on the IPC borderlands.
-  scoped_refptr<media::VideoCaptureDevice::Client::Buffer> texture_buffer =
-      ReserveOutputBuffer(media::PIXEL_FORMAT_TEXTURE, frame_format.frame_size);
-  DVLOG_IF(1, !texture_buffer) << "Couldn't allocate Texture Buffer";
-  if (!texture_buffer)
-    return;
-
-  capture_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &TextureWrapperDelegate::OnIncomingCapturedData,
-          wrapper_delegate_,
-          texture_buffer,
-          argb_buffer,
-          frame_format.frame_size,
-          timestamp));
-}
-
-VideoCaptureTextureWrapper::TextureWrapperDelegate::TextureWrapperDelegate(
-    const base::WeakPtr<VideoCaptureController>& controller,
-    const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner,
-    const media::VideoCaptureFormat& capture_format)
-  : controller_(controller),
-    capture_task_runner_(capture_task_runner) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  capture_task_runner_->PostTask(FROM_HERE,
-      base::Bind(&TextureWrapperDelegate::Init, this, capture_format));
-}
-
-void VideoCaptureTextureWrapper::TextureWrapperDelegate::OnIncomingCapturedData(
-    const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>&
-        texture_buffer,
-    const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& argb_buffer,
-    const gfx::Size& frame_size,
-    const base::TimeTicks& timestamp) {
-  DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
-  DVLOG_IF(1, !gl_helper_) << " Skipping ingress frame, no GL context.";
-  if (!gl_helper_)
-    return;
-
-  DVLOG_IF(1, gpu_memory_buffers_.empty()) << " Skipping ingress frame, 0 GMBs";
-  if (gpu_memory_buffers_.empty())
-    return;
-
-  linked_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
-      gpu_memory_buffers_.front();
-  gpu_memory_buffers_.pop();
-  DCHECK(gpu_memory_buffer.get());
-
-  void* data = NULL;
-  bool rv = gpu_memory_buffer->Map(&data);
-  DCHECK(rv);
-  int stride;
-  gpu_memory_buffer->GetStride(&stride);
-
-  uint8* mapped_buffer = static_cast<uint8*>(data);
-  DCHECK(mapped_buffer);
-  libyuv::ARGBCopy(
-      reinterpret_cast<uint8*>(argb_buffer->data()), frame_size.width() * 4,
-      mapped_buffer, stride,
-      frame_size.width(), frame_size.height());
-  gpu_memory_buffer->Unmap();
-
-  gpu::gles2::GLES2Interface* gl = capture_thread_context_->ContextGL();
-  GLuint image_id = gl->CreateImageCHROMIUM(gpu_memory_buffer->AsClientBuffer(),
-                                            frame_size.width(),
-                                            frame_size.height(), GL_BGRA_EXT);
-  DCHECK(image_id);
-
-  GLuint texture_id = gl_helper_->CreateTexture();
-  DCHECK(texture_id);
-  {
-    content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_id);
-    gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
-  }
-
-  scoped_ptr<gpu::MailboxHolder> mailbox_holder(new gpu::MailboxHolder(
-      gl_helper_->ProduceMailboxHolderFromTexture(texture_id)));
-  DCHECK(!mailbox_holder->mailbox.IsZero());
-  DCHECK(mailbox_holder->mailbox.Verify());
-  DCHECK(mailbox_holder->texture_target);
-  DCHECK(mailbox_holder->sync_point);
-
-  scoped_refptr<media::VideoFrame> video_frame =
-      media::VideoFrame::WrapNativeTexture(
-          mailbox_holder.Pass(),
-          media::BindToCurrentLoop(
-              base::Bind(&VideoCaptureTextureWrapper::TextureWrapperDelegate::
-                             ReleaseCallback,
-                         this, image_id, texture_id, gpu_memory_buffer)),
-          frame_size,
-          gfx::Rect(frame_size),
-          frame_size,
-          base::TimeDelta(),
-          true /* allow_overlay */);
-
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(
-          &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
-          controller_, texture_buffer, video_frame, timestamp));
-}
-
-VideoCaptureTextureWrapper::TextureWrapperDelegate::~TextureWrapperDelegate() {
-  // Might not be running on capture_task_runner_'s thread. Ensure owned objects
-  // are destroyed on the correct threads.
-  while (!gpu_memory_buffers_.empty()) {
-    capture_task_runner_->DeleteSoon(FROM_HERE,
-                                     gpu_memory_buffers_.front().release());
-    gpu_memory_buffers_.pop();
-  }
-  if (gl_helper_)
-    capture_task_runner_->DeleteSoon(FROM_HERE, gl_helper_.release());
-
-  if (capture_thread_context_) {
-    capture_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&ResetLostContextCallback, capture_thread_context_));
-    capture_thread_context_->AddRef();
-    ContextProviderCommandBuffer* raw_capture_thread_context =
-        capture_thread_context_.get();
-    capture_thread_context_ = nullptr;
-    capture_task_runner_->ReleaseSoon(FROM_HERE, raw_capture_thread_context);
-  }
-}
-
-void VideoCaptureTextureWrapper::TextureWrapperDelegate::Init(
-    const media::VideoCaptureFormat& capture_format) {
-  DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
-  // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread.
-  // TODO(mcasas): At this point |frame_format| represents the format we want to
-  // get from the VCDevice, but this might send another format.
-  for (size_t i = 0; i < kNumGpuMemoryBuffers; ++i) {
-    linked_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer(
-        BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer(
-            capture_format.frame_size,
-            gfx::GpuMemoryBuffer::BGRA_8888,
-            gfx::GpuMemoryBuffer::MAP).release());
-    if (!gpu_memory_buffer.get()) {
-      OnError("Could not allocate GpuMemoryBuffer");
-      while(!gpu_memory_buffers_.empty())
-        gpu_memory_buffers_.pop();
-      return;
-    }
-    gpu_memory_buffers_.push(gpu_memory_buffer);
-  }
-
-  // In threaded compositing mode, we have to create our own context for Capture
-  // to avoid using the GPU command queue from multiple threads. Context
-  // creation must happen on UI thread; then the context needs to be bound to
-  // the appropriate thread, which is done in CreateGlHelper().
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&CreateContextOnUIThread,
-                 media::BindToCurrentLoop(
-                     base::Bind(&VideoCaptureTextureWrapper::
-                                    TextureWrapperDelegate::CreateGlHelper,
-                                this))));
-}
-
-void VideoCaptureTextureWrapper::TextureWrapperDelegate::CreateGlHelper(
-    scoped_refptr<ContextProviderCommandBuffer> capture_thread_context) {
-  DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
-  if (!capture_thread_context.get()) {
-    DLOG(ERROR) << "No offscreen GL Context!";
-    return;
-  }
-  // This may not happen in IO Thread. The destructor resets the context lost
-  // callback, so base::Unretained is safe; otherwise it'd be a circular ref
-  // counted dependency.
-  capture_thread_context->SetLostContextCallback(media::BindToCurrentLoop(
-      base::Bind(
-          &VideoCaptureTextureWrapper::TextureWrapperDelegate::
-              LostContextCallback,
-          base::Unretained(this))));
-  if (!capture_thread_context->BindToCurrentThread()) {
-    capture_thread_context = NULL;
-    DLOG(ERROR) << "Couldn't bind the Capture Context to the Capture Thread.";
-    return;
-  }
-  DCHECK(capture_thread_context);
-  capture_thread_context_ = capture_thread_context;
-
-  // At this point, |capture_thread_context| is a cc::ContextProvider. Creation
-  // of our GLHelper should happen on Capture Thread.
-  gl_helper_.reset(new GLHelper(capture_thread_context->ContextGL(),
-                                capture_thread_context->ContextSupport()));
-  DCHECK(gl_helper_);
-}
-
-void VideoCaptureTextureWrapper::TextureWrapperDelegate::ReleaseCallback(
-    GLuint image_id,
-    GLuint texture_id,
-    linked_ptr<gfx::GpuMemoryBuffer> memory_buffer,
-    uint32 sync_point) {
-  DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
-  // TODO(mcasas): Before recycling |memory_buffer| we have to make sure it has
-  // been consumed and fully used.
-  gpu_memory_buffers_.push(memory_buffer);
-
-  if (gl_helper_) {
-    gl_helper_->DeleteTexture(texture_id);
-    capture_thread_context_->ContextGL()->DestroyImageCHROMIUM(image_id);
-  }
-}
-
-void VideoCaptureTextureWrapper::TextureWrapperDelegate::LostContextCallback() {
-  DCHECK(capture_task_runner_->BelongsToCurrentThread());
-  // Prevent incoming frames from being processed while OnError gets groked.
-  gl_helper_.reset();
-  OnError("GLContext lost");
-}
-
-void VideoCaptureTextureWrapper::TextureWrapperDelegate::OnError(
-    const std::string& message) {
-  DCHECK(capture_task_runner_->BelongsToCurrentThread());
-  DLOG(ERROR) << message;
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_texture_wrapper.h b/content/browser/renderer_host/media/video_capture_texture_wrapper.h
deleted file mode 100644
index db6c1c5..0000000
--- a/content/browser/renderer_host/media/video_capture_texture_wrapper.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_TEXTURE_WRAPPER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_TEXTURE_WRAPPER_H_
-
-#include "base/memory/linked_ptr.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "content/browser/renderer_host/media/video_capture_device_client.h"
-#include "content/common/content_export.h"
-#include "media/video/capture/video_capture_device.h"
-
-namespace content {
-
-// VideoCaptureDeviceClient derived class for copying incoming memory-backed
-// video data into a GpuMemoryBuffer (in turn into a VideoFrame), and sending it
-// to |controller_|. Construction happens on IO Thread, whereas calls to
-// OnIncomingCapturedData() come from wherever capture happens which might be,
-// and often is, an OS thread different from Device Thread.
-//
-// It has an internal ref counted TextureWrapperDelegate class used to do all
-// the work. This class creates and manages the necessary interactions with the
-// GPU process for the texture uploading. This delegate is needed since the
-// frame producer needs to own us, but we need to launch PostTask()s.
-//
-// TODO(mcasas): ctor |frame_format| is used for early GpuMemoryBuffer pool
-// allocation, but VideoCaptureDevices might provide a different resolution when
-// calling OnIncomingCapturedData(). What should we do then...?
-
-class CONTENT_EXPORT VideoCaptureTextureWrapper final
-    : public VideoCaptureDeviceClient {
- public:
-  VideoCaptureTextureWrapper(
-      const base::WeakPtr<VideoCaptureController>& controller,
-      const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
-      const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner,
-      const media::VideoCaptureFormat& capture_format);
-  ~VideoCaptureTextureWrapper() override;
-
-  // Single media::VideoCaptureDevice::Client overriden method.
-  void OnIncomingCapturedData(const uint8* data,
-                              int length,
-                              const media::VideoCaptureFormat& frame_format,
-                              int clockwise_rotation,
-                              const base::TimeTicks& timestamp) override;
-
- private:
-  class TextureWrapperDelegate;
-  // Internal delegate doing most of the work.
-  scoped_refptr<TextureWrapperDelegate> wrapper_delegate_;
-  // Reference to Capture Thread task runner.
-  const scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoCaptureTextureWrapper);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_TEXTURE_WRAPPER_H_
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 1e20d8e..467adf90 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -35,6 +35,7 @@
 #include "base/trace_event/trace_event.h"
 #include "base/tracked_objects.h"
 #include "cc/base/switches.h"
+#include "components/scheduler/common/scheduler_switches.h"
 #include "content/browser/appcache/appcache_dispatcher_host.h"
 #include "content/browser/appcache/chrome_appcache_service.h"
 #include "content/browser/bad_message.h"
@@ -1218,7 +1219,6 @@
     switches::kDisable3DAPIs,
     switches::kDisableAcceleratedJpegDecoding,
     switches::kDisableAcceleratedVideoDecode,
-    switches::kDisableBlinkScheduler,
     switches::kDisableBlinkFeatures,
     switches::kDisableBreakpad,
     switches::kDisablePreferCompositingToLCDText,
@@ -1356,6 +1356,9 @@
     cc::switches::kStrictLayerPropertyChangeChecking,
     cc::switches::kTopControlsHideThreshold,
     cc::switches::kTopControlsShowThreshold,
+
+    scheduler::switches::kDisableBlinkScheduler,
+
 #if defined(ENABLE_PLUGINS)
     switches::kEnablePepperTesting,
 #endif
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 8599a31..021f4214 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -3311,8 +3311,13 @@
   // doesn't call any NSTextInput functions, such as setMarkedText or
   // insertText. So, we need to send an IPC message to a renderer so it can
   // delete the composition node.
+  // TODO(erikchen): NSInputManager is deprecated since OSX 10.6. Switch to
+  // NSTextInputContext. http://www.crbug.com/479010.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   NSInputManager *currentInputManager = [NSInputManager currentInputManager];
   [currentInputManager markedTextAbandoned:self];
+#pragma clang diagnostic pop
 
   hasMarkedText_ = NO;
   // Should not call [self unmarkText] here, because it'll send unnecessary
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 62d3b62c..0044aa4 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -70,7 +70,7 @@
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell->web_contents());
   wc->GetFrameTree()->root()->navigator()->RequestOpenURL(
       wc->GetFrameTree()->root()->current_frame_host(), extension_url, nullptr,
-      Referrer(), CURRENT_TAB, false, true);
+      Referrer(), ui::PAGE_TRANSITION_LINK, CURRENT_TAB, false, true);
 
   // Since the navigation above requires a cross-process swap, there will be a
   // pending RenderViewHost. Ensure it exists and is in a different process
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index d2b0048..3c75a90 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -160,8 +160,7 @@
   void OnVersionStateChanged(int64 version_id,
                              ServiceWorkerVersion::Status) override {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
-    const ServiceWorkerVersion* version =
-        context_->context()->GetLiveVersion(version_id);
+    const ServiceWorkerVersion* version = context_->GetLiveVersion(version_id);
     if (version->status() == ServiceWorkerVersion::ACTIVATED) {
       context_->RemoveObserver(this);
       BrowserThread::PostTask(BrowserThread::UI,
@@ -249,7 +248,7 @@
   *num_resources = -1;
 
   std::vector<ServiceWorkerRegistrationInfo> infos =
-     wrapper->context()->GetAllLiveRegistrationInfo();
+      wrapper->GetAllLiveRegistrationInfo();
   if (infos.empty())
     return;
 
@@ -267,8 +266,7 @@
   else
     return;
 
-  ServiceWorkerVersion* version =
-      wrapper->context()->GetLiveVersion(version_id);
+  ServiceWorkerVersion* version = wrapper->GetLiveVersion(version_id);
   *num_resources = static_cast<int>(version->script_cache_map()->size());
 }
 
@@ -1097,12 +1095,10 @@
   void FindRegistrationOnIO(const GURL& document_url,
                             ServiceWorkerStatusCode* status,
                             const base::Closure& continuation) {
-    wrapper()->context()->storage()->FindRegistrationForDocument(
+    wrapper()->FindRegistrationForDocument(
         document_url,
         base::Bind(&ServiceWorkerBlackBoxBrowserTest::FindRegistrationOnIO2,
-                   this,
-                   status,
-                   continuation));
+                   this, status, continuation));
   }
 
   void FindRegistrationOnIO2(
diff --git a/content/browser/service_worker/service_worker_context_watcher.cc b/content/browser/service_worker/service_worker_context_watcher.cc
index 5d1a1a8..7c69ea22 100644
--- a/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/content/browser/service_worker/service_worker_context_watcher.cc
@@ -54,7 +54,7 @@
 
 void ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  context_->context()->storage()->GetAllRegistrations(base::Bind(
+  context_->GetAllRegistrations(base::Bind(
       &ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread, this));
 }
 
@@ -67,11 +67,9 @@
       registration_info_map;
   for (const auto& registration : stored_registrations)
     StoreRegistrationInfo(registration, &registration_info_map);
-  for (const auto& registration :
-       context_->context()->GetAllLiveRegistrationInfo()) {
+  for (const auto& registration : context_->GetAllLiveRegistrationInfo())
     StoreRegistrationInfo(registration, &registration_info_map);
-  }
-  for (const auto& version : context_->context()->GetAllLiveVersionInfo())
+  for (const auto& version : context_->GetAllLiveVersionInfo())
     StoreVersionInfo(version);
 
   std::vector<ServiceWorkerRegistrationInfo> registrations;
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 0c09251..db72622 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -147,11 +147,6 @@
       base::Bind(&ServiceWorkerContextWrapper::DidDeleteAndStartOver, this));
 }
 
-ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  return context_core_.get();
-}
-
 StoragePartitionImpl* ServiceWorkerContextWrapper::storage_partition() const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return storage_partition_;
@@ -432,6 +427,125 @@
                                this, other_url, callback));
 }
 
+ServiceWorkerRegistration* ServiceWorkerContextWrapper::GetLiveRegistration(
+    int64_t registration_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_)
+    return nullptr;
+  return context_core_->GetLiveRegistration(registration_id);
+}
+
+ServiceWorkerVersion* ServiceWorkerContextWrapper::GetLiveVersion(
+    int64_t version_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_)
+    return nullptr;
+  return context_core_->GetLiveVersion(version_id);
+}
+
+std::vector<ServiceWorkerRegistrationInfo>
+ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_)
+    return std::vector<ServiceWorkerRegistrationInfo>();
+  return context_core_->GetAllLiveRegistrationInfo();
+}
+
+std::vector<ServiceWorkerVersionInfo>
+ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_)
+    return std::vector<ServiceWorkerVersionInfo>();
+  return context_core_->GetAllLiveVersionInfo();
+}
+
+void ServiceWorkerContextWrapper::FindRegistrationForDocument(
+    const GURL& document_url,
+    const FindRegistrationCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    // FindRegistrationForDocument() can run the callback synchronously.
+    callback.Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
+    return;
+  }
+  context_core_->storage()->FindRegistrationForDocument(document_url, callback);
+}
+
+void ServiceWorkerContextWrapper::FindRegistrationForId(
+    int64_t registration_id,
+    const GURL& origin,
+    const FindRegistrationCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    // FindRegistrationForId() can run the callback synchronously.
+    callback.Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
+    return;
+  }
+  context_core_->storage()->FindRegistrationForId(registration_id, origin,
+                                                  callback);
+}
+
+void ServiceWorkerContextWrapper::GetAllRegistrations(
+    const GetRegistrationsInfosCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    RunSoon(base::Bind(callback, std::vector<ServiceWorkerRegistrationInfo>()));
+    return;
+  }
+  context_core_->storage()->GetAllRegistrations(callback);
+}
+
+void ServiceWorkerContextWrapper::GetRegistrationUserData(
+    int64_t registration_id,
+    const std::string& key,
+    const GetUserDataCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    RunSoon(base::Bind(callback, std::string(), SERVICE_WORKER_ERROR_ABORT));
+    return;
+  }
+  context_core_->storage()->GetUserData(registration_id, key, callback);
+}
+
+void ServiceWorkerContextWrapper::StoreRegistrationUserData(
+    int64_t registration_id,
+    const GURL& origin,
+    const std::string& key,
+    const std::string& data,
+    const StatusCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
+    return;
+  }
+  context_core_->storage()->StoreUserData(registration_id, origin, key, data,
+                                          callback);
+}
+
+void ServiceWorkerContextWrapper::ClearRegistrationUserData(
+    int64_t registration_id,
+    const std::string& key,
+    const StatusCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
+    return;
+  }
+  context_core_->storage()->ClearUserData(registration_id, key, callback);
+}
+
+void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations(
+    const std::string& key,
+    const GetUserDataForAllRegistrationsCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    RunSoon(base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
+                       SERVICE_WORKER_ERROR_ABORT));
+    return;
+  }
+  context_core_->storage()->GetUserDataForAllRegistrations(key, callback);
+}
+
 void ServiceWorkerContextWrapper::AddObserver(
     ServiceWorkerContextObserver* observer) {
   observer_list_->AddObserver(observer);
@@ -497,4 +611,9 @@
                          &ServiceWorkerContextObserver::OnStorageWiped);
 }
 
+ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  return context_core_.get();
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index f77b07c..eca4a36 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -40,7 +40,15 @@
     : NON_EXPORTED_BASE(public ServiceWorkerContext),
       public base::RefCountedThreadSafe<ServiceWorkerContextWrapper> {
  public:
-  typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
+  using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
+  using FindRegistrationCallback =
+      ServiceWorkerStorage::FindRegistrationCallback;
+  using GetRegistrationsInfosCallback =
+      ServiceWorkerStorage::GetRegistrationsInfosCallback;
+  using GetUserDataCallback = ServiceWorkerStorage::GetUserDataCallback;
+  using GetUserDataForAllRegistrationsCallback =
+      ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback;
+
   ServiceWorkerContextWrapper(BrowserContext* browser_context);
 
   // Init and Shutdown are for use on the UI thread when the profile,
@@ -55,11 +63,6 @@
   // called on the IO thread.
   void DeleteAndStartOver();
 
-  // The core context is only for use on the IO thread.
-  // Can be null before/during init, during/after shutdown, and after
-  // DeleteAndStartOver fails.
-  ServiceWorkerContextCore* context();
-
   // The StoragePartition should only be used on the UI thread.
   // Can be null before/during init and during/after shutdown.
   StoragePartitionImpl* storage_partition() const;
@@ -88,6 +91,32 @@
       const GURL& other_url,
       const CheckHasServiceWorkerCallback& callback) override;
 
+  ServiceWorkerRegistration* GetLiveRegistration(int64_t registration_id);
+  ServiceWorkerVersion* GetLiveVersion(int64_t version_id);
+  std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo();
+  std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo();
+
+  void FindRegistrationForDocument(const GURL& document_url,
+                                   const FindRegistrationCallback& callback);
+  void FindRegistrationForId(int64_t registration_id,
+                             const GURL& origin,
+                             const FindRegistrationCallback& callback);
+  void GetAllRegistrations(const GetRegistrationsInfosCallback& callback);
+  void GetRegistrationUserData(int64_t registration_id,
+                               const std::string& key,
+                               const GetUserDataCallback& callback);
+  void StoreRegistrationUserData(int64_t registration_id,
+                                 const GURL& origin,
+                                 const std::string& key,
+                                 const std::string& data,
+                                 const StatusCallback& callback);
+  void ClearRegistrationUserData(int64_t registration_id,
+                                 const std::string& key,
+                                 const StatusCallback& callback);
+  void GetUserDataForAllRegistrations(
+      const std::string& key,
+      const GetUserDataForAllRegistrationsCallback& callback);
+
   // DeleteForOrigin with completion callback.  Does not exit early, and returns
   // false if one or more of the deletions fail.
   virtual void DeleteForOrigin(const GURL& origin_url,
@@ -104,7 +133,12 @@
   friend class BackgroundSyncManagerTest;
   friend class base::RefCountedThreadSafe<ServiceWorkerContextWrapper>;
   friend class EmbeddedWorkerTestHelper;
+  friend class EmbeddedWorkerBrowserTest;
+  friend class ServiceWorkerDispatcherHost;
+  friend class ServiceWorkerInternalsUI;
   friend class ServiceWorkerProcessManager;
+  friend class ServiceWorkerRequestHandler;
+  friend class ServiceWorkerVersionBrowserTest;
   friend class MockServiceWorkerContextWrapper;
 
   ~ServiceWorkerContextWrapper() override;
@@ -133,6 +167,11 @@
       ServiceWorkerStatusCode status,
       const scoped_refptr<content::ServiceWorkerRegistration>& registration);
 
+  // The core context is only for use on the IO thread.
+  // Can be null before/during init, during/after shutdown, and after
+  // DeleteAndStartOver fails.
+  ServiceWorkerContextCore* context();
+
   const scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> >
       observer_list_;
   const scoped_ptr<ServiceWorkerProcessManager> process_manager_;
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 14e0ceec..771cbb1 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -86,7 +86,7 @@
       request_.get());
   DCHECK(!fetch_callback_.is_null());
   FetchCallback fetch_callback = fetch_callback_;
-  fetch_callback.Run(status, fetch_result, response);
+  fetch_callback.Run(status, fetch_result, response, version_);
 }
 
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h
index f20fb94..f0165b6 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -20,7 +20,9 @@
  public:
   typedef base::Callback<void(ServiceWorkerStatusCode,
                               ServiceWorkerFetchEventResult,
-                              const ServiceWorkerResponse&)> FetchCallback;
+                              const ServiceWorkerResponse&,
+                              scoped_refptr<ServiceWorkerVersion>)>
+      FetchCallback;
 
   ServiceWorkerFetchDispatcher(scoped_ptr<ServiceWorkerFetchRequest> request,
                                ServiceWorkerVersion* version,
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc
index 0a0df729..2176eb75 100644
--- a/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -78,13 +78,8 @@
     return;
   }
 
-  if (!context->context()) {
-    callback.Run(SERVICE_WORKER_ERROR_ABORT);
-    return;
-  }
-
   scoped_refptr<ServiceWorkerVersion> version =
-      context->context()->GetLiveVersion(version_id);
+      context->GetLiveVersion(version_id);
   if (!version.get()) {
     callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
     return;
@@ -107,13 +102,8 @@
     return;
   }
 
-  if (!context->context()) {
-    callback.Run(SERVICE_WORKER_ERROR_ABORT);
-    return;
-  }
-
   scoped_refptr<ServiceWorkerVersion> version =
-      context->context()->GetLiveVersion(version_id);
+      context->GetLiveVersion(version_id);
   if (!version.get()) {
     callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
     return;
@@ -122,45 +112,6 @@
   version->DispatchPushEvent(callback, data);
 }
 
-void UnregisterWithScope(
-    scoped_refptr<ServiceWorkerContextWrapper> context,
-    const GURL& scope,
-    const ServiceWorkerInternalsUI::StatusCallback& callback) {
-  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(UnregisterWithScope, context, scope, callback));
-    return;
-  }
-
-  if (!context->context()) {
-    callback.Run(SERVICE_WORKER_ERROR_ABORT);
-    return;
-  }
-  context->context()->UnregisterServiceWorker(scope, callback);
-}
-
-void FindRegistrationForPattern(
-    scoped_refptr<ServiceWorkerContextWrapper> context,
-    const GURL& scope,
-    const ServiceWorkerStorage::FindRegistrationCallback callback) {
-  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(FindRegistrationForPattern, context, scope, callback));
-    return;
-  }
-
-  if (!context->context()) {
-    callback.Run(SERVICE_WORKER_ERROR_ABORT,
-                 scoped_refptr<ServiceWorkerRegistration>());
-    return;
-  }
-  context->context()->storage()->FindRegistrationForPattern(scope, callback);
-}
-
 void UpdateVersionInfo(const ServiceWorkerVersionInfo& version,
                        DictionaryValue* info) {
   switch (version.running_status) {
@@ -256,37 +207,17 @@
     const GetRegistrationsCallback& callback,
     const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (!context->context()) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(callback, std::vector<ServiceWorkerRegistrationInfo>(),
-                   std::vector<ServiceWorkerVersionInfo>(),
-                   std::vector<ServiceWorkerRegistrationInfo>()));
-    return;
-  }
-
   BrowserThread::PostTask(
-      BrowserThread::UI,
-      FROM_HERE,
-      base::Bind(callback,
-                 context->context()->GetAllLiveRegistrationInfo(),
-                 context->context()->GetAllLiveVersionInfo(),
-                 stored_registrations));
+      BrowserThread::UI, FROM_HERE,
+      base::Bind(callback, context->GetAllLiveRegistrationInfo(),
+                 context->GetAllLiveVersionInfo(), stored_registrations));
 }
 
 void GetRegistrationsOnIOThread(
     scoped_refptr<ServiceWorkerContextWrapper> context,
     const GetRegistrationsCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (!context->context()) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(callback, std::vector<ServiceWorkerRegistrationInfo>(),
-                   std::vector<ServiceWorkerVersionInfo>(),
-                   std::vector<ServiceWorkerRegistrationInfo>()));
-    return;
-  }
-  context->context()->storage()->GetAllRegistrations(
+  context->GetAllRegistrations(
       base::Bind(DidGetStoredRegistrationsOnIOThread, context, callback));
 }
 
@@ -669,4 +600,26 @@
   context->StartServiceWorker(GURL(scope_string), callback);
 }
 
+void ServiceWorkerInternalsUI::UnregisterWithScope(
+    scoped_refptr<ServiceWorkerContextWrapper> context,
+    const GURL& scope,
+    const ServiceWorkerInternalsUI::StatusCallback& callback) const {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::Bind(&ServiceWorkerInternalsUI::UnregisterWithScope,
+                   base::Unretained(this), context, scope, callback));
+    return;
+  }
+
+  if (!context->context()) {
+    callback.Run(SERVICE_WORKER_ERROR_ABORT);
+    return;
+  }
+
+  // ServiceWorkerContextWrapper::UnregisterServiceWorker doesn't work here
+  // because that reduces a status code to boolean.
+  context->context()->UnregisterServiceWorker(scope, callback);
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_internals_ui.h b/content/browser/service_worker/service_worker_internals_ui.h
index 40ceb38..82040f0 100644
--- a/content/browser/service_worker/service_worker_internals_ui.h
+++ b/content/browser/service_worker/service_worker_internals_ui.h
@@ -64,6 +64,10 @@
                    StoragePartition** result_partition,
                    StoragePartition* storage_partition) const;
 
+  void UnregisterWithScope(scoped_refptr<ServiceWorkerContextWrapper> context,
+                           const GURL& scope,
+                           const StatusCallback& callback) const;
+
   base::ScopedPtrHashMap<uintptr_t, PartitionObserver> observers_;
   int next_partition_id_;
 };
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc
index 26d4528..d2b5833 100644
--- a/content/browser/service_worker/service_worker_registration.cc
+++ b/content/browser/service_worker/service_worker_registration.cc
@@ -259,10 +259,8 @@
   scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version();
   scoped_refptr<ServiceWorkerVersion> exiting_version = active_version();
 
-  if (activating_version->is_doomed() ||
-      activating_version->status() == ServiceWorkerVersion::REDUNDANT) {
+  if (activating_version->is_redundant())
     return;  // Activation is no longer relevant.
-  }
 
   // "5. If exitingWorker is not null,
   if (exiting_version.get()) {
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
index 7d53c2d..aa07b5b3 100644
--- a/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -1116,7 +1116,6 @@
                  &verify_ids,
                  &was_called,
                  &result));
-  registration_->active_version()->Doom();
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
@@ -1131,6 +1130,7 @@
 
   // Removing the controllee should cause the resources to be deleted.
   registration_->active_version()->RemoveControllee(host.get());
+  registration_->active_version()->Doom();
   base::RunLoop().RunUntilIdle();
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1268,7 +1268,6 @@
                  &verify_ids,
                  &was_called,
                  &result));
-  registration_->active_version()->Doom();
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
@@ -1284,6 +1283,7 @@
   // Removing the controllee should cause the old version's resources to be
   // deleted.
   registration_->active_version()->RemoveControllee(host.get());
+  registration_->active_version()->Doom();
   base::RunLoop().RunUntilIdle();
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc
index 8d848f4..c6bdfd7 100644
--- a/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -477,7 +477,8 @@
 void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
     ServiceWorkerStatusCode status,
     ServiceWorkerFetchEventResult fetch_result,
-    const ServiceWorkerResponse& response) {
+    const ServiceWorkerResponse& response,
+    scoped_refptr<ServiceWorkerVersion> version) {
   fetch_dispatcher_.reset();
 
   // Check if we're not orphaned.
@@ -529,16 +530,16 @@
   // TODO(horo): When we support mixed-content (HTTP) no-cors requests from a
   // ServiceWorker, we have to check the security level of the responses.
   DCHECK(!http_response_info_);
+  DCHECK(version);
   const net::HttpResponseInfo* main_script_http_info =
-      provider_host_->active_version()->GetMainScriptHttpResponseInfo();
+      version->GetMainScriptHttpResponseInfo();
   DCHECK(main_script_http_info);
   http_response_info_.reset(new net::HttpResponseInfo(*main_script_http_info));
 
   // Set up a request for reading the stream.
   if (response.stream_url.is_valid()) {
     DCHECK(response.blob_uuid.empty());
-    DCHECK(provider_host_->active_version());
-    streaming_version_ = provider_host_->active_version();
+    streaming_version_ = version;
     streaming_version_->AddStreamingURLRequestJob(this);
     response_url_ = response.url;
     service_worker_response_type_ = response.response_type;
diff --git a/content/browser/service_worker/service_worker_url_request_job.h b/content/browser/service_worker/service_worker_url_request_job.h
index 0081740..b9faa7a0 100644
--- a/content/browser/service_worker/service_worker_url_request_job.h
+++ b/content/browser/service_worker/service_worker_url_request_job.h
@@ -144,7 +144,8 @@
   void DidPrepareFetchEvent();
   void DidDispatchFetchEvent(ServiceWorkerStatusCode status,
                              ServiceWorkerFetchEventResult fetch_result,
-                             const ServiceWorkerResponse& response);
+                             const ServiceWorkerResponse& response,
+                             scoped_refptr<ServiceWorkerVersion> version);
 
   // Populates |http_response_headers_|.
   void CreateResponseHeader(int status_code,
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index 1f3dd48..c004bf0 100644
--- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -235,6 +235,39 @@
   TestRequest(200, "OK", std::string());
 }
 
+class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
+ public:
+  ProviderDeleteHelper(int mock_render_process_id)
+      : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
+  ~ProviderDeleteHelper() override {}
+
+ protected:
+  void OnFetchEvent(int embedded_worker_id,
+                    int request_id,
+                    const ServiceWorkerFetchRequest& request) override {
+    context()->RemoveProviderHost(kProcessID, kProviderID);
+    SimulateSend(new ServiceWorkerHostMsg_FetchEventFinished(
+        embedded_worker_id, request_id,
+        SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
+        ServiceWorkerResponse(
+            GURL(), 200, "OK", blink::WebServiceWorkerResponseTypeDefault,
+            ServiceWorkerHeaderMap(), std::string(), 0, GURL())));
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProviderDeleteHelper);
+};
+
+TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHost) {
+  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+  // Shouldn't crash if the ProviderHost is deleted prior to completion of
+  // the fetch event.
+  SetUpWithHelper(new ProviderDeleteHelper(kProcessID));
+
+  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+  TestRequest(200, "OK", std::string());
+}
+
 // Responds to fetch events with a blob.
 class BlobResponder : public EmbeddedWorkerTestHelper {
  public:
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index f0a9c17..de905b67 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -806,10 +806,6 @@
   if (HasControllee())
     return;
   FOR_EACH_OBSERVER(Listener, listeners_, OnNoControllees(this));
-  if (is_doomed_) {
-    DoomInternal();
-    return;
-  }
 }
 
 void ServiceWorkerVersion::AddStreamingURLRequestJob(
@@ -822,7 +818,7 @@
 void ServiceWorkerVersion::RemoveStreamingURLRequestJob(
     const ServiceWorkerURLRequestJob* request_job) {
   streaming_url_request_jobs_.erase(request_job);
-  if (is_doomed_)
+  if (is_redundant())
     StopWorkerIfIdle();
 }
 
@@ -845,11 +841,14 @@
 }
 
 void ServiceWorkerVersion::Doom() {
-  if (is_doomed_)
+  DCHECK(!HasControllee());
+  SetStatus(REDUNDANT);
+  StopWorkerIfIdle();
+  if (!context_)
     return;
-  is_doomed_ = true;
-  if (!HasControllee())
-    DoomInternal();
+  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+  script_cache_map_.GetResources(&resources);
+  context_->storage()->PurgeResources(resources);
 }
 
 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
@@ -927,7 +926,7 @@
   DCHECK_EQ(STOPPED, running_status());
   scoped_refptr<ServiceWorkerVersion> protect(this);
 
-  bool should_restart = !is_doomed() && !start_callbacks_.empty() &&
+  bool should_restart = !is_redundant() && !start_callbacks_.empty() &&
                         (old_status != EmbeddedWorkerInstance::STARTING);
 
   StopTimeoutTimer();
@@ -971,7 +970,6 @@
 
   FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this));
 
-  // Restart worker if we have any start callbacks and the worker isn't doomed.
   if (should_restart)
     StartWorkerInternal(false /* pause_after_download */);
 }
@@ -1139,7 +1137,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(rv);
-  RemoveCallbackAndStopIfDoomed(&activate_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&activate_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnInstallEventFinished(
@@ -1162,7 +1160,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(status);
-  RemoveCallbackAndStopIfDoomed(&install_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&install_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnFetchEventFinished(
@@ -1180,7 +1178,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(SERVICE_WORKER_OK, result, response);
-  RemoveCallbackAndStopIfDoomed(&fetch_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&fetch_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnSyncEventFinished(
@@ -1196,7 +1194,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(SERVICE_WORKER_OK);
-  RemoveCallbackAndStopIfDoomed(&sync_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&sync_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnNotificationClickEventFinished(
@@ -1212,7 +1210,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(SERVICE_WORKER_OK);
-  RemoveCallbackAndStopIfDoomed(&notification_click_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&notification_click_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnPushEventFinished(
@@ -1232,7 +1230,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(status);
-  RemoveCallbackAndStopIfDoomed(&push_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&push_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnGeofencingEventFinished(int request_id) {
@@ -1248,7 +1246,7 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(SERVICE_WORKER_OK);
-  RemoveCallbackAndStopIfDoomed(&geofencing_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&geofencing_callbacks_, request_id);
 }
 
 void ServiceWorkerVersion::OnCrossOriginConnectEventFinished(
@@ -1266,7 +1264,8 @@
 
   scoped_refptr<ServiceWorkerVersion> protect(this);
   callback->Run(SERVICE_WORKER_OK, accept_connection);
-  RemoveCallbackAndStopIfDoomed(&cross_origin_connect_callbacks_, request_id);
+  RemoveCallbackAndStopIfRedundant(&cross_origin_connect_callbacks_,
+                                   request_id);
 }
 
 void ServiceWorkerVersion::OnOpenWindow(int request_id, GURL url) {
@@ -1518,7 +1517,7 @@
     const StatusCallback& callback,
     ServiceWorkerStatusCode status,
     const scoped_refptr<ServiceWorkerRegistration>& protect) {
-  if (status != SERVICE_WORKER_OK || is_doomed()) {
+  if (status != SERVICE_WORKER_OK || is_redundant()) {
     RecordStartWorkerResult(status);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
     return;
@@ -1746,9 +1745,9 @@
   base::TimeTicks start_time = start_time_;
   ClearTick(&start_time_);
 
-  // Failing to start a doomed worker isn't interesting and very common when
+  // Failing to start a redundant worker isn't interesting and very common when
   // update dooms because the script is byte-to-byte identical.
-  if (is_doomed_ || status_ == REDUNDANT)
+  if (is_redundant())
     return;
 
   ServiceWorkerMetrics::RecordStartWorkerStatus(status, IsInstalled(status_));
@@ -1783,25 +1782,12 @@
                             EmbeddedWorkerInstance::STARTING_PHASE_MAX_VALUE);
 }
 
-void ServiceWorkerVersion::DoomInternal() {
-  DCHECK(is_doomed_);
-  DCHECK(!HasControllee());
-  SetStatus(REDUNDANT);
-  StopWorkerIfIdle();
-  if (!context_)
-    return;
-  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
-  script_cache_map_.GetResources(&resources);
-  context_->storage()->PurgeResources(resources);
-}
-
 template <typename IDMAP>
-void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed(
-    IDMAP* callbacks,
-    int request_id) {
+void ServiceWorkerVersion::RemoveCallbackAndStopIfRedundant(IDMAP* callbacks,
+                                                            int request_id) {
   RestartTick(&idle_time_);
   callbacks->Remove(request_id);
-  if (is_doomed_) {
+  if (is_redundant()) {
     // The stop should be already scheduled, but try to stop immediately, in
     // order to release worker resources soon.
     StopWorkerIfIdle();
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 11810a8..ba13327 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -286,11 +286,10 @@
   void ReportError(ServiceWorkerStatusCode status,
                    const std::string& status_message);
 
-  // Dooms this version to have REDUNDANT status and its resources deleted.  If
-  // the version is controlling a page, these changes will happen when the
-  // version no longer controls any pages.
+  // Sets this version's status to REDUNDANT and deletes its resources.
+  // The version must not have controllees.
   void Doom();
-  bool is_doomed() const { return is_doomed_; }
+  bool is_redundant() const { return status_ == REDUNDANT; }
 
   bool skip_waiting() const { return skip_waiting_; }
 
@@ -472,10 +471,8 @@
   // and records metrics about startup.
   void RecordStartWorkerResult(ServiceWorkerStatusCode status);
 
-  void DoomInternal();
-
   template <typename IDMAP>
-  void RemoveCallbackAndStopIfDoomed(IDMAP* callbacks, int request_id);
+  void RemoveCallbackAndStopIfRedundant(IDMAP* callbacks, int request_id);
 
   template <typename CallbackType>
   int AddRequest(const CallbackType& callback,
@@ -539,7 +536,6 @@
   // callback map).
   std::queue<RequestInfo> requests_;
 
-  bool is_doomed_ = false;
   bool skip_waiting_ = false;
   bool skip_recording_startup_time_ = false;
   bool force_bypass_cache_for_scripts_ = false;
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 3e76965..29ee0e1d 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -18,6 +18,7 @@
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/frame_messages.h"
+#include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
@@ -2044,4 +2045,33 @@
       DepictFrameTree(root));
 }
 
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       PageTransitionForSecondaryIframeNavigation) {
+  GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
+  NavigateToURL(shell(), main_url);
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+
+  TestNavigationObserver observer(shell()->web_contents());
+
+  // Load same-site page into iframe.
+  FrameTreeNode* child = root->child_at(0);
+  GURL http_url(embedded_test_server()->GetURL("/title1.html"));
+  NavigateFrameToURL(child, http_url);
+  EXPECT_EQ(http_url, observer.last_navigation_url());
+  EXPECT_TRUE(observer.last_navigation_succeeded());
+
+  // Load cross-site page into iframe.
+  TestFrameNavigationObserver frame_observer(child, 1);
+  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
+  NavigateIframeToURL(shell()->web_contents(), "test", url);
+  frame_observer.Wait();
+
+  EXPECT_EQ(NAVIGATION_TYPE_NEW_SUBFRAME,
+            frame_observer.load_committed_details().type);
+}
+
 }  // namespace content
diff --git a/content/browser/speech/google_streaming_remote_engine.cc b/content/browser/speech/google_streaming_remote_engine.cc
index ca8e906e..11c7ac7 100644
--- a/content/browser/speech/google_streaming_remote_engine.cc
+++ b/content/browser/speech/google_streaming_remote_engine.cc
@@ -445,20 +445,17 @@
       case proto::SpeechRecognitionEvent::STATUS_ABORTED:
         return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
       case proto::SpeechRecognitionEvent::STATUS_AUDIO_CAPTURE:
-        return Abort(SPEECH_RECOGNITION_ERROR_AUDIO);
+        return Abort(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE);
       case proto::SpeechRecognitionEvent::STATUS_NETWORK:
         return Abort(SPEECH_RECOGNITION_ERROR_NETWORK);
       case proto::SpeechRecognitionEvent::STATUS_NOT_ALLOWED:
-        // TODO(hans): We need a better error code for this.
-        return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+        return Abort(SPEECH_RECOGNITION_ERROR_NOT_ALLOWED);
       case proto::SpeechRecognitionEvent::STATUS_SERVICE_NOT_ALLOWED:
-        // TODO(hans): We need a better error code for this.
-        return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+        return Abort(SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED);
       case proto::SpeechRecognitionEvent::STATUS_BAD_GRAMMAR:
         return Abort(SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR);
       case proto::SpeechRecognitionEvent::STATUS_LANGUAGE_NOT_SUPPORTED:
-        // TODO(hans): We need a better error code for this.
-        return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+        return Abort(SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED);
     }
   }
 
diff --git a/content/browser/speech/speech_recognizer_impl.cc b/content/browser/speech/speech_recognizer_impl.cc
index 7b1d53f..a08ffe17 100644
--- a/content/browser/speech/speech_recognizer_impl.cc
+++ b/content/browser/speech/speech_recognizer_impl.cc
@@ -503,7 +503,7 @@
   // TODO(xians): Check if the OS has the device with |device_id_|, return
   // |SPEECH_AUDIO_ERROR_DETAILS_NO_MIC| if the target device does not exist.
   if (!audio_manager->HasAudioInputDevices()) {
-    return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO,
+    return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE,
                                         SPEECH_AUDIO_ERROR_DETAILS_NO_MIC));
   }
 
@@ -513,7 +513,8 @@
       device_id_);
   if (!in_params.IsValid() && !unit_test_is_active) {
     DLOG(ERROR) << "Invalid native audio input parameters";
-    return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO));
+    return Abort(
+        SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
   }
 
   // Audio converter shall provide audio based on these parameters as output.
@@ -564,7 +565,8 @@
       audio_manager, this, input_parameters, device_id_, NULL);
 
   if (!audio_controller_.get()) {
-    return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO));
+    return Abort(
+        SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
   }
 
   audio_log_->OnCreated(0, input_parameters, device_id_);
@@ -649,7 +651,8 @@
 SpeechRecognizerImpl::FSMState
 SpeechRecognizerImpl::AbortWithError(const FSMEventArgs& event_args) {
   if (event_args.event == EVENT_AUDIO_ERROR) {
-    return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO));
+    return Abort(
+        SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
   } else if (event_args.event == EVENT_ENGINE_ERROR) {
     return Abort(event_args.engine_error);
   }
diff --git a/content/browser/speech/speech_recognizer_impl_unittest.cc b/content/browser/speech/speech_recognizer_impl_unittest.cc
index 7168fb6..3e8ef28 100644
--- a/content/browser/speech/speech_recognizer_impl_unittest.cc
+++ b/content/browser/speech/speech_recognizer_impl_unittest.cc
@@ -380,7 +380,7 @@
   EXPECT_TRUE(recognition_started_);
   EXPECT_FALSE(audio_started_);
   EXPECT_FALSE(result_received_);
-  EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO, error_);
+  EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE, error_);
   CheckFinalEventsConsistency();
 }
 
@@ -400,7 +400,7 @@
   EXPECT_TRUE(recognition_started_);
   EXPECT_TRUE(audio_started_);
   EXPECT_FALSE(result_received_);
-  EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO, error_);
+  EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE, error_);
   CheckFinalEventsConsistency();
 }
 
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc
index 610f741..5a627fb 100644
--- a/content/browser/ssl/ssl_policy.cc
+++ b/content/browser/ssl/ssl_policy.cc
@@ -8,6 +8,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/memory/singleton.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "content/browser/frame_host/navigation_entry_impl.h"
@@ -26,6 +27,16 @@
 
 namespace content {
 
+namespace {
+
+// Events for UMA. Do not reorder or change!
+enum SSLGoodCertSeenEvent {
+  NO_PREVIOUS_EXCEPTION = 0,
+  HAD_PREVIOUS_EXCEPTION = 1,
+  SSL_GOOD_CERT_SEEN_EVENT_MAX = 2
+};
+}
+
 SSLPolicy::SSLPolicy(SSLPolicyBackend* backend)
     : backend_(backend) {
   DCHECK(backend_);
@@ -110,8 +121,20 @@
   // this information back through WebKit and out some FrameLoaderClient
   // methods.
 
-  if (net::IsCertStatusError(info->ssl_cert_status()))
+  if (net::IsCertStatusError(info->ssl_cert_status())) {
     backend_->HostRanInsecureContent(info->url().host(), info->child_id());
+  } else {
+    SSLGoodCertSeenEvent event = NO_PREVIOUS_EXCEPTION;
+    if (backend_->HasAllowException(info->url().host())) {
+      // If there's no certificate error, a good certificate has been seen, so
+      // clear out any exceptions that were made by the user for bad
+      // certificates.
+      backend_->RevokeUserAllowExceptions(info->url().host());
+      event = HAD_PREVIOUS_EXCEPTION;
+    }
+    UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.good_cert_seen", event,
+                              SSL_GOOD_CERT_SEEN_EVENT_MAX);
+  }
 }
 
 void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry,
diff --git a/content/browser/ssl/ssl_policy_backend.cc b/content/browser/ssl/ssl_policy_backend.cc
index 5c65874..a2626da 100644
--- a/content/browser/ssl/ssl_policy_backend.cc
+++ b/content/browser/ssl/ssl_policy_backend.cc
@@ -31,6 +31,20 @@
   return ssl_host_state_delegate_->DidHostRunInsecureContent(host, pid);
 }
 
+void SSLPolicyBackend::RevokeUserAllowExceptions(const std::string& host) {
+  if (!ssl_host_state_delegate_)
+    return;
+
+  ssl_host_state_delegate_->RevokeUserAllowExceptions(host);
+}
+
+bool SSLPolicyBackend::HasAllowException(const std::string& host) {
+  if (!ssl_host_state_delegate_)
+    return false;
+
+  return ssl_host_state_delegate_->HasAllowException(host);
+}
+
 void SSLPolicyBackend::AllowCertForHost(const net::X509Certificate& cert,
                                         const std::string& host,
                                         net::CertStatus error) {
diff --git a/content/browser/ssl/ssl_policy_backend.h b/content/browser/ssl/ssl_policy_backend.h
index 15ebe31..ed50c24 100644
--- a/content/browser/ssl/ssl_policy_backend.h
+++ b/content/browser/ssl/ssl_policy_backend.h
@@ -27,6 +27,13 @@
   // Returns whether the specified host ran insecure content.
   bool DidHostRunInsecureContent(const std::string& host, int pid) const;
 
+  // Revokes all allow exceptions by the user for |host|.
+  void RevokeUserAllowExceptions(const std::string& host);
+
+  // Returns true if and only if a user exception has previously been made for
+  // |host|.
+  bool HasAllowException(const std::string& host);
+
   // Records that |cert| is permitted to be used for |host| in the future, for
   // a specific error type.
   void AllowCertForHost(const net::X509Certificate& cert,
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index 34e384a..68984fa 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -937,6 +937,10 @@
     tmf->SendProcessMemoryDumpRequest(args);
 }
 
+bool TracingControllerImpl::IsCoordinatorProcess() const {
+  return true;
+}
+
 void TracingControllerImpl::OnProcessMemoryDumpResponse(
     TraceMessageFilter* trace_message_filter,
     uint64 dump_guid,
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h
index ce504e6..4b732ec 100644
--- a/content/browser/tracing/tracing_controller_impl.h
+++ b/content/browser/tracing/tracing_controller_impl.h
@@ -61,6 +61,7 @@
   void RequestGlobalMemoryDump(
       const base::trace_event::MemoryDumpRequestArgs& args,
       const base::trace_event::MemoryDumpCallback& callback) override;
+  bool IsCoordinatorProcess() const override;
 
  private:
   typedef std::set<scoped_refptr<TraceMessageFilter> > TraceMessageFilterSet;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 05f9806..3ce4b68 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -24,7 +24,6 @@
 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
 #include "content/browser/browser_plugin/browser_plugin_guest.h"
 #include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/devtools/devtools_manager.h"
 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
 #include "content/browser/download/download_stats.h"
@@ -3077,6 +3076,15 @@
 
 void WebContentsImpl::OnUpdateFaviconURL(
     const std::vector<FaviconURL>& candidates) {
+  // We get updated favicon URLs after the page stops loading. If a cross-site
+  // navigation occurs while a page is still loading, the initial page
+  // may stop loading and send us updated favicon URLs after the navigation
+  // for the new page has committed.
+  RenderViewHostImpl* rvhi =
+      static_cast<RenderViewHostImpl*>(render_view_message_source_);
+  if (!rvhi->is_active())
+    return;
+
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
                     DidUpdateFaviconURL(candidates));
 }
@@ -3561,8 +3569,6 @@
 
   FOR_EACH_OBSERVER(
       WebContentsObserver, observers_, RenderViewCreated(render_view_host));
-
-  DevToolsManager::GetInstance()->RenderViewCreated(this, render_view_host);
 }
 
 void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index 620b194..3a82a88 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2700,14 +2700,12 @@
   EXPECT_EQ(1u, instance->GetRelatedActiveContentsCount());
 
   // Navigate to a URL with WebUI. This will change BrowsingInstances.
-  contents->GetController().LoadURL(GURL(kTestWebUIUrl),
+  const GURL kWebUIUrl = GURL(kTestWebUIUrl);
+  contents->GetController().LoadURL(kWebUIUrl,
                                     Referrer(),
                                     ui::PAGE_TRANSITION_TYPED,
                                     std::string());
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableBrowserSideNavigation)) {
-    contents->GetMainFrame()->PrepareForCommit();
-  }
+  contents->GetMainFrame()->PrepareForCommit();
   EXPECT_TRUE(contents->CrossProcessNavigationPending());
   scoped_refptr<SiteInstance> instance_webui(
       contents->GetPendingMainFrame()->GetSiteInstance());
@@ -2718,7 +2716,7 @@
   EXPECT_EQ(0u, instance_webui->GetRelatedActiveContentsCount());
 
   // Commit and contents counts for the new one.
-  contents->CommitPendingNavigation();
+  contents->GetPendingMainFrame()->SendNavigate(1, kWebUIUrl);
   EXPECT_EQ(0u, instance->GetRelatedActiveContentsCount());
   EXPECT_EQ(1u, instance_webui->GetRelatedActiveContentsCount());
 
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 8cf8cd8..9e1f792 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -594,8 +594,8 @@
     return;
 
   NSSelectionDirection direction =
-      [[[notification userInfo] objectForKey:kSelectionDirection]
-        unsignedIntegerValue];
+      static_cast<NSSelectionDirection>([[[notification userInfo]
+          objectForKey:kSelectionDirection] unsignedIntegerValue]);
   if (direction == NSDirectSelection)
     return;
 
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
index fe296dd..77898e7a 100644
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -110,6 +110,7 @@
     sources = []
   } else {
     deps += [
+      "//components/scheduler:scheduler",
       "//content/app/resources",
       "//content/app/strings",
       "//crypto:platform",
diff --git a/content/child/DEPS b/content/child/DEPS
index 42cba53..7931bc2 100644
--- a/content/child/DEPS
+++ b/content/child/DEPS
@@ -1,9 +1,11 @@
 include_rules = [
   # Allow inclusion of specific components that we depend on. We may only
   # depend on components which we share with the mojo html_viewer.
+  "+components/scheduler/child",
+  "+components/scheduler/common",
+  "+components/tracing",
   "+components/webcrypto",
 
-  "+components/tracing",
   "+content/app/strings/grit",  # For generated headers
   "+content/public/child",
   "+media/base/android",
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 8a58c91..25faab4 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -27,6 +27,7 @@
 #include "base/time/time.h"
 #include "blink/public/resources/grit/blink_image_resources.h"
 #include "blink/public/resources/grit/blink_resources.h"
+#include "components/scheduler/child/webthread_impl_for_worker_scheduler.h"
 #include "content/app/resources/grit/content_resources.h"
 #include "content/app/strings/grit/content_strings.h"
 #include "content/child/bluetooth/web_bluetooth_impl.h"
@@ -40,7 +41,6 @@
 #include "content/child/permissions/permission_dispatcher_thread_proxy.h"
 #include "content/child/push_messaging/push_dispatcher.h"
 #include "content/child/push_messaging/push_provider.h"
-#include "content/child/scheduler/webthread_impl_for_worker_scheduler.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/web_discardable_memory_impl.h"
 #include "content/child/web_url_loader_impl.h"
@@ -519,8 +519,8 @@
 }
 
 blink::WebThread* BlinkPlatformImpl::createThread(const char* name) {
-  WebThreadImplForWorkerScheduler* thread =
-      new WebThreadImplForWorkerScheduler(name);
+  scheduler::WebThreadImplForWorkerScheduler* thread =
+      new scheduler::WebThreadImplForWorkerScheduler(name);
   thread->TaskRunner()->PostTask(
       FROM_HERE, base::Bind(&BlinkPlatformImpl::UpdateWebThreadTLS,
                             base::Unretained(this), thread));
@@ -589,15 +589,18 @@
   return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
 }
 
-long* BlinkPlatformImpl::getTraceSamplingState(
-    const unsigned thread_bucket) {
+blink::Platform::TraceEventAPIAtomicWord*
+BlinkPlatformImpl::getTraceSamplingState(const unsigned thread_bucket) {
   switch (thread_bucket) {
     case 0:
-      return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(0));
+      return reinterpret_cast<blink::Platform::TraceEventAPIAtomicWord*>(
+          &TRACE_EVENT_API_THREAD_BUCKET(0));
     case 1:
-      return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(1));
+      return reinterpret_cast<blink::Platform::TraceEventAPIAtomicWord*>(
+          &TRACE_EVENT_API_THREAD_BUCKET(1));
     case 2:
-      return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(2));
+      return reinterpret_cast<blink::Platform::TraceEventAPIAtomicWord*>(
+          &TRACE_EVENT_API_THREAD_BUCKET(2));
     default:
       NOTREACHED() << "Unknown thread bucket type.";
   }
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 7ae04dc..3b5462d2 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -102,7 +102,8 @@
   virtual void histogramSparse(const char* name, int sample);
   virtual const unsigned char* getTraceCategoryEnabledFlag(
       const char* category_name);
-  virtual long* getTraceSamplingState(const unsigned thread_bucket);
+  virtual TraceEventAPIAtomicWord* getTraceSamplingState(
+      const unsigned thread_bucket);
   virtual TraceEventHandle addTraceEvent(
       char phase,
       const unsigned char* category_group_enabled,
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 30dbbe89..d2f1791b 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -13,6 +13,7 @@
 #include "base/basictypes.h"
 #include "base/command_line.h"
 #include "base/debug/leak_annotations.h"
+#include "base/debug/profiler.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
@@ -25,6 +26,7 @@
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/thread_local.h"
+#include "base/trace_event/memory_dump_manager.h"
 #include "base/tracked_objects.h"
 #include "components/tracing/child_trace_message_filter.h"
 #include "content/child/bluetooth/bluetooth_message_filter.h"
@@ -138,6 +140,7 @@
     //
     // So, we install a filter on the sender so that we can process this event
     // here and kill the process.
+    base::debug::StopProfiling();
 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
     defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
     defined(UNDEFINED_SANITIZER)
@@ -419,6 +422,8 @@
       ::HeapProfilerStop, ::GetHeapProfile));
 #endif
 
+  base::trace_event::MemoryDumpManager::GetInstance()->Initialize();
+
   shared_bitmap_manager_.reset(
       new ChildSharedBitmapManager(thread_safe_sender()));
 
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 39adb12..b4d5df5 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -9,6 +9,7 @@
 #include "base/command_line.h"
 #include "base/metrics/field_trial.h"
 #include "base/strings/string_split.h"
+#include "components/scheduler/common/scheduler_switches.h"
 #include "content/common/content_switches_internal.h"
 #include "content/public/common/content_switches.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
@@ -96,7 +97,7 @@
   if (command_line.HasSwitch(switches::kDisableDatabases))
     WebRuntimeFeatures::enableDatabase(false);
 
-  if (command_line.HasSwitch(switches::kDisableBlinkScheduler))
+  if (command_line.HasSwitch(scheduler::switches::kDisableBlinkScheduler))
     WebRuntimeFeatures::enableBlinkScheduler(false);
 
   if (command_line.HasSwitch(switches::kDisableLocalStorage))
@@ -116,9 +117,6 @@
     WebRuntimeFeatures::enableSharedWorker(false);
 
 #if defined(OS_ANDROID)
-  if (command_line.HasSwitch(switches::kDisableWebRTC))
-    WebRuntimeFeatures::enablePeerConnection(false);
-
   // WebAudio is enabled by default on ARM and X86, if the MediaCodec
   // API is available.
   WebRuntimeFeatures::enableWebAudio(
diff --git a/content/child/scheduler/null_idle_task_runner.h b/content/child/scheduler/null_idle_task_runner.h
deleted file mode 100644
index 31a83fc..0000000
--- a/content/child/scheduler/null_idle_task_runner.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_CHILD_SCHEDULER_NULL_IDLE_TASK_RUNNER_H_
-#define CONTENT_CHILD_SCHEDULER_NULL_IDLE_TASK_RUNNER_H_
-
-#include "content/child/scheduler/single_thread_idle_task_runner.h"
-
-namespace content {
-
-class NullIdleTaskRunner : public SingleThreadIdleTaskRunner {
- public:
-  NullIdleTaskRunner();
-  void PostIdleTask(const tracked_objects::Location& from_here,
-                    const IdleTask& idle_task) override;
-
-  void PostNonNestableIdleTask(
-      const tracked_objects::Location& from_here,
-      const IdleTask& idle_task) override;
-
-  void PostIdleTaskAfterWakeup(
-      const tracked_objects::Location& from_here,
-      const IdleTask& idle_task) override;
-
- protected:
-  ~NullIdleTaskRunner() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NullIdleTaskRunner);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_SCHEDULER_NULL_IDLE_TASK_RUNNER_H_
diff --git a/content/child/scheduler/time_source.h b/content/child/scheduler/time_source.h
deleted file mode 100644
index e5d8606b..0000000
--- a/content/child/scheduler/time_source.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_CHILD_SCHEDULER_TIME_SOURCE_H_
-#define CONTENT_CHILD_SCHEDULER_TIME_SOURCE_H_
-
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-class CONTENT_EXPORT TimeSource {
- public:
-  TimeSource();
-  virtual ~TimeSource();
-
-  virtual base::TimeTicks Now() const;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TimeSource);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_SCHEDULER_TIME_SOURCE_H_
diff --git a/content/child/scheduler/worker_scheduler.h b/content/child/scheduler/worker_scheduler.h
deleted file mode 100644
index 7d12251..0000000
--- a/content/child/scheduler/worker_scheduler.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_CHILD_SCHEDULER_WORKER_SCHEDULER_H_
-#define CONTENT_CHILD_SCHEDULER_WORKER_SCHEDULER_H_
-
-#include "base/message_loop/message_loop.h"
-#include "content/child/scheduler/child_scheduler.h"
-#include "content/child/scheduler/single_thread_idle_task_runner.h"
-#include "content/common/content_export.h"
-
-namespace base {
-class MessageLoop;
-}
-
-namespace content {
-
-class CONTENT_EXPORT WorkerScheduler : public ChildScheduler {
- public:
-  ~WorkerScheduler() override;
-  static scoped_ptr<WorkerScheduler> Create(base::MessageLoop* message_loop);
-
-  // Must be called before the scheduler can be used. Does any post construction
-  // initialization needed such as initializing idle period detection.
-  virtual void Init() = 0;
-
- protected:
-  WorkerScheduler();
-  DISALLOW_COPY_AND_ASSIGN(WorkerScheduler);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_SCHEDULER_WORKER_SCHEDULER_H_
diff --git a/content/child/threaded_data_provider.cc b/content/child/threaded_data_provider.cc
index 395e452..eea420a 100644
--- a/content/child/threaded_data_provider.cc
+++ b/content/child/threaded_data_provider.cc
@@ -4,10 +4,10 @@
 
 #include "content/child/threaded_data_provider.h"
 
+#include "components/scheduler/child/webthread_impl_for_worker_scheduler.h"
 #include "content/child/child_process.h"
 #include "content/child/child_thread_impl.h"
 #include "content/child/resource_dispatcher.h"
-#include "content/child/scheduler/webthread_impl_for_worker_scheduler.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/common/resource_messages.h"
 #include "ipc/ipc_sync_channel.h"
@@ -23,7 +23,7 @@
   DataProviderMessageFilter(
       const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
-      const WebThreadImplForWorkerScheduler& background_thread,
+      const scheduler::WebThreadImplForWorkerScheduler& background_thread,
       const base::WeakPtr<ThreadedDataProvider>&
           background_thread_resource_provider,
       const base::WeakPtr<ThreadedDataProvider>& main_thread_resource_provider,
@@ -41,7 +41,7 @@
 
   const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
-  const WebThreadImplForWorkerScheduler& background_thread_;
+  const scheduler::WebThreadImplForWorkerScheduler& background_thread_;
   // This weakptr can only be dereferenced on the background thread.
   base::WeakPtr<ThreadedDataProvider>
       background_thread_resource_provider_;
@@ -54,7 +54,7 @@
 DataProviderMessageFilter::DataProviderMessageFilter(
     const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
-    const WebThreadImplForWorkerScheduler& background_thread,
+    const scheduler::WebThreadImplForWorkerScheduler& background_thread,
     const base::WeakPtr<ThreadedDataProvider>&
         background_thread_resource_provider,
     const base::WeakPtr<ThreadedDataProvider>& main_thread_resource_provider,
@@ -126,8 +126,9 @@
     : request_id_(request_id),
       shm_buffer_(shm_buffer),
       shm_size_(shm_size),
-      background_thread_(static_cast<WebThreadImplForWorkerScheduler&>(
-          *threaded_data_receiver->backgroundThread())),
+      background_thread_(
+          static_cast<scheduler::WebThreadImplForWorkerScheduler&>(
+              *threaded_data_receiver->backgroundThread())),
       ipc_channel_(ChildThreadImpl::current()->channel()),
       threaded_data_receiver_(threaded_data_receiver),
       resource_filter_active_(false),
@@ -186,7 +187,8 @@
     // We should never end up with a different parser thread than from when the
     // ThreadedDataProvider gets created.
     DCHECK(current_background_thread ==
-           static_cast<WebThreadImplForWorkerScheduler*>(&background_thread_));
+           static_cast<scheduler::WebThreadImplForWorkerScheduler*>(
+               &background_thread_));
     background_thread_.TaskRunner()->PostTask(
         FROM_HERE, base::Bind(&ThreadedDataProvider::StopOnBackgroundThread,
                               base::Unretained(this)));
diff --git a/content/child/threaded_data_provider.h b/content/child/threaded_data_provider.h
index effb4f9..5cd74330 100644
--- a/content/child/threaded_data_provider.h
+++ b/content/child/threaded_data_provider.h
@@ -24,9 +24,12 @@
 class SyncChannel;
 }
 
+namespace scheduler {
+class WebThreadImplForWorkerScheduler;
+}
+
 namespace content {
 class ResourceDispatcher;
-class WebThreadImplForWorkerScheduler;
 
 class ThreadedDataProvider {
  public:
@@ -78,7 +81,7 @@
   int shm_size_;
   scoped_ptr<base::WeakPtrFactory<ThreadedDataProvider> >
       background_thread_weak_factory_;
-  WebThreadImplForWorkerScheduler& background_thread_;
+  scheduler::WebThreadImplForWorkerScheduler& background_thread_;
   IPC::SyncChannel* ipc_channel_;
   blink::WebThreadedDataReceiver* threaded_data_receiver_;
   bool resource_filter_active_;
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index c3431b5..a1a5beb4 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -778,6 +778,11 @@
   if (request_.downloadToFile())
     return false;
 
+  // Data url requests from object tags may need to be intercepted as streams
+  // and so need to be sent to the browser.
+  if (request_.requestContext() == WebURLRequest::RequestContextObject)
+    return false;
+
   // Optimize for the case where we can handle a data URL locally.  We must
   // skip this for data URLs targetted at frames since those could trigger a
   // download.
diff --git a/content/common/gpu/media/h264_decoder.cc b/content/common/gpu/media/h264_decoder.cc
index 02ba468c..9953ff2 100644
--- a/content/common/gpu/media/h264_decoder.cc
+++ b/content/common/gpu/media/h264_decoder.cc
@@ -615,6 +615,9 @@
 void H264Decoder::OutputPic(scoped_refptr<H264Picture> pic) {
   DCHECK(!pic->outputted);
   pic->outputted = true;
+
+  DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_)
+      << "Outputting out of order, likely a broken stream";
   last_output_poc_ = pic->pic_order_cnt;
 
   DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt;
@@ -895,16 +898,25 @@
   // to remain in the DPB and can be removed.
   H264Picture::Vector::iterator output_candidate = not_outputted.begin();
   size_t num_remaining = not_outputted.size();
-  while (num_remaining > max_num_reorder_frames_) {
-    int poc = (*output_candidate)->pic_order_cnt;
-    DCHECK_GE(poc, last_output_poc_);
+  while (num_remaining > max_num_reorder_frames_ ||
+         // If the condition below is used, this is an invalid stream. We should
+         // not be forced to output beyond max_num_reorder_frames in order to
+         // make room in DPB to store the current picture (if we need to do so).
+         // However, if this happens, ignore max_num_reorder_frames and try
+         // to output more. This may cause out-of-order output, but is not
+         // fatal, and better than failing instead.
+         ((dpb_.IsFull() && (!pic->outputted || pic->ref)) && num_remaining)) {
+    DVLOG_IF(1, num_remaining <= max_num_reorder_frames_)
+        << "Invalid stream: max_num_reorder_frames not preserved";
+
     OutputPic(*output_candidate);
 
     if (!(*output_candidate)->ref) {
       // Current picture hasn't been inserted into DPB yet, so don't remove it
       // if we managed to output it immediately.
-      if ((*output_candidate)->pic_order_cnt != pic->pic_order_cnt)
-        dpb_.DeleteByPOC(poc);
+      int outputted_poc = (*output_candidate)->pic_order_cnt;
+      if (outputted_poc != pic->pic_order_cnt)
+        dpb_.DeleteByPOC(outputted_poc);
     }
 
     ++output_candidate;
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
index d075740..e2d29c5 100644
--- a/content/common/gpu/media/v4l2_video_encode_accelerator.cc
+++ b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
@@ -868,7 +868,6 @@
   // Device might have adjusted the required output size.
   size_t adjusted_output_buffer_size =
       base::checked_cast<size_t>(format.fmt.pix_mp.plane_fmt[0].sizeimage);
-  DCHECK_GE(adjusted_output_buffer_size, output_buffer_byte_size_);
   output_buffer_byte_size_ = adjusted_output_buffer_size;
 
   return true;
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 2eece7a..87c7a71a 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1729,6 +1729,7 @@
         'browser/devtools/devtools.gyp:devtools_protocol_handler',
         '../cc/cc.gyp:cc',
         '../cc/cc.gyp:cc_surfaces',
+        '../components/scheduler/scheduler.gyp:scheduler_common',
         '../device/bluetooth/bluetooth.gyp:device_bluetooth',
         '../net/net.gyp:http_server',
         '../storage/storage_browser.gyp:storage',
@@ -1815,12 +1816,6 @@
         'browser/media/capture/desktop_capture_device_aura.h',
       ],
     }],
-    ['enable_webrtc==1 and (OS=="linux" or OS=="mac")', {
-      'sources': [
-        'browser/renderer_host/media/video_capture_texture_wrapper.cc',
-        'browser/renderer_host/media/video_capture_texture_wrapper.h',
-      ],
-    }],
     ['OS=="win"', {
       'dependencies': [
         # For accessibility
diff --git a/content/content_child.gypi b/content/content_child.gypi
index 297c40d..02da309 100644
--- a/content/content_child.gypi
+++ b/content/content_child.gypi
@@ -190,35 +190,6 @@
       'child/request_extra_data.h',
       'child/request_info.cc',
       'child/request_info.h',
-      'child/scheduler/cancelable_closure_holder.cc',
-      'child/scheduler/cancelable_closure_holder.h',
-      'child/scheduler/child_scheduler.h',
-      'child/scheduler/nestable_single_thread_task_runner.h',
-      'child/scheduler/null_idle_task_runner.cc',
-      'child/scheduler/null_idle_task_runner.h',
-      'child/scheduler/null_worker_scheduler.cc',
-      'child/scheduler/null_worker_scheduler.h',
-      'child/scheduler/prioritizing_task_queue_selector.cc',
-      'child/scheduler/prioritizing_task_queue_selector.h',
-      'child/scheduler/scheduler_helper.cc',
-      'child/scheduler/scheduler_helper.h',
-      'child/scheduler/scheduler_message_loop_delegate.cc',
-      'child/scheduler/scheduler_message_loop_delegate.h',
-      'child/scheduler/single_thread_idle_task_runner.cc',
-      'child/scheduler/single_thread_idle_task_runner.h',
-      'child/scheduler/task_queue_selector.h',
-      'child/scheduler/task_queue_manager.cc',
-      'child/scheduler/task_queue_manager.h',
-      'child/scheduler/time_source.cc',
-      'child/scheduler/time_source.h',
-      'child/scheduler/webthread_impl_for_worker_scheduler.cc',
-      'child/scheduler/webthread_impl_for_worker_scheduler.h',
-      'child/scheduler/web_scheduler_impl.cc',
-      'child/scheduler/web_scheduler_impl.h',
-      'child/scheduler/worker_scheduler.cc',
-      'child/scheduler/worker_scheduler.h',
-      'child/scheduler/worker_scheduler_impl.cc',
-      'child/scheduler/worker_scheduler_impl.h',
       'child/resource_dispatcher.cc',
       'child/resource_dispatcher.h',
       'child/resource_scheduling_filter.cc',
@@ -286,8 +257,6 @@
       'child/webthemeengine_impl_default.cc',
       'child/webthemeengine_impl_default.h',
       'child/webthemeengine_impl_mac.h',
-      'child/webthread_base.cc',
-      'child/webthread_base.h',
       'child/weburlresponse_extradata_impl.cc',
       'child/weburlresponse_extradata_impl.h',
       'child/worker_task_runner.cc',
@@ -333,6 +302,7 @@
       'dependencies': [
         'app/resources/content_resources.gyp:content_resources',
         'app/strings/content_strings.gyp:content_strings',
+        '../components/scheduler/scheduler.gyp:scheduler',
         '../storage/storage_common.gyp:storage_common',
         '../third_party/WebKit/public/blink.gyp:blink',
         '../third_party/WebKit/public/blink_resources.gyp:blink_image_resources',
diff --git a/content/content_nacl_nonsfi.gyp b/content/content_nacl_nonsfi.gyp
index 4f30ca4..f60f120 100644
--- a/content/content_nacl_nonsfi.gyp
+++ b/content/content_nacl_nonsfi.gyp
@@ -32,7 +32,6 @@
           },
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
           ],
         },
       ],
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 0ae7fbba..fb2a7cf 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -8,6 +8,7 @@
     '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
     '../cc/cc.gyp:cc',
     '../cc/blink/cc_blink.gyp:cc_blink',
+    '../components/scheduler/scheduler.gyp:scheduler',
     '../device/battery/battery.gyp:device_battery',
     '../device/battery/battery.gyp:device_battery_mojo_bindings',
     '../device/vibration/vibration.gyp:device_vibration',
@@ -371,18 +372,8 @@
       'renderer/sad_plugin.h',
       'renderer/savable_resources.cc',
       'renderer/savable_resources.h',
-      'renderer/scheduler/deadline_task_runner.cc',
-      'renderer/scheduler/deadline_task_runner.h',
-      'renderer/scheduler/null_renderer_scheduler.cc',
-      'renderer/scheduler/null_renderer_scheduler.h',
-      'renderer/scheduler/renderer_scheduler.cc',
-      'renderer/scheduler/renderer_scheduler.h',
-      'renderer/scheduler/renderer_scheduler_impl.cc',
-      'renderer/scheduler/renderer_scheduler_impl.h',
       'renderer/scheduler/resource_dispatch_throttler.cc',
       'renderer/scheduler/resource_dispatch_throttler.h',
-      'renderer/scheduler/webthread_impl_for_renderer_scheduler.cc',
-      'renderer/scheduler/webthread_impl_for_renderer_scheduler.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 4931f11..20835bd4 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -47,6 +47,7 @@
         '../cc/blink/cc_blink.gyp:cc_blink',
         '../cc/cc.gyp:cc',
         '../components/components.gyp:crash_component_breakpad_mac_to_be_deleted',
+        '../components/components.gyp:devtools_discovery',
         '../components/components.gyp:devtools_http_handler',
         '../components/components.gyp:web_cache_renderer',
         '../device/bluetooth/bluetooth.gyp:device_bluetooth',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index a9938c21..660e674 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -163,8 +163,6 @@
       'test/test_render_view_host.h',
       'test/test_render_view_host_factory.cc',
       'test/test_render_view_host_factory.h',
-      'test/test_time_source.cc',
-      'test/test_time_source.h',
       'test/test_web_contents.cc',
       'test/test_web_contents.h',
       'test/test_web_contents_factory.cc',
@@ -190,8 +188,8 @@
       'browser/accessibility/dump_accessibility_browsertest_base.h',
       'browser/accessibility/dump_accessibility_events_browsertest.cc',
       'browser/accessibility/dump_accessibility_tree_browsertest.cc',
-      'browser/accessibility/snapshot_ax_tree_browsertest.cc',
       'browser/accessibility/site_per_process_accessibility_browsertest.cc',
+      'browser/accessibility/snapshot_ax_tree_browsertest.cc',
       'browser/battery_status/battery_monitor_impl_browsertest.cc',
       'browser/battery_status/battery_monitor_integration_browsertest.cc',
       'browser/bookmarklet_browsertest.cc',
@@ -249,8 +247,8 @@
       'browser/web_contents/web_contents_view_aura_browsertest.cc',
       'browser/webkit_browsertest.cc',
       'browser/webui/web_ui_mojo_browsertest.cc',
-      'child/site_isolation_policy_browsertest.cc',
       'child/child_discardable_shared_memory_manager_browsertest.cc',
+      'child/site_isolation_policy_browsertest.cc',
       'renderer/accessibility/renderer_accessibility_browsertest.cc',
       'renderer/devtools/v8_sampling_profiler_browsertest.cc',
       'renderer/gin_browsertest.cc',
@@ -478,10 +476,10 @@
       'browser/media/midi_host_unittest.cc',
       'browser/media/webrtc_identity_store_unittest.cc',
       'browser/net/sqlite_persistent_cookie_store_unittest.cc',
+      'browser/notification_service_impl_unittest.cc',
       'browser/notifications/notification_database_data_unittest.cc',
       'browser/notifications/notification_database_unittest.cc',
       'browser/notifications/platform_notification_context_unittest.cc',
-      'browser/notification_service_impl_unittest.cc',
       'browser/power_monitor_message_broadcaster_unittest.cc',
       'browser/power_profiler/power_profiler_service_unittest.cc',
       'browser/power_usage_monitor_impl_unittest.cc',
@@ -587,13 +585,6 @@
       'child/notifications/notification_data_conversions_unittest.cc',
       'child/power_monitor_broadcast_source_unittest.cc',
       'child/resource_dispatcher_unittest.cc',
-      'child/scheduler/nestable_task_runner_for_test.cc',
-      'child/scheduler/nestable_task_runner_for_test.h',
-      'child/scheduler/prioritizing_task_queue_selector_unittest.cc',
-      'child/scheduler/scheduler_helper_unittest.cc',
-      'child/scheduler/task_queue_manager_unittest.cc',
-      'child/scheduler/webthread_impl_for_worker_scheduler_unittest.cc',
-      'child/scheduler/worker_scheduler_impl_unittest.cc',
       'child/service_worker/service_worker_dispatcher_unittest.cc',
       'child/simple_webmimeregistry_impl_unittest.cc',
       'child/site_isolation_policy_unittest.cc',
@@ -665,10 +656,7 @@
       'renderer/media/video_capture_message_filter_unittest.cc',
       'renderer/render_thread_impl_unittest.cc',
       'renderer/render_widget_unittest.cc',
-      'renderer/scheduler/deadline_task_runner_unittest.cc',
-      'renderer/scheduler/renderer_scheduler_impl_unittest.cc',
       'renderer/scheduler/resource_dispatch_throttler_unittest.cc',
-      'renderer/scheduler/webthread_impl_for_renderer_scheduler_unittest.cc',
       'renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc',
       'renderer/skia_benchmarking_extension_unittest.cc',
       'test/fileapi_test_file_set.cc',
@@ -873,6 +861,7 @@
             '../cc/blink/cc_blink.gyp:cc_blink',
             '../cc/cc.gyp:cc',
             '../cc/cc_tests.gyp:cc_test_support',
+            '../components/scheduler/scheduler.gyp:scheduler',
             '../gpu/blink/gpu_blink.gyp:gpu_blink',
             '../ipc/mojo/ipc_mojo.gyp:*',
             '../media/blink/media_blink.gyp:media_blink',
@@ -1256,7 +1245,6 @@
             'browser/renderer_host/input/input_router_impl_perftest.cc',
             'common/cc_messages_perftest.cc',
             'common/discardable_shared_memory_heap_perftest.cc',
-            'child/scheduler/task_queue_manager_perftest.cc',
             'test/run_all_perftests.cc',
           ],
           'conditions': [
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentView.java b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
index 63761a69..33a7c2c 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
@@ -8,7 +8,6 @@
 import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -16,8 +15,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.widget.FrameLayout;
@@ -40,17 +38,8 @@
      * @param context The Context the view is running in, through which it can
      *                access the current theme, resources, etc.
      * @param cvc A pointer to the content view core managing this content view.
-     * @return A ContentView instance.
      */
-    public static ContentView newInstance(Context context, ContentViewCore cvc) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
-            return new ContentView(context, cvc);
-        } else {
-            return new JellyBeanContentView(context, cvc);
-        }
-    }
-
-    protected ContentView(Context context, ContentViewCore cvc) {
+    public ContentView(Context context, ContentViewCore cvc) {
         super(context, null, android.R.attr.webViewStyle);
 
         if (getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
@@ -64,6 +53,25 @@
         mContentViewCore = cvc;
     }
 
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        if (mContentViewCore.supportsAccessibilityAction(action)) {
+            return mContentViewCore.performAccessibilityAction(action, arguments);
+        }
+
+        return super.performAccessibilityAction(action, arguments);
+    }
+
+    @Override
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+        AccessibilityNodeProvider provider = mContentViewCore.getAccessibilityNodeProvider();
+        if (provider != null) {
+            return provider;
+        } else {
+            return super.getAccessibilityNodeProvider();
+        }
+    }
+
     // Needed by ContentViewCore.InternalAccessDelegate
     @Override
     public boolean drawChild(Canvas canvas, View child, long drawingTime) {
@@ -226,22 +234,6 @@
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        mContentViewCore.onInitializeAccessibilityNodeInfo(info);
-    }
-
-    /**
-     * Fills in scrolling values for AccessibilityEvents.
-     * @param event Event being fired.
-     */
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        mContentViewCore.onInitializeAccessibilityEvent(event);
-    }
-
-    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mContentViewCore.onAttachedToWindow();
@@ -273,6 +265,7 @@
             return;
         }
         mContentViewCore.setSmartClipDataListener(new ContentViewCore.SmartClipDataListener() {
+            @Override
             public void onSmartClipDataExtracted(String text, String html, Rect clipRect) {
                 Bundle bundle = new Bundle();
                 bundle.putString("url", mContentViewCore.getWebContents().getVisibleUrl());
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
index 8775c6bb..a874357 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
@@ -171,15 +171,6 @@
     }
 
     /**
-     * @return Whether javascript is enabled by the embedder.
-     */
-    // TODO(tedchoc): Only used for ICS accessibility injection, so remove this method when
-    //                that is no longer needed.
-    public boolean isJavascriptEnabled() {
-        return true;
-    }
-
-    /**
      * @return Whether an externally managed (i.e., not compositor-driven) fling
      *         of this ContentView is active.
      */
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 cb233d4..c064988 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
@@ -9,7 +9,6 @@
 import android.app.Activity;
 import android.app.SearchManager;
 import android.content.ClipboardManager;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
@@ -19,14 +18,12 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Rect;
-import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.provider.Browser;
-import android.provider.Settings;
 import android.text.Editable;
 import android.text.Selection;
 import android.text.TextUtils;
@@ -38,10 +35,8 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
@@ -58,7 +53,6 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.content.R;
 import org.chromium.content.browser.ScreenOrientationListener.ScreenOrientationObserver;
-import org.chromium.content.browser.accessibility.AccessibilityInjector;
 import org.chromium.content.browser.accessibility.BrowserAccessibilityManager;
 import org.chromium.content.browser.accessibility.captioning.CaptioningBridgeFactory;
 import org.chromium.content.browser.accessibility.captioning.SystemCaptioningBridge;
@@ -89,7 +83,6 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -314,20 +307,6 @@
         }
 
         @Override
-        public void didStartLoading(String url) {
-            ContentViewCore contentViewCore = mWeakContentViewCore.get();
-            if (contentViewCore == null) return;
-            contentViewCore.mAccessibilityInjector.onPageLoadStarted();
-        }
-
-        @Override
-        public void didStopLoading(String url) {
-            ContentViewCore contentViewCore = mWeakContentViewCore.get();
-            if (contentViewCore == null) return;
-            contentViewCore.mAccessibilityInjector.onPageLoadStopped();
-        }
-
-        @Override
         public void didFailLoad(boolean isProvisionalLoad, boolean isMainFrame, int errorCode,
                 String description, String failingUrl) {
             // Navigation that fails the provisional load will have the strong binding removed
@@ -539,9 +518,6 @@
     // Delegate that will handle GET downloads, and be notified of completion of POST downloads.
     private ContentViewDownloadDelegate mDownloadDelegate;
 
-    // The AccessibilityInjector that handles loading Accessibility scripts into the web page.
-    private AccessibilityInjector mAccessibilityInjector;
-
     // Whether native accessibility, i.e. without any script injection, is allowed.
     private boolean mNativeAccessibilityAllowed;
 
@@ -837,8 +813,6 @@
         mImeAdapter = createImeAdapter();
         attachImeAdapter();
 
-        mAccessibilityInjector = AccessibilityInjector.newInstance(this);
-
         mWebContentsObserver = new ContentViewWebContentsObserver(this);
     }
 
@@ -989,7 +963,6 @@
         if (mNativeContentViewCore != 0) {
             nativeOnJavaContentViewCoreDestroyed(mNativeContentViewCore);
         }
-        mSystemCaptioningBridge.destroy();
         mWebContentsObserver.destroy();
         mWebContentsObserver = null;
         setSmartClipDataListener(null);
@@ -1443,7 +1416,6 @@
     public void onHide() {
         assert mWebContents != null;
         hidePopupsAndPreserveSelection();
-        setInjectedAccessibility(false);
         mWebContents.onHide();
     }
 
@@ -1506,6 +1478,7 @@
         restoreSelectionPopupsIfNecessary();
         ScreenOrientationListener.getInstance().addObserver(this, mContext);
         GamepadList.onAttachedToWindow(mContext);
+        mSystemCaptioningBridge.registerBridge();
     }
 
     /**
@@ -1514,7 +1487,6 @@
     @SuppressWarnings("javadoc")
     @SuppressLint("MissingSuperCall")
     public void onDetachedFromWindow() {
-        setInjectedAccessibility(false);
         mZoomControlsDelegate.dismissZoomPicker();
         unregisterAccessibilityContentObserver();
 
@@ -1528,6 +1500,7 @@
         // locking and app switching.
         setTextHandlesTemporarilyHidden(true);
         hidePopupsAndPreserveSelection();
+        mSystemCaptioningBridge.unregisterBridge();
     }
 
     /**
@@ -2877,7 +2850,8 @@
      * @return Whether or not this action is supported.
      */
     public boolean supportsAccessibilityAction(int action) {
-        return mAccessibilityInjector.supportsAccessibilityAction(action);
+        // TODO(dmazzoni): implement this in BrowserAccessibilityManager.
+        return false;
     }
 
     /**
@@ -2891,10 +2865,7 @@
      *         the super {@link View} class.
      */
     public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (mAccessibilityInjector.supportsAccessibilityAction(action)) {
-            return mAccessibilityInjector.performAccessibilityAction(action, arguments);
-        }
-
+        // TODO(dmazzoni): implement this in BrowserAccessibilityManager.
         return false;
     }
 
@@ -2955,96 +2926,6 @@
     }
 
     /**
-     * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
-     */
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        // Note: this is only used by the script-injecting accessibility code.
-        mAccessibilityInjector.onInitializeAccessibilityNodeInfo(info);
-    }
-
-    /**
-     * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
-     */
-    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        // Note: this is only used by the script-injecting accessibility code.
-        event.setClassName(this.getClass().getName());
-
-        // Identify where the top-left of the screen currently points to.
-        event.setScrollX(mRenderCoordinates.getScrollXPixInt());
-        event.setScrollY(mRenderCoordinates.getScrollYPixInt());
-
-        // The maximum scroll values are determined by taking the content dimensions and
-        // subtracting off the actual dimensions of the ChromeView.
-        int maxScrollXPix = Math.max(0, mRenderCoordinates.getMaxHorizontalScrollPixInt());
-        int maxScrollYPix = Math.max(0, mRenderCoordinates.getMaxVerticalScrollPixInt());
-        event.setScrollable(maxScrollXPix > 0 || maxScrollYPix > 0);
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
-            event.setMaxScrollX(maxScrollXPix);
-            event.setMaxScrollY(maxScrollYPix);
-        }
-    }
-
-    /**
-     * Returns whether accessibility script injection is enabled on the device
-     */
-    public boolean isDeviceAccessibilityScriptInjectionEnabled() {
-        try {
-            // On JellyBean and higher, native accessibility is the default so script
-            // injection is only allowed if enabled via a flag.
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
-                    && !CommandLine.getInstance().hasSwitch(
-                            ContentSwitches.ENABLE_ACCESSIBILITY_SCRIPT_INJECTION)) {
-                return false;
-            }
-
-            if (!mContentViewClient.isJavascriptEnabled()) {
-                return false;
-            }
-
-            int result = getContext().checkCallingOrSelfPermission(
-                    android.Manifest.permission.INTERNET);
-            if (result != PackageManager.PERMISSION_GRANTED) {
-                return false;
-            }
-
-            Field field = Settings.Secure.class.getField("ACCESSIBILITY_SCRIPT_INJECTION");
-            field.setAccessible(true);
-            String accessibilityScriptInjection = (String) field.get(null);
-            ContentResolver contentResolver = getContext().getContentResolver();
-
-            if (mAccessibilityScriptInjectionObserver == null) {
-                ContentObserver contentObserver = new ContentObserver(new Handler()) {
-                    @Override
-                    public void onChange(boolean selfChange, Uri uri) {
-                        setAccessibilityState(mAccessibilityManager.isEnabled());
-                    }
-                };
-                contentResolver.registerContentObserver(
-                        Settings.Secure.getUriFor(accessibilityScriptInjection),
-                        false,
-                        contentObserver);
-                mAccessibilityScriptInjectionObserver = contentObserver;
-            }
-
-            return Settings.Secure.getInt(contentResolver, accessibilityScriptInjection, 0) == 1;
-        } catch (NoSuchFieldException e) {
-            // Do nothing, default to false.
-        } catch (IllegalAccessException e) {
-            // Do nothing, default to false.
-        }
-        return false;
-    }
-
-    /**
-     * Returns whether or not accessibility injection is being used.
-     */
-    public boolean isInjectingAccessibilityScript() {
-        return mAccessibilityInjector.accessibilityIsAvailable();
-    }
-
-    /**
      * Returns true if accessibility is on and touch exploration is enabled.
      */
     public boolean isTouchExplorationEnabled() {
@@ -3059,33 +2940,15 @@
      */
     public void setAccessibilityState(boolean state) {
         if (!state) {
-            setInjectedAccessibility(false);
             mNativeAccessibilityAllowed = false;
             mTouchExplorationEnabled = false;
         } else {
-            boolean useScriptInjection = isDeviceAccessibilityScriptInjectionEnabled();
-            setInjectedAccessibility(useScriptInjection);
-            mNativeAccessibilityAllowed = !useScriptInjection;
+            mNativeAccessibilityAllowed = true;
             mTouchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
         }
     }
 
     /**
-     * Enable or disable injected accessibility features
-     */
-    public void setInjectedAccessibility(boolean enabled) {
-        mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
-        mAccessibilityInjector.setScriptEnabled(enabled);
-    }
-
-    /**
-     * Stop any TTS notifications that are currently going on.
-     */
-    public void stopCurrentAccessibilityNotifications() {
-        mAccessibilityInjector.onPageLostFocus();
-    }
-
-    /**
      * Return whether or not we should set accessibility focus on page load.
      */
     public boolean shouldSetAccessibilityFocusOnPageLoad() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java b/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java
deleted file mode 100644
index 88dd3bc..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java
+++ /dev/null
@@ -1,37 +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.content.browser;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.view.accessibility.AccessibilityNodeProvider;
-
-/**
- * A version of {@link ContentView} that supports JellyBean features.
- */
-class JellyBeanContentView extends ContentView {
-    JellyBeanContentView(Context context, ContentViewCore cvc) {
-        super(context, cvc);
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (mContentViewCore.supportsAccessibilityAction(action)) {
-            return mContentViewCore.performAccessibilityAction(action, arguments);
-        }
-
-        return super.performAccessibilityAction(action, arguments);
-    }
-
-    @Override
-    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
-        AccessibilityNodeProvider provider = mContentViewCore.getAccessibilityNodeProvider();
-        if (provider != null) {
-            return provider;
-        } else {
-            return super.getAccessibilityNodeProvider();
-        }
-    }
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ServiceRegistrar.java b/content/public/android/java/src/org/chromium/content/browser/ServiceRegistrar.java
index e18b3c60..6065fa5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ServiceRegistrar.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ServiceRegistrar.java
@@ -39,4 +39,10 @@
         registry.addService(BatteryMonitor.MANAGER,
                 new BatteryMonitorImplementationFactory(applicationContext));
     }
+
+    @CalledByNative
+    static void registerFrameHostServices(ServiceRegistry registry, Context applicationContext) {
+        assert applicationContext != null;
+        // TODO(avayvod): Register the PresentationService implementation here.
+    }
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java
index 974191e..6d535cb 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java
@@ -95,7 +95,7 @@
             // Translate Android SpeechRecognizer errors to Web Speech API errors.
             switch(error) {
                 case SpeechRecognizer.ERROR_AUDIO:
-                    code = SpeechRecognitionErrorCode.AUDIO;
+                    code = SpeechRecognitionErrorCode.AUDIO_CAPTURE;
                     break;
                 case SpeechRecognizer.ERROR_CLIENT:
                     code = SpeechRecognitionErrorCode.ABORTED;
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
deleted file mode 100644
index d07c4931..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
+++ /dev/null
@@ -1,457 +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.content.browser.accessibility;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Vibrator;
-import android.speech.tts.TextToSpeech;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.chromium.base.CommandLine;
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.JavascriptInterface;
-import org.chromium.content.common.ContentSwitches;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Responsible for accessibility injection and management of a {@link ContentViewCore}.
- */
-public class AccessibilityInjector {
-    // The ContentView this injector is responsible for managing.
-    protected ContentViewCore mContentViewCore;
-
-    // The Java objects that are exposed to JavaScript
-    private TextToSpeechWrapper mTextToSpeech;
-    private VibratorWrapper mVibrator;
-    private final boolean mHasVibratePermission;
-
-    // Lazily loaded helper objects.
-    private AccessibilityManager mAccessibilityManager;
-
-    // Whether or not we should be injecting the script.
-    protected boolean mInjectedScriptEnabled;
-    protected boolean mScriptInjected;
-
-    private final String mAccessibilityScreenReaderUrl;
-
-    // To support building against the JELLY_BEAN and not JELLY_BEAN_MR1 SDK we need to add this
-    // constant here.
-    private static final int FEEDBACK_BRAILLE = 0x00000020;
-
-    // constants for determining script injection strategy
-    private static final int ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED = -1;
-    private static final int ACCESSIBILITY_SCRIPT_INJECTION_OPTED_OUT = 0;
-    private static final int ACCESSIBILITY_SCRIPT_INJECTION_PROVIDED = 1;
-    private static final String ALIAS_ACCESSIBILITY_JS_INTERFACE = "accessibility";
-    private static final String ALIAS_ACCESSIBILITY_JS_INTERFACE_2 = "accessibility2";
-
-    // Template for JavaScript that injects a screen-reader.
-    private static final String DEFAULT_ACCESSIBILITY_SCREEN_READER_URL =
-            "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);"
-            + "  })();";
-
-    // 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);"
-            + "    }"
-            + "  })();";
-
-    /**
-     * Returns an instance of the {@link AccessibilityInjector} based on the SDK version.
-     * @param view The ContentViewCore that this AccessibilityInjector manages.
-     * @return An instance of a {@link AccessibilityInjector}.
-     */
-    public static AccessibilityInjector newInstance(ContentViewCore view) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            return new LollipopAccessibilityInjector(view);
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            return new JellyBeanAccessibilityInjector(view);
-        } else {
-            return new AccessibilityInjector(view);
-        }
-    }
-
-    /**
-     * Creates an instance of the IceCreamSandwichAccessibilityInjector.
-     * @param view The ContentViewCore that this AccessibilityInjector manages.
-     */
-    protected AccessibilityInjector(ContentViewCore view) {
-        mContentViewCore = view;
-
-        mAccessibilityScreenReaderUrl = CommandLine.getInstance().getSwitchValue(
-                ContentSwitches.ACCESSIBILITY_JAVASCRIPT_URL,
-                DEFAULT_ACCESSIBILITY_SCREEN_READER_URL);
-
-        mHasVibratePermission = mContentViewCore.getContext().checkCallingOrSelfPermission(
-                android.Manifest.permission.VIBRATE) == PackageManager.PERMISSION_GRANTED;
-    }
-
-    /**
-     * Injects a <script> tag into the current web site that pulls in the ChromeVox script for
-     * accessibility support.  Only injects if accessibility is turned on by
-     * {@link AccessibilityManager#isEnabled()}, accessibility script injection is turned on, and
-     * javascript is enabled on this page.
-     *
-     * @see AccessibilityManager#isEnabled()
-     */
-    public void injectAccessibilityScriptIntoPage() {
-        if (!accessibilityIsAvailable()) return;
-
-        int axsParameterValue = getAxsUrlParameterValue();
-        if (axsParameterValue != ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED) {
-            return;
-        }
-
-        String js = getScreenReaderInjectingJs();
-        if (mContentViewCore.isDeviceAccessibilityScriptInjectionEnabled()
-                && js != null && mContentViewCore.isAlive()) {
-            addOrRemoveAccessibilityApisIfNecessary();
-            mContentViewCore.getWebContents().evaluateJavaScript(js, null);
-            mInjectedScriptEnabled = true;
-            mScriptInjected = true;
-        }
-    }
-
-    /**
-     * Handles adding or removing accessibility related Java objects ({@link TextToSpeech} and
-     * {@link Vibrator}) interfaces from Javascript.  This method should be called at a time when it
-     * is safe to add or remove these interfaces, specifically when the {@link ContentViewCore} is
-     * first initialized or right before the {@link ContentViewCore} is about to navigate to a URL
-     * or reload.
-     * <p>
-     * If this method is called at other times, the interfaces might not be correctly removed,
-     * meaning that Javascript can still access these Java objects that may have been already
-     * shut down.
-     */
-    public void addOrRemoveAccessibilityApisIfNecessary() {
-        if (accessibilityIsAvailable()) {
-            addAccessibilityApis();
-        } else {
-            removeAccessibilityApis();
-        }
-    }
-
-    /**
-     * Checks whether or not touch to explore is enabled on the system.
-     */
-    public boolean accessibilityIsAvailable() {
-        if (!getAccessibilityManager().isEnabled()
-                || !mContentViewCore.getContentViewClient().isJavascriptEnabled()) {
-            return false;
-        }
-
-        try {
-            // Check that there is actually a service running that requires injecting this script.
-            List<AccessibilityServiceInfo> services =
-                    getAccessibilityManager().getEnabledAccessibilityServiceList(
-                            FEEDBACK_BRAILLE | AccessibilityServiceInfo.FEEDBACK_SPOKEN);
-            return services.size() > 0;
-        } catch (NullPointerException e) {
-            // getEnabledAccessibilityServiceList() can throw an NPE due to a bad
-            // AccessibilityService.
-            return false;
-        }
-    }
-
-    /**
-     * Sets whether or not the script is enabled.  If the script is disabled, we also stop any
-     * we output that is occurring. If the script has not yet been injected, injects it.
-     * @param enabled Whether or not to enable the script.
-     */
-    public void setScriptEnabled(boolean enabled) {
-        if (enabled && !mScriptInjected) injectAccessibilityScriptIntoPage();
-        if (!accessibilityIsAvailable() || mInjectedScriptEnabled == enabled) return;
-
-        mInjectedScriptEnabled = enabled;
-        if (mContentViewCore.isAlive()) {
-            String js = String.format(TOGGLE_CHROME_VOX_JAVASCRIPT, Boolean.toString(
-                    mInjectedScriptEnabled));
-            mContentViewCore.getWebContents().evaluateJavaScript(js, null);
-
-            if (!mInjectedScriptEnabled) {
-                // Stop any TTS/Vibration right now.
-                onPageLostFocus();
-            }
-        }
-    }
-
-    /**
-     * Notifies this handler that a page load has started, which means we should mark the
-     * accessibility script as not being injected.  This way we can properly ignore incoming
-     * accessibility gesture events.
-     */
-    public void onPageLoadStarted() {
-        mScriptInjected = false;
-    }
-
-    /**
-     * Notifies this handler that a page load has stopped, which means we can now inject the
-     * accessibility script.
-     */
-    public void onPageLoadStopped() {
-        injectAccessibilityScriptIntoPage();
-    }
-
-    /**
-     * Stop any notifications that are currently going on (e.g. Text-to-Speech).
-     */
-    public void onPageLostFocus() {
-        if (mContentViewCore.isAlive()) {
-            if (mTextToSpeech != null) mTextToSpeech.stop();
-            if (mVibrator != null) mVibrator.cancel();
-        }
-    }
-
-    /**
-     * Initializes an {@link AccessibilityNodeInfo} with the actions and movement granularity
-     * levels supported by this {@link AccessibilityInjector}.
-     * <p>
-     * If an action identifier is added in this method, this {@link AccessibilityInjector} should
-     * also return {@code true} from {@link #supportsAccessibilityAction(int)}.
-     * </p>
-     *
-     * @param info The info to initialize.
-     * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
-     */
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { }
-
-    /**
-     * Returns {@code true} if this {@link AccessibilityInjector} should handle the specified
-     * action.
-     *
-     * @param action An accessibility action identifier.
-     * @return {@code true} if this {@link AccessibilityInjector} should handle the specified
-     *         action.
-     */
-    public boolean supportsAccessibilityAction(int action) {
-        return false;
-    }
-
-    /**
-     * Performs the specified accessibility action.
-     *
-     * @param action The identifier of the action to perform.
-     * @param arguments The action arguments, or {@code null} if no arguments.
-     * @return {@code true} if the action was successful.
-     * @see View#performAccessibilityAction(int, Bundle)
-     */
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        return false;
-    }
-
-    protected void addAccessibilityApis() {
-        Context context = mContentViewCore.getContext();
-        if (context != null) {
-            // Enabled, we should try to add if we have to.
-            if (mTextToSpeech == null) {
-                mTextToSpeech = createTextToSpeechWrapper(mContentViewCore.getContainerView(),
-                        context);
-                mContentViewCore.addJavascriptInterface(mTextToSpeech,
-                        ALIAS_ACCESSIBILITY_JS_INTERFACE);
-            }
-
-            if (mVibrator == null && mHasVibratePermission) {
-                mVibrator = new VibratorWrapper(context);
-                mContentViewCore.addJavascriptInterface(mVibrator,
-                        ALIAS_ACCESSIBILITY_JS_INTERFACE_2);
-            }
-        }
-    }
-
-    protected void removeAccessibilityApis() {
-        if (mTextToSpeech != null) {
-            mContentViewCore.removeJavascriptInterface(ALIAS_ACCESSIBILITY_JS_INTERFACE);
-            mTextToSpeech.stop();
-            mTextToSpeech.shutdownInternal();
-            mTextToSpeech = null;
-        }
-
-        if (mVibrator != null) {
-            mContentViewCore.removeJavascriptInterface(ALIAS_ACCESSIBILITY_JS_INTERFACE_2);
-            mVibrator.cancel();
-            mVibrator = null;
-        }
-    }
-
-    private int getAxsUrlParameterValue() {
-        if (mContentViewCore.getWebContents().getUrl() == null) {
-            return ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED;
-        }
-
-        try {
-            List<NameValuePair> params = URLEncodedUtils.parse(
-                    new URI(mContentViewCore.getWebContents().getUrl()), null);
-
-            for (NameValuePair param : params) {
-                if ("axs".equals(param.getName())) {
-                    return Integer.parseInt(param.getValue());
-                }
-            }
-        } catch (URISyntaxException ex) {
-            // Intentional no-op.
-        } catch (NumberFormatException ex) {
-            // Intentional no-op.
-        } catch (IllegalArgumentException ex) {
-            // Intentional no-op.
-        }
-
-        return ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED;
-    }
-
-    private String getScreenReaderInjectingJs() {
-        return String.format(ACCESSIBILITY_SCREEN_READER_JAVASCRIPT_TEMPLATE,
-                mAccessibilityScreenReaderUrl);
-    }
-
-    private AccessibilityManager getAccessibilityManager() {
-        if (mAccessibilityManager == null) {
-            mAccessibilityManager = (AccessibilityManager) mContentViewCore.getContext()
-                    .getSystemService(Context.ACCESSIBILITY_SERVICE);
-        }
-
-        return mAccessibilityManager;
-    }
-
-    /**
-     * Used to protect how long JavaScript can vibrate for.  This isn't a good comprehensive
-     * protection, just used to cover mistakes and protect against long vibrate durations/repeats.
-     *
-     * Also only exposes methods we *want* to expose, no others for the class.
-     */
-    private static class VibratorWrapper {
-        private static final long MAX_VIBRATE_DURATION_MS = 5000;
-
-        private final Vibrator mVibrator;
-
-        public VibratorWrapper(Context context) {
-            mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public boolean hasVibrator() {
-            return mVibrator.hasVibrator();
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public void vibrate(long milliseconds) {
-            milliseconds = Math.min(milliseconds, MAX_VIBRATE_DURATION_MS);
-            mVibrator.vibrate(milliseconds);
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public void vibrate(long[] pattern, int repeat) {
-            for (int i = 0; i < pattern.length; ++i) {
-                pattern[i] = Math.min(pattern[i], MAX_VIBRATE_DURATION_MS);
-            }
-
-            repeat = -1;
-
-            mVibrator.vibrate(pattern, repeat);
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public void cancel() {
-            mVibrator.cancel();
-        }
-    }
-
-    protected TextToSpeechWrapper createTextToSpeechWrapper(View view, Context context) {
-        return new TextToSpeechWrapper(view, context);
-    }
-
-    /**
-     * Used to protect the TextToSpeech class, only exposing the methods we want to expose.
-     */
-    protected static class TextToSpeechWrapper {
-        protected final TextToSpeech mTextToSpeech;
-        private final View mView;
-
-        protected TextToSpeechWrapper(View view, Context context) {
-            mView = view;
-            mTextToSpeech = new TextToSpeech(context, null, null);
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public boolean isSpeaking() {
-            return mTextToSpeech.isSpeaking();
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings({"unused", "deprecation"})
-        public int speak(String text, int queueMode, String jsonParams) {
-            // Try to pull the params from the JSON string.
-            HashMap<String, String> params = null;
-            try {
-                if (jsonParams != null) {
-                    params = new HashMap<String, String>();
-                    JSONObject json = new JSONObject(jsonParams);
-
-                    // Using legacy API here.
-                    @SuppressWarnings("unchecked")
-                    Iterator<String> keyIt = json.keys();
-
-                    while (keyIt.hasNext()) {
-                        String key = keyIt.next();
-                        // Only add parameters that are raw data types.
-                        if (json.optJSONObject(key) == null && json.optJSONArray(key) == null) {
-                            params.put(key, json.getString(key));
-                        }
-                    }
-                }
-            } catch (JSONException e) {
-                params = null;
-            }
-
-            return mTextToSpeech.speak(text, queueMode, params);
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public int stop() {
-            return mTextToSpeech.stop();
-        }
-
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public void braille(String jsonString) {
-            // This is here because AndroidVox depends on the existence
-            // of this method.
-        }
-
-        @SuppressWarnings("unused")
-        protected void shutdownInternal() {
-            mTextToSpeech.shutdown();
-        }
-    }
-}
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
deleted file mode 100644
index 67b4dca..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
+++ /dev/null
@@ -1,268 +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.content.browser.accessibility;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.JavascriptInterface;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Handles injecting accessibility Javascript and related Javascript -> Java APIs for JB and newer
- * devices.
- */
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
-class JellyBeanAccessibilityInjector extends AccessibilityInjector {
-    private CallbackHandler mCallback;
-    private JSONObject mAccessibilityJSONObject;
-
-    private static final String ALIAS_TRAVERSAL_JS_INTERFACE = "accessibilityTraversal";
-
-    // Template for JavaScript that performs AndroidVox actions.
-    private static final String ACCESSIBILITY_ANDROIDVOX_TEMPLATE =
-            "cvox.AndroidVox.performAction('%1s')";
-
-    /**
-     * Constructs an instance of the JellyBeanAccessibilityInjector.
-     * @param view The ContentViewCore that this AccessibilityInjector manages.
-     */
-    protected JellyBeanAccessibilityInjector(ContentViewCore view) {
-        super(view);
-    }
-
-    @Override
-    @SuppressWarnings("deprecation")
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-        info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
-        info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
-        info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
-        info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
-        info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
-        info.setClickable(true);
-    }
-
-    @Override
-    public boolean supportsAccessibilityAction(int action) {
-        if (action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                || action == AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                || action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT
-                || action == AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT
-                || action == AccessibilityNodeInfo.ACTION_CLICK) {
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (!accessibilityIsAvailable() || !mContentViewCore.isAlive()
-                || !mInjectedScriptEnabled || !mScriptInjected) {
-            return false;
-        }
-
-        boolean actionSuccessful = sendActionToAndroidVox(action, arguments);
-
-        if (actionSuccessful) mContentViewCore.getWebContents().showImeIfNeeded();
-
-        return actionSuccessful;
-    }
-
-    @Override
-    protected void addAccessibilityApis() {
-        super.addAccessibilityApis();
-
-        Context context = mContentViewCore.getContext();
-        if (context != null && mCallback == null) {
-            mCallback = new CallbackHandler(ALIAS_TRAVERSAL_JS_INTERFACE);
-            mContentViewCore.addJavascriptInterface(mCallback, ALIAS_TRAVERSAL_JS_INTERFACE);
-        }
-    }
-
-    @Override
-    protected void removeAccessibilityApis() {
-        super.removeAccessibilityApis();
-
-        if (mCallback != null) {
-            mContentViewCore.removeJavascriptInterface(ALIAS_TRAVERSAL_JS_INTERFACE);
-            mCallback = null;
-        }
-    }
-
-    /**
-     * Packs an accessibility action into a JSON object and sends it to AndroidVox.
-     *
-     * @param action The action identifier.
-     * @param arguments The action arguments, if applicable.
-     * @return The result of the action.
-     */
-    private boolean sendActionToAndroidVox(int action, Bundle arguments) {
-        if (mCallback == null) return false;
-        if (mAccessibilityJSONObject == null) {
-            mAccessibilityJSONObject = new JSONObject();
-        } else {
-            // Remove all keys from the object.
-            final Iterator<?> keys = mAccessibilityJSONObject.keys();
-            while (keys.hasNext()) {
-                keys.next();
-                keys.remove();
-            }
-        }
-
-        try {
-            mAccessibilityJSONObject.accumulate("action", action);
-            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);
-                    mAccessibilityJSONObject.accumulate("granularity", granularity);
-                } else if (action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT
-                        || action == AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT) {
-                    final String element = arguments.getString(
-                            AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
-                    mAccessibilityJSONObject.accumulate("element", element);
-                }
-            }
-        } catch (JSONException ex) {
-            return false;
-        }
-
-        final String jsonString = mAccessibilityJSONObject.toString();
-        final String jsCode = String.format(Locale.US, ACCESSIBILITY_ANDROIDVOX_TEMPLATE,
-                jsonString);
-        return mCallback.performAction(mContentViewCore, jsCode);
-    }
-
-    private static class CallbackHandler {
-        private static final String JAVASCRIPT_ACTION_TEMPLATE = "(function() {"
-                + "  retVal = false;"
-                + "  try {"
-                + "    retVal = %s;"
-                + "  } catch (e) {"
-                + "    retVal = false;"
-                + "  }"
-                + "  %s.onResult(%d, retVal);"
-                + "})()";
-
-        // Time in milliseconds to wait for a result before failing.
-        private static final long RESULT_TIMEOUT = 5000;
-
-        private final AtomicInteger mResultIdCounter = new AtomicInteger();
-        private final Object mResultLock = new Object();
-        private final String mInterfaceName;
-
-        private boolean mResult = false;
-        private long mResultId = -1;
-
-        private CallbackHandler(String interfaceName) {
-            mInterfaceName = interfaceName;
-        }
-
-        /**
-         * Performs an action and attempts to wait for a result.
-         *
-         * @param contentView The ContentViewCore to perform the action on.
-         * @param code Javascript code that evaluates to a result.
-         * @return The result of the action.
-         */
-        private boolean performAction(ContentViewCore contentView, String code) {
-            final int resultId = mResultIdCounter.getAndIncrement();
-            final String js = String.format(Locale.US, JAVASCRIPT_ACTION_TEMPLATE, code,
-                    mInterfaceName, resultId);
-            contentView.getWebContents().evaluateJavaScript(js, null);
-
-            return getResultAndClear(resultId);
-        }
-
-        /**
-         * Gets the result of a request to perform an accessibility action.
-         *
-         * @param resultId The result id to match the result with the request.
-         * @return The result of the request.
-         */
-        private boolean getResultAndClear(int resultId) {
-            synchronized (mResultLock) {
-                final boolean success = waitForResultTimedLocked(resultId);
-                final boolean result = success ? mResult : false;
-                clearResultLocked();
-                return result;
-            }
-        }
-
-        /**
-         * Clears the result state.
-         */
-        private void clearResultLocked() {
-            mResultId = -1;
-            mResult = false;
-        }
-
-        /**
-         * Waits up to a given bound for a result of a request and returns it.
-         *
-         * @param resultId The result id to match the result with the request.
-         * @return Whether the result was received.
-         */
-        private boolean waitForResultTimedLocked(int resultId) {
-            long waitTimeMillis = RESULT_TIMEOUT;
-            final long startTimeMillis = SystemClock.uptimeMillis();
-            while (true) {
-                try {
-                    if (mResultId == resultId) return true;
-                    if (mResultId > resultId) return false;
-                    final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                    waitTimeMillis = RESULT_TIMEOUT - elapsedTimeMillis;
-                    if (waitTimeMillis <= 0) return false;
-                    mResultLock.wait(waitTimeMillis);
-                } catch (InterruptedException ie) {
-                    /* ignore */
-                }
-            }
-        }
-
-        /**
-         * Callback exposed to JavaScript.  Handles returning the result of a
-         * request to a waiting (or potentially timed out) thread.
-         *
-         * @param id The result id of the request as a {@link String}.
-         * @param result The result of a request as a {@link String}.
-         */
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public void onResult(String id, String result) {
-            final long resultId;
-            try {
-                resultId = Long.parseLong(id);
-            } catch (NumberFormatException e) {
-                return;
-            }
-
-            synchronized (mResultLock) {
-                if (resultId > mResultId) {
-                    mResult = Boolean.parseBoolean(result);
-                    mResultId = resultId;
-                }
-                mResultLock.notifyAll();
-            }
-        }
-    }
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java
deleted file mode 100644
index d7737eb5..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java
+++ /dev/null
@@ -1,93 +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.content.browser.accessibility;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.JavascriptInterface;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.Iterator;
-
-/**
- * Handles injecting accessibility Javascript and related Javascript -> Java APIs for Lollipop and
- * newer devices.
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-class LollipopAccessibilityInjector extends JellyBeanAccessibilityInjector {
-    /**
-     * Constructs an instance of the LollipopAccessibilityInjector.
-     * @param view The ContentViewCore that this AccessibilityInjector manages.
-     */
-    protected LollipopAccessibilityInjector(ContentViewCore view) {
-        super(view);
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        info.setMovementGranularities(
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-        info.addAction(
-                AccessibilityNodeInfo.AccessibilityAction.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
-        info.addAction(
-                AccessibilityNodeInfo.AccessibilityAction.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_NEXT_HTML_ELEMENT);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_PREVIOUS_HTML_ELEMENT);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
-        info.setClickable(true);
-    }
-
-    @Override
-    protected TextToSpeechWrapper createTextToSpeechWrapper(View view, Context context) {
-        return new LTextToSpeechWrapper(view, context);
-    }
-
-    protected static class LTextToSpeechWrapper extends AccessibilityInjector.TextToSpeechWrapper {
-        private LTextToSpeechWrapper(View view, Context context) {
-            super(view, context);
-        }
-
-        @Override
-        @JavascriptInterface
-        @SuppressWarnings("unused")
-        public int speak(String text, int queueMode, String jsonParams) {
-            // Try to pull the params from the JSON string.
-            Bundle bundle = null;
-            try {
-                if (jsonParams != null) {
-                    bundle = new Bundle();
-                    JSONObject json = new JSONObject(jsonParams);
-
-                    // Using legacy API here.
-                    @SuppressWarnings("unchecked")
-                    Iterator<String> keyIt = json.keys();
-
-                    while (keyIt.hasNext()) {
-                        String key = keyIt.next();
-                        // Only add parameters that are raw data types.
-                        if (json.optJSONObject(key) == null && json.optJSONArray(key) == null) {
-                            bundle.putCharSequence(key, json.getString(key));
-                        }
-                    }
-                }
-            } catch (JSONException e) {
-                bundle = null;
-            }
-
-            return mTextToSpeech.speak(text, queueMode, bundle, null);
-        }
-    }
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/EmptyCaptioningBridge.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/EmptyCaptioningBridge.java
index da25683..8ae257f9 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/EmptyCaptioningBridge.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/EmptyCaptioningBridge.java
@@ -12,10 +12,18 @@
     /**
      * A no-op implementation of the syncToDelegate function.
      */
+    @Override
     public void syncToDelegate() {}
 
     /**
-     * A no-op implementation of the destroy function.
+     * No-op implementation of registerBridge.
      */
-    public void destroy() {}
+    @Override
+    public void registerBridge() {}
+
+    /**
+     * A no-op implementation of the unregisterBridge function.
+     */
+    @Override
+    public void unregisterBridge() {}
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/KitKatCaptioningBridge.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/KitKatCaptioningBridge.java
index 73feeea..04b16e8 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/KitKatCaptioningBridge.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/KitKatCaptioningBridge.java
@@ -63,13 +63,12 @@
         mCaptioningManager = (CaptioningManager) contenViewCore.getContext()
                                      .getApplicationContext()
                                      .getSystemService(Context.CAPTIONING_SERVICE);
-        mCaptioningManager.addCaptioningChangeListener(mCaptioningChangeListener);
-        syncToDelegate();
     }
 
     /**
      * Force-sync the current closed caption settings to the delegate
      */
+    @Override
     public void syncToDelegate() {
         mCaptioningChangeDelegate.onEnabledChanged(mCaptioningManager.isEnabled());
         mCaptioningChangeDelegate.onFontScaleChanged(mCaptioningManager.getFontScale());
@@ -79,10 +78,19 @@
     }
 
     /**
-     * De-register this bridge from the system captioning manager. This bridge
-     * should not be used again after this is called.
+     * Register this bridge for event changes with the system CaptioningManager.
      */
-    public void destroy() {
+    @Override
+    public void registerBridge() {
+        mCaptioningManager.addCaptioningChangeListener(mCaptioningChangeListener);
+        syncToDelegate();
+    }
+
+    /**
+     * De-register this bridge from the system captioning manager.
+     */
+    @Override
+    public void unregisterBridge() {
         mCaptioningManager.removeCaptioningChangeListener(mCaptioningChangeListener);
     }
 
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java
index 55eb5afb..c640622d 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java
@@ -14,8 +14,12 @@
     public void syncToDelegate();
 
     /**
-     * Removes any external listeners that were added. This implementation doesn't do anything.
-     * After destroy is called, this object should not be used again.
+     * Register this bridge for event changes with the system CaptioningManager.
      */
-    public void destroy();
+    public void registerBridge();
+
+    /**
+     * Unregister this bridge from system CaptionManager. Must be called to avoid leaks.
+     */
+    public void unregisterBridge();
 }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java
index 6b74559a..145ed5a9 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java
@@ -17,14 +17,14 @@
 public class ContentCommandLineTest extends NativeLibraryTestBase {
     // A reference command line. Note that switch2 is [brea\d], switch3 is [and "butter"],
     // and switch4 is [a "quoted" 'food'!]
-    static final String INIT_SWITCHES[] = { "init_command", "--SWITCH", "Arg",
+    static final String INIT_SWITCHES[] = { "init_command", "--switch", "Arg",
         "--switch2=brea\\d", "--switch3=and \"butter\"",
         "--switch4=a \"quoted\" 'food'!",
         "--", "--actually_an_arg" };
 
     // The same command line, but in quoted string format.
     static final char INIT_SWITCHES_BUFFER[] =
-        ("init_command --SWITCH Arg --switch2=brea\\d --switch3=\"and \\\"butt\"er\\\"   "
+        ("init_command --switch Arg --switch2=brea\\d --switch3=\"and \\\"butt\"er\\\"   "
         + "--switch4='a \"quoted\" \\'food\\'!' "
         + "-- --actually_an_arg").toCharArray();
 
@@ -46,15 +46,14 @@
     void checkInitSwitches() {
         CommandLine cl = CommandLine.getInstance();
         assertFalse(cl.hasSwitch("init_command"));
-        assertFalse(cl.hasSwitch("switch"));
-        assertTrue(cl.hasSwitch("SWITCH"));
-        assertFalse(cl.hasSwitch("--SWITCH"));
-        assertFalse(cl.hasSwitch("Arg"));
+        assertTrue(cl.hasSwitch("switch"));
+        assertFalse(cl.hasSwitch("--switch"));
+        assertFalse(cl.hasSwitch("arg"));
         assertFalse(cl.hasSwitch("actually_an_arg"));
         assertEquals("brea\\d", cl.getSwitchValue("switch2"));
         assertEquals("and \"butter\"", cl.getSwitchValue("switch3"));
         assertEquals("a \"quoted\" 'food'!", cl.getSwitchValue("switch4"));
-        assertNull(cl.getSwitchValue("SWITCH"));
+        assertNull(cl.getSwitchValue("switch"));
         assertNull(cl.getSwitchValue("non-existant"));
     }
 
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/GamepadMappingsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/GamepadMappingsTest.java
deleted file mode 100644
index 5ae486d5..0000000
--- a/content/public/android/javatests/src/org/chromium/content/browser/input/GamepadMappingsTest.java
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.content.browser.input;
-
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import org.chromium.base.test.util.Feature;
-
-import java.util.Arrays;
-import java.util.BitSet;
-
-/**
- * Verify no regressions in gamepad mappings.
- */
-public class GamepadMappingsTest extends InstrumentationTestCase {
-    /**
-     * Set bits indicate that we don't expect the button at mMappedButtons[index] to be mapped.
-     */
-    private BitSet mUnmappedButtons = new BitSet(CanonicalButtonIndex.COUNT);
-    /**
-     * Set bits indicate that we don't expect the axis at mMappedAxes[index] to be mapped.
-     */
-    private BitSet mUnmappedAxes = new BitSet(CanonicalAxisIndex.COUNT);
-    private float[] mMappedButtons = new float[CanonicalButtonIndex.COUNT];
-    private float[] mMappedAxes = new float[CanonicalAxisIndex.COUNT];
-    private float[] mRawButtons = new float[GamepadDevice.MAX_RAW_BUTTON_VALUES];
-    private float[] mRawAxes = new float[GamepadDevice.MAX_RAW_AXIS_VALUES];
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        // By default, we expect every button and axis to be mapped.
-        mUnmappedButtons.clear();
-        mUnmappedAxes.clear();
-
-        // Start with all the mapped values as unmapped.
-        Arrays.fill(mMappedButtons, Float.NaN);
-        Arrays.fill(mMappedAxes, Float.NaN);
-
-        // Set each raw value to something unique.
-        for (int i = 0; i < GamepadDevice.MAX_RAW_AXIS_VALUES; i++) {
-            mRawAxes[i] = -i - 1.0f;
-        }
-        for (int i = 0; i < GamepadDevice.MAX_RAW_BUTTON_VALUES; i++) {
-            mRawButtons[i] = i + 1.0f;
-        }
-    }
-
-    @SmallTest
-    @Feature({"Gamepad"})
-    public void testShieldGamepadMappings() throws Exception {
-        GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
-                GamepadMappings.NVIDIA_SHIELD_DEVICE_NAME_PREFIX);
-
-        assertShieldGamepadMappings();
-    }
-
-    @SmallTest
-    @Feature({"Gamepad"})
-    public void testXBox360GamepadMappings() throws Exception {
-        GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
-                GamepadMappings.MICROSOFT_XBOX_PAD_DEVICE_NAME);
-
-        assertShieldGamepadMappings();
-    }
-
-    @SmallTest
-    @Feature({"Gamepad"})
-    public void testPS3SixAxisGamepadMappings() throws Exception {
-        GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
-                GamepadMappings.PS3_SIXAXIS_DEVICE_NAME);
-
-        assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_X]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_Y]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_A]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_B]);
-
-        assertMappedCommonTriggerButtons();
-        assertMappedCommonThumbstickButtons();
-        assertMappedCommonDpadButtons();
-        assertMappedCommonStartSelectMetaButtons();
-        assertMappedTriggerAxexToShoulderButtons();
-        assertMappedXYAxes();
-        assertMappedZAndRZAxesToRightStick();
-
-        assertMapping();
-    }
-
-    @SmallTest
-    @Feature({"Gamepad"})
-    public void testSamsungEIGP20GamepadMappings() throws Exception {
-        GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
-                GamepadMappings.SAMSUNG_EI_GP20_DEVICE_NAME);
-
-        assertMappedCommonXYABButtons();
-        assertMappedCommonTriggerButtons();
-        assertMappedCommonThumbstickButtons();
-        assertMappedCommonStartSelectMetaButtons();
-        assertMappedHatAxisToDpadButtons();
-        assertMappedXYAxes();
-        assertMappedRXAndRYAxesToRightStick();
-
-        expectNoShoulderButtons();
-        assertMapping();
-    }
-
-    @SmallTest
-    @Feature({"Gamepad"})
-    public void testAmazonFireGamepadMappings() throws Exception {
-        GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
-                GamepadMappings.AMAZON_FIRE_DEVICE_NAME);
-
-        assertMappedCommonXYABButtons();
-        assertMappedPedalAxesToBottomShoulder();
-        assertMappedCommonThumbstickButtons();
-        assertMappedCommonStartSelectMetaButtons();
-        assertMappedTriggerButtonsToTopShoulder();
-        assertMappedHatAxisToDpadButtons();
-        assertMappedXYAxes();
-        assertMappedZAndRZAxesToRightStick();
-
-        assertMapping();
-    }
-
-    @SmallTest
-    @Feature({"Gamepad"})
-    public void testUnknownGamepadMappings() throws Exception {
-        GamepadMappings.mapToStandardGamepad(
-                mMappedAxes, mMappedButtons, mRawAxes, mRawButtons, "");
-
-        assertMappedCommonXYABButtons();
-        assertMappedCommonTriggerButtons();
-        assertMappedCommonThumbstickButtons();
-        assertMappedCommonStartSelectMetaButtons();
-        assertMappedTriggerAxexToShoulderButtons();
-        assertMappedCommonDpadButtons();
-        assertMappedXYAxes();
-        assertMappedRXAndRYAxesToRightStick();
-
-        assertMapping();
-    }
-
-    /**
-     * Asserts that the current gamepad mapping being tested matches the shield mappings.
-     */
-    public void assertShieldGamepadMappings() {
-        assertMappedCommonXYABButtons();
-        assertMappedTriggerButtonsToTopShoulder();
-        assertMappedCommonThumbstickButtons();
-        assertMappedCommonStartSelectMetaButtons();
-        assertMappedTriggerAxesToBottomShoulder();
-        assertMappedHatAxisToDpadButtons();
-        assertMappedXYAxes();
-        assertMappedZAndRZAxesToRightStick();
-
-        assertMapping();
-    }
-
-    public void expectNoShoulderButtons() {
-        mUnmappedButtons.set(CanonicalButtonIndex.LEFT_SHOULDER);
-        mUnmappedButtons.set(CanonicalButtonIndex.RIGHT_SHOULDER);
-    }
-
-    public void assertMapping() {
-        for (int i = 0; i < mMappedAxes.length; i++) {
-            if (mUnmappedAxes.get(i)) {
-                assertTrue(
-                        "An unexpected axis was mapped at index " + i, Float.isNaN(mMappedAxes[i]));
-            } else {
-                assertFalse("An axis was not mapped at index " + i, Float.isNaN(mMappedAxes[i]));
-            }
-        }
-        for (int i = 0; i < mMappedButtons.length; i++) {
-            if (mUnmappedButtons.get(i)) {
-                assertTrue("An unexpected button was mapped at index " + i,
-                        Float.isNaN(mMappedButtons[i]));
-            } else {
-                assertFalse(
-                        "A button was not mapped at index " + i, Float.isNaN(mMappedButtons[i]));
-            }
-        }
-    }
-
-    private void assertMappedCommonTriggerButtons() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_L1]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_R1]);
-    }
-
-    private void assertMappedCommonDpadButtons() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_DOWN],
-                mRawButtons[KeyEvent.KEYCODE_DPAD_DOWN]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_UP],
-                mRawButtons[KeyEvent.KEYCODE_DPAD_UP]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_LEFT],
-                mRawButtons[KeyEvent.KEYCODE_DPAD_LEFT]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_RIGHT],
-                mRawButtons[KeyEvent.KEYCODE_DPAD_RIGHT]);
-    }
-
-    private void assertMappedTriggerAxexToShoulderButtons() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
-                mRawAxes[MotionEvent.AXIS_LTRIGGER]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
-                mRawAxes[MotionEvent.AXIS_RTRIGGER]);
-    }
-
-    private void assertMappedTriggerButtonsToTopShoulder() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_L1]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_R1]);
-    }
-
-    private void assertMappedCommonXYABButtons() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_A]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_B]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_X]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_Y]);
-    }
-
-    private void assertMappedCommonThumbstickButtons() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_THUMBSTICK],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_THUMBL]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_THUMBSTICK],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_THUMBR]);
-    }
-
-    private void assertMappedCommonStartSelectMetaButtons() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.START],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_START]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.BACK_SELECT],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_SELECT]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.META],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_MODE]);
-    }
-
-    private void assertMappedPedalAxesToBottomShoulder() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
-                mRawAxes[MotionEvent.AXIS_BRAKE]);
-        assertEquals(
-                mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER], mRawAxes[MotionEvent.AXIS_GAS]);
-    }
-
-    private void assertMappedTriggerAxesToBottomShoulder() {
-        assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
-                mRawAxes[MotionEvent.AXIS_LTRIGGER]);
-        assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
-                mRawAxes[MotionEvent.AXIS_RTRIGGER]);
-    }
-
-    private void assertMappedHatAxisToDpadButtons() {
-        float hatX = mRawAxes[MotionEvent.AXIS_HAT_X];
-        float hatY = mRawAxes[MotionEvent.AXIS_HAT_Y];
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_LEFT],
-                GamepadMappings.negativeAxisValueAsButton(hatX));
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_RIGHT],
-                GamepadMappings.positiveAxisValueAsButton(hatX));
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_UP],
-                GamepadMappings.negativeAxisValueAsButton(hatY));
-        assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_DOWN],
-                GamepadMappings.positiveAxisValueAsButton(hatY));
-    }
-
-    private void assertMappedXYAxes() {
-        assertEquals(mMappedAxes[CanonicalAxisIndex.LEFT_STICK_X], mRawAxes[MotionEvent.AXIS_X]);
-        assertEquals(mMappedAxes[CanonicalAxisIndex.LEFT_STICK_Y], mRawAxes[MotionEvent.AXIS_Y]);
-    }
-
-    private void assertMappedRXAndRYAxesToRightStick() {
-        assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_X], mRawAxes[MotionEvent.AXIS_RX]);
-        assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_Y], mRawAxes[MotionEvent.AXIS_RY]);
-    }
-
-    private void assertMappedZAndRZAxesToRightStick() {
-        assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_X], mRawAxes[MotionEvent.AXIS_Z]);
-        assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_Y], mRawAxes[MotionEvent.AXIS_RZ]);
-    }
-}
diff --git a/content/public/browser/push_messaging_service.cc b/content/public/browser/push_messaging_service.cc
index 061af7ad..27335eb 100644
--- a/content/public/browser/push_messaging_service.cc
+++ b/content/public/browser/push_messaging_service.cc
@@ -50,7 +50,7 @@
     const std::string& key,
     const PushMessagingService::StringCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  service_worker_context_wrapper->context()->storage()->GetUserData(
+  service_worker_context_wrapper->GetRegistrationUserData(
       service_worker_registration_id, key,
       base::Bind(&CallStringCallbackFromIO, callback));
 }
@@ -61,7 +61,7 @@
     const std::string& data,
     const PushMessagingService::ResultCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  service_worker_context_wrapper->context()->storage()->StoreUserData(
+  service_worker_context_wrapper->StoreRegistrationUserData(
       service_worker_registration_id, origin,
       kNotificationsShownServiceWorkerKey, data,
       base::Bind(&CallResultCallbackFromIO, callback));
@@ -73,7 +73,7 @@
     const base::Closure& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  service_worker_context->context()->storage()->ClearUserData(
+  service_worker_context->ClearRegistrationUserData(
       service_worker_registration_id,
       kPushRegistrationIdServiceWorkerKey,
       base::Bind(&CallClosureFromIO, callback));
diff --git a/content/public/browser/ssl_host_state_delegate.h b/content/public/browser/ssl_host_state_delegate.h
index 4666471..39589a5 100644
--- a/content/public/browser/ssl_host_state_delegate.h
+++ b/content/public/browser/ssl_host_state_delegate.h
@@ -54,6 +54,16 @@
   virtual bool DidHostRunInsecureContent(const std::string& host,
                                          int pid) const = 0;
 
+  // Revokes all SSL certificate error allow exceptions made by the user for
+  // |host|.
+  virtual void RevokeUserAllowExceptions(const std::string& host) = 0;
+
+  // Returns whether the user has allowed a certificate error exception for
+  // |host|. This does not mean that *all* certificate errors are allowed, just
+  // that there exists an exception. To see if a particular certificate and
+  // error combination exception is allowed, use QueryPolicy().
+  virtual bool HasAllowException(const std::string& host) const = 0;
+
  protected:
   virtual ~SSLHostStateDelegate() {}
 };
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index f9b5801..6672723 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -91,10 +91,6 @@
 // features.
 const char kDisableBlinkFeatures[]          = "disable-blink-features";
 
-// Disable the Blink Scheduler. Ensures there's no reordering of blink tasks.
-// This switch is intended only for performance tests.
-const char kDisableBlinkScheduler[]         = "disable-blink-scheduler";
-
 // Disable the creation of compositing layers when it would prevent LCD text.
 const char kDisablePreferCompositingToLCDText[] =
     "disable-prefer-compositing-to-lcd-text";
@@ -907,12 +903,6 @@
 // Override the maximum framerate as can be specified in calls to getUserMedia.
 // This flag expects a value.  Example: --max-gum-fps=17.5
 const char kWebRtcMaxCaptureFramerate[]     = "max-gum-fps";
-
-#if defined(OS_LINUX) || defined(OS_MACOSX)
-// Enables Video Capture Device captured data uploaded to Texture for zero-copy
-// capture pipeline.
-const char kEnableWebRtcCaptureToTexture[] = "enable-webrtc-capture-to-texture";
-#endif
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index c72322a..a183e70e 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -36,7 +36,6 @@
 CONTENT_EXPORT extern const char kDisableAcceleratedJpegDecoding[];
 CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[];
 extern const char kDisableBackingStoreLimit[];
-CONTENT_EXPORT extern const char kDisableBlinkScheduler[];
 CONTENT_EXPORT extern const char kDisablePreferCompositingToLCDText[];
 CONTENT_EXPORT extern const char kDisableDatabases[];
 CONTENT_EXPORT extern const char kDisableDelegatedRenderer[];
@@ -252,9 +251,6 @@
 CONTENT_EXPORT extern const char kEnableWebRtcHWH264Encoding[];
 CONTENT_EXPORT extern const char kEnableWebRtcStunOrigin[];
 extern const char kWebRtcMaxCaptureFramerate[];
-#if defined(OS_LINUX) || defined(OS_MACOSX)
-CONTENT_EXPORT extern const char kEnableWebRtcCaptureToTexture[];
-#endif
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/content/public/common/speech_recognition_error.h b/content/public/common/speech_recognition_error.h
index bbd73c7..7456a43 100644
--- a/content/public/common/speech_recognition_error.h
+++ b/content/public/common/speech_recognition_error.h
@@ -14,11 +14,14 @@
   // There was no error.
   SPEECH_RECOGNITION_ERROR_NONE,
 
+  // No speech heard before timeout.
+  SPEECH_RECOGNITION_ERROR_NO_SPEECH,
+
   // The user or a script aborted speech input.
   SPEECH_RECOGNITION_ERROR_ABORTED,
 
   // There was an error with recording audio.
-  SPEECH_RECOGNITION_ERROR_AUDIO,
+  SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE,
 
   // There was a network error.
   SPEECH_RECOGNITION_ERROR_NETWORK,
@@ -26,15 +29,19 @@
   // Not allowed for privacy or security reasons.
   SPEECH_RECOGNITION_ERROR_NOT_ALLOWED,
 
-  // No speech heard before timeout.
-  SPEECH_RECOGNITION_ERROR_NO_SPEECH,
+  // Speech service is not allowed for privacy or security reasons.
+  SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED,
+
+  // There was an error in the speech recognition grammar.
+  SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR,
+
+  // The language was not supported.
+  SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED,
 
   // Speech was heard, but could not be interpreted.
   SPEECH_RECOGNITION_ERROR_NO_MATCH,
 
-  // There was an error in the speech recognition grammar.
-  SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR,
-  SPEECH_RECOGNITION_ERROR_LAST = SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR,
+  SPEECH_RECOGNITION_ERROR_LAST = SPEECH_RECOGNITION_ERROR_NO_MATCH,
 };
 
 // Error details for the SPEECH_RECOGNITION_ERROR_AUDIO error.
diff --git a/content/public/test/DEPS b/content/public/test/DEPS
index e897ad3..fbe84ed7 100644
--- a/content/public/test/DEPS
+++ b/content/public/test/DEPS
@@ -7,6 +7,10 @@
 # Ensure we don't leak internal content headers through public headers.
 specific_include_rules = {
   ".*\.cc": [
+    # Allow inclusion of specific components that we depend on. We may only
+    # depend on components which we share with the mojo html_viewer.
+    "+components/scheduler/renderer",
+
     # Testing utilities can access anything in content/
     "+content",
     "+gin/v8_initializer.h",
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java
index 6142ffb..3316c7b 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java
@@ -61,15 +61,19 @@
     }
 
     /**
-     * Checks whether the given Criteria is satisfied polling at a default interval on the UI
-     * thread.
+     * Checks whether the given Criteria is satisfied polling at a given interval on the UI
+     * thread, until either the criteria is satisfied, or the maxTimeoutMs number of ms has elapsed.
+     *
      * @param criteria The Criteria that will be checked.
+     * @param maxTimeoutMs The maximum number of ms that this check will be performed for
+     * before timeout.
+     * @param checkIntervalMs The number of ms between checks.
      * @return iff checking has ended with the criteria being satisfied.
      * @throws InterruptedException
      * @see #pollForCriteria(Criteria)
      */
-    public static boolean pollForUIThreadCriteria(final Criteria criteria)
-            throws InterruptedException {
+    public static boolean pollForUIThreadCriteria(final Criteria criteria, long maxTimeoutMs,
+            long checkIntervalMs) throws InterruptedException {
         final Callable<Boolean> callable = new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
@@ -82,7 +86,21 @@
             public boolean isSatisfied() {
                 return ThreadUtils.runOnUiThreadBlockingNoException(callable);
             }
-        });
+        }, maxTimeoutMs, checkIntervalMs);
+    }
+
+    /**
+     * Checks whether the given Criteria is satisfied polling at a default interval on the UI
+     * thread.
+     * @param criteria The Criteria that will be checked.
+     * @return iff checking has ended with the criteria being satisfied.
+     * @throws InterruptedException
+     * @see #pollForCriteria(Criteria)
+     */
+    public static boolean pollForUIThreadCriteria(final Criteria criteria)
+            throws InterruptedException {
+        return pollForUIThreadCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL,
+                DEFAULT_POLLING_INTERVAL);
     }
 
     /**
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index ca67587..1e1a048 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -5,6 +5,7 @@
 #include "content/public/test/render_view_test.h"
 
 #include "base/run_loop.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
@@ -21,7 +22,6 @@
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/renderer_blink_platform_impl.h"
 #include "content/renderer/renderer_main_platform_delegate.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
 #include "content/test/fake_compositor_dependencies.h"
 #include "content/test/mock_render_process.h"
 #include "content/test/test_content_client.h"
@@ -63,7 +63,8 @@
 class RendererBlinkPlatformImplNoSandboxImpl
     : public RendererBlinkPlatformImpl {
  public:
-  RendererBlinkPlatformImplNoSandboxImpl(RendererScheduler* scheduler)
+  RendererBlinkPlatformImplNoSandboxImpl(
+      scheduler::RendererScheduler* scheduler)
       : RendererBlinkPlatformImpl(scheduler) {}
 
   virtual blink::WebSandboxSupport* sandboxSupport() {
@@ -73,7 +74,7 @@
 
 RenderViewTest::RendererBlinkPlatformImplNoSandbox::
     RendererBlinkPlatformImplNoSandbox() {
-  renderer_scheduler_ = RendererScheduler::Create();
+  renderer_scheduler_ = scheduler::RendererScheduler::Create();
   blink_platform_impl_.reset(
       new RendererBlinkPlatformImplNoSandboxImpl(renderer_scheduler_.get()));
 }
diff --git a/content/public/test/render_view_test.h b/content/public/test/render_view_test.h
index d512c54..d3fd776e 100644
--- a/content/public/test/render_view_test.h
+++ b/content/public/test/render_view_test.h
@@ -29,6 +29,10 @@
 class Rect;
 }
 
+namespace scheduler {
+class RendererScheduler;
+}
+
 namespace content {
 class ContentBrowserClient;
 class ContentClient;
@@ -38,7 +42,6 @@
 class PageState;
 class RendererMainPlatformDelegate;
 class RendererBlinkPlatformImplNoSandboxImpl;
-class RendererScheduler;
 class RenderView;
 
 class RenderViewTest : public testing::Test {
@@ -52,7 +55,7 @@
     blink::Platform* Get();
 
    private:
-    scoped_ptr<RendererScheduler> renderer_scheduler_;
+    scoped_ptr<scheduler::RendererScheduler> renderer_scheduler_;
     scoped_ptr<RendererBlinkPlatformImplNoSandboxImpl> blink_platform_impl_;
   };
 
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 13713fd..d4a17fb 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -28,6 +28,7 @@
     "//base/allocator",
     "//cc",
     "//cc/blink",
+    "//components/scheduler:scheduler",
     "//content:resources",
     "//content/common:mojo_bindings",
     "//content/public/child:child_sources",
diff --git a/content/renderer/DEPS b/content/renderer/DEPS
index 076c1129..1f43f937 100644
--- a/content/renderer/DEPS
+++ b/content/renderer/DEPS
@@ -1,4 +1,8 @@
 include_rules = [
+  # Allow inclusion of specific components that we depend on. We may only
+  # depend on components which we share with the mojo html_viewer.
+  "+components/scheduler",
+
   "+cc/blink",
   "+content/public/child",
   "+content/public/renderer",
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index 1ad905da..c0a1ef5 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -335,6 +335,12 @@
                          src.hierarchicalLevel());
   }
 
+  if (src.setSize())
+    dst->AddIntAttribute(ui::AX_ATTR_SET_SIZE, src.setSize());
+
+  if (src.posInSet())
+    dst->AddIntAttribute(ui::AX_ATTR_POS_IN_SET, src.posInSet());
+
   // Treat the active list box item as focused.
   if (dst->role == ui::AX_ROLE_LIST_BOX_OPTION &&
       src.isSelectedOptionActive()) {
diff --git a/content/renderer/devtools/v8_sampling_profiler.cc b/content/renderer/devtools/v8_sampling_profiler.cc
index 8dc70d9c..20b2238 100644
--- a/content/renderer/devtools/v8_sampling_profiler.cc
+++ b/content/renderer/devtools/v8_sampling_profiler.cc
@@ -542,7 +542,11 @@
   state.fp =
       reinterpret_cast<void*>(mcontext.gregs[REG_64_32(REG_RBP, REG_EBP)]);
 #endif  // OS_MACOS
-#endif  // ARCH_CPU_X86_FAMILY
+#elif defined(ARCH_CPU_MIPS_FAMILY)
+  state.pc = reinterpret_cast<void*>(mcontext.pc);
+  state.sp = reinterpret_cast<void*>(mcontext.gregs[29]);
+  state.fp = reinterpret_cast<void*>(mcontext.gregs[30]);
+#endif  // ARCH_CPU_MIPS_FAMILY
 
   Sampler::GetInstance()->DoSample(state);
 }
diff --git a/content/renderer/gpu/compositor_dependencies.h b/content/renderer/gpu/compositor_dependencies.h
index 5c72ee7c..9973a65 100644
--- a/content/renderer/gpu/compositor_dependencies.h
+++ b/content/renderer/gpu/compositor_dependencies.h
@@ -23,8 +23,11 @@
 class GpuMemoryBufferManager;
 }
 
-namespace content {
+namespace scheduler {
 class RendererScheduler;
+}
+
+namespace content {
 
 class CompositorDependencies {
  public:
@@ -48,7 +51,7 @@
   GetCompositorImplThreadTaskRunner() = 0;
   virtual cc::SharedBitmapManager* GetSharedBitmapManager() = 0;
   virtual gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() = 0;
-  virtual RendererScheduler* GetRendererScheduler() = 0;
+  virtual scheduler::RendererScheduler* GetRendererScheduler() = 0;
   virtual cc::ContextProvider* GetSharedMainThreadContextProvider() = 0;
   virtual scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
       int routing_id) = 0;
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index d4890b5..45a350a 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -254,11 +254,8 @@
     scoped_ptr<V8ValueConverter> converter =
         make_scoped_ptr(V8ValueConverter::create());
     v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
-#ifdef WEB_FRAME_USES_V8_LOCAL
-    v8::Local<v8::Value> argv[] = {value};
-#else
     v8::Handle<v8::Value> argv[] = { value };
-#endif
+
     frame->callFunctionEvenIfScriptDisabled(
         callback_and_context->GetCallback(),
         v8::Object::New(isolate),
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 31aa6a8..0264aa5 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -30,11 +30,11 @@
 #include "cc/scheduler/begin_frame_source.h"
 #include "cc/trees/latency_info_swap_promise_monitor.h"
 #include "cc/trees/layer_tree_host.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "content/common/content_switches_internal.h"
 #include "content/common/gpu/client/context_provider_command_buffer.h"
 #include "content/public/common/content_switches.h"
 #include "content/renderer/input/input_handler_manager.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h"
 #include "third_party/WebKit/public/platform/WebSelectionBound.h"
diff --git a/content/renderer/gpu/render_widget_compositor_unittest.cc b/content/renderer/gpu/render_widget_compositor_unittest.cc
index 448fa1f..6becdf51 100644
--- a/content/renderer/gpu/render_widget_compositor_unittest.cc
+++ b/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -7,9 +7,9 @@
 #include "cc/output/begin_frame_args.h"
 #include "cc/test/failure_output_surface.h"
 #include "cc/trees/layer_tree_host.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "content/public/test/mock_render_thread.h"
 #include "content/renderer/render_widget.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
 #include "content/test/fake_compositor_dependencies.h"
 #include "content/test/fake_renderer_scheduler.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/content/renderer/input/input_handler_manager.cc b/content/renderer/input/input_handler_manager.cc
index f266cb85..ef011cc 100644
--- a/content/renderer/input/input_handler_manager.cc
+++ b/content/renderer/input/input_handler_manager.cc
@@ -8,11 +8,11 @@
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/trace_event/trace_event.h"
 #include "cc/input/input_handler.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "content/renderer/input/input_event_filter.h"
 #include "content/renderer/input/input_handler_manager_client.h"
 #include "content/renderer/input/input_handler_wrapper.h"
 #include "content/renderer/input/input_scroll_elasticity_controller.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
 
 using blink::WebInputEvent;
 
@@ -39,7 +39,7 @@
 InputHandlerManager::InputHandlerManager(
     const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
     InputHandlerManagerClient* client,
-    RendererScheduler* renderer_scheduler)
+    scheduler::RendererScheduler* renderer_scheduler)
     : message_loop_proxy_(message_loop_proxy),
       client_(client),
       renderer_scheduler_(renderer_scheduler) {
diff --git a/content/renderer/input/input_handler_manager.h b/content/renderer/input/input_handler_manager.h
index 130fc97..e49d566 100644
--- a/content/renderer/input/input_handler_manager.h
+++ b/content/renderer/input/input_handler_manager.h
@@ -25,12 +25,15 @@
 class WebMouseWheelEvent;
 }
 
+namespace scheduler {
+class RendererScheduler;
+}
+
 namespace content {
 
 class InputHandlerWrapper;
 class InputHandlerManagerClient;
 struct DidOverscrollParams;
-class RendererScheduler;
 
 // InputHandlerManager class manages InputHandlerProxy instances for
 // the WebViews in this renderer.
@@ -43,7 +46,7 @@
   InputHandlerManager(
       const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
       InputHandlerManagerClient* client,
-      RendererScheduler* renderer_scheduler);
+      scheduler::RendererScheduler* renderer_scheduler);
   ~InputHandlerManager();
 
   // Callable from the main thread only.
@@ -96,7 +99,7 @@
 
   scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
   InputHandlerManagerClient* client_;
-  RendererScheduler* renderer_scheduler_;  // Not owned.
+  scheduler::RendererScheduler* renderer_scheduler_;  // Not owned.
 };
 
 }  // namespace content
diff --git a/content/renderer/media/media_stream_audio_processor.cc b/content/renderer/media/media_stream_audio_processor.cc
index af9824d..78237d98c 100644
--- a/content/renderer/media/media_stream_audio_processor.cc
+++ b/content/renderer/media/media_stream_audio_processor.cc
@@ -85,10 +85,17 @@
 }
 
 bool IsBeamformingEnabled(const MediaAudioConstraints& audio_constraints) {
-  return audio_constraints.GetProperty(
-             MediaAudioConstraints::kGoogBeamforming) ||
-         base::FieldTrialList::FindFullName("ChromebookBeamforming") ==
-             "Enabled";
+  return base::FieldTrialList::FindFullName("ChromebookBeamforming") ==
+             "Enabled" ||
+         audio_constraints.GetProperty(MediaAudioConstraints::kGoogBeamforming);
+}
+
+bool IsAudioProcessing48kHzSupportEnabled(
+    const MediaAudioConstraints& audio_constraints) {
+  return base::FieldTrialList::FindFullName("AudioProcessing48kHzSupport") ==
+             "Enabled" ||
+         audio_constraints.GetProperty(
+             MediaAudioConstraints::kGoogAudioProcessing48kHzSupport);
 }
 
 }  // namespace
@@ -465,8 +472,8 @@
   const bool goog_beamforming = IsBeamformingEnabled(audio_constraints);
   const bool goog_high_pass_filter = audio_constraints.GetProperty(
       MediaAudioConstraints::kGoogHighpassFilter);
-  audio_proc_48kHz_support_ = audio_constraints.GetProperty(
-      MediaAudioConstraints::kGoogAudioProcessing48kHzSupport);
+  audio_proc_48kHz_support_ =
+      IsAudioProcessing48kHzSupportEnabled(audio_constraints);
   // Return immediately if no goog constraint is enabled.
   if (!echo_cancellation && !goog_experimental_aec && !goog_ns &&
       !goog_high_pass_filter && !goog_typing_detection &&
diff --git a/content/renderer/media/render_media_client_unittest.cc b/content/renderer/media/render_media_client_unittest.cc
index 7ac253e..f40d0c5 100644
--- a/content/renderer/media/render_media_client_unittest.cc
+++ b/content/renderer/media/render_media_client_unittest.cc
@@ -30,13 +30,13 @@
     key_system_info.max_audio_robustness = media::EmeRobustness::EMPTY;
     key_system_info.max_video_robustness = media::EmeRobustness::EMPTY;
     key_system_info.persistent_license_support =
-        media::EME_SESSION_TYPE_NOT_SUPPORTED;
+        media::EmeSessionTypeSupport::NOT_SUPPORTED;
     key_system_info.persistent_release_message_support =
-        media::EME_SESSION_TYPE_NOT_SUPPORTED;
+        media::EmeSessionTypeSupport::NOT_SUPPORTED;
     key_system_info.persistent_state_support =
-        media::EME_FEATURE_NOT_SUPPORTED;
+        media::EmeFeatureSupport::NOT_SUPPORTED;
     key_system_info.distinctive_identifier_support =
-        media::EME_FEATURE_NOT_SUPPORTED;
+        media::EmeFeatureSupport::NOT_SUPPORTED;
     key_systems_info->push_back(key_system_info);
 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     if (is_extra_key_system_enabled_) {
@@ -45,13 +45,13 @@
       wv_key_system_info.max_audio_robustness = media::EmeRobustness::EMPTY;
       wv_key_system_info.max_video_robustness = media::EmeRobustness::EMPTY;
       wv_key_system_info.persistent_license_support =
-          media::EME_SESSION_TYPE_NOT_SUPPORTED;
+          media::EmeSessionTypeSupport::NOT_SUPPORTED;
       wv_key_system_info.persistent_release_message_support =
-          media::EME_SESSION_TYPE_NOT_SUPPORTED;
+          media::EmeSessionTypeSupport::NOT_SUPPORTED;
       wv_key_system_info.persistent_state_support =
-          media::EME_FEATURE_NOT_SUPPORTED;
+          media::EmeFeatureSupport::NOT_SUPPORTED;
       wv_key_system_info.distinctive_identifier_support =
-          media::EME_FEATURE_NOT_SUPPORTED;
+          media::EmeFeatureSupport::NOT_SUPPORTED;
       key_systems_info->push_back(wv_key_system_info);
     }
 #endif
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 07930b3..00e2f05 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -367,11 +367,11 @@
                      const ui::LatencyInfo* old_latency,
                      blink::WebInputEvent::Type type,
                      int64 input_sequence) {
-  new_latency->AddLatencyNumber(
+  new_latency->AddLatencyNumberWithTraceName(
       ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT,
       0,
-      input_sequence);
-  new_latency->TraceEventType(WebInputEventTraits::GetName(type));
+      input_sequence,
+      WebInputEventTraits::GetName(type));
   if (old_latency) {
     new_latency->CopyLatencyFrom(*old_latency,
                                  ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
diff --git a/content/renderer/pepper/ppb_var_deprecated_impl.cc b/content/renderer/pepper/ppb_var_deprecated_impl.cc
index 064aeb1..589981cf 100644
--- a/content/renderer/pepper/ppb_var_deprecated_impl.cc
+++ b/content/renderer/pepper/ppb_var_deprecated_impl.cc
@@ -248,14 +248,8 @@
     return PP_MakeUndefined();
   }
 
-#ifdef WEB_FRAME_USES_V8_LOCAL
-  scoped_ptr<v8::Local<v8::Value>[]> converted_args(
-      new v8::Local<v8::Value>[argc]);
-#else
   scoped_ptr<v8::Handle<v8::Value>[] > converted_args(
       new v8::Handle<v8::Value>[argc]);
-#endif
-
   for (uint32_t i = 0; i < argc; ++i) {
     converted_args[i] = try_catch.ToV8(argv[i]);
     if (try_catch.HasException())
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3cf9e9b8..1e7ead7 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1100,6 +1100,20 @@
                  << request_params.frame_to_navigate;
   }
 
+  // If this frame isn't in the same process as its parent, it will naively
+  // assume that this is the first navigation in the iframe, but this may not
+  // actually be the case. The PageTransition differentiates between the first
+  // navigation in a subframe and subsequent navigations, so if this is a
+  // subsequent navigation, force the frame's state machine forward.
+  if (ui::PageTransitionCoreTypeIs(common_params.transition,
+                                   ui::PAGE_TRANSITION_MANUAL_SUBFRAME)) {
+    CHECK(frame_->parent());
+    if (frame_->parent()->isWebRemoteFrame()) {
+      CHECK_EQ(frame, frame_);
+      frame_->setCommittedFirstRealLoad();
+    }
+  }
+
   if (is_reload && !render_view_->history_controller()->GetCurrentEntry()) {
     // We cannot reload if we do not have any history state.  This happens, for
     // example, when recovering from a crash.
@@ -2554,6 +2568,8 @@
   document_state->set_start_load_time(Time::Now());
 
   bool is_top_most = !frame->parent();
+  NavigationStateImpl* navigation_state =
+      static_cast<NavigationStateImpl*>(document_state->navigation_state());
   if (is_top_most) {
     render_view_->set_navigation_gesture(
         WebUserGestureIndicator::isProcessingUserGesture() ?
@@ -2562,8 +2578,17 @@
     // Subframe navigations that don't add session history items must be
     // marked with AUTO_SUBFRAME. See also didFailProvisionalLoad for how we
     // handle loading of error pages.
-    static_cast<NavigationStateImpl*>(document_state->navigation_state())
-        ->set_transition_type(ui::PAGE_TRANSITION_AUTO_SUBFRAME);
+    navigation_state->set_transition_type(ui::PAGE_TRANSITION_AUTO_SUBFRAME);
+  } else if (ui::PageTransitionCoreTypeIs(navigation_state->GetTransitionType(),
+                                          ui::PAGE_TRANSITION_LINK)) {
+    // Subframe navigations that are creating a new history item should be
+    // marked MANUAL_SUBFRAME, unless it has already been marked as a
+    // FORM_SUBMIT. This state will be attached to a main resource request
+    // in the process that began the request. If the request is transferred
+    // to a different process, this state will be used in
+    // RenderFrameImpl::OnNavigate() in the new process (as well as in the
+    // browser process).
+    navigation_state->set_transition_type(ui::PAGE_TRANSITION_MANUAL_SUBFRAME);
   }
 
   FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(),
@@ -3147,16 +3172,9 @@
     }
   }
 
-  WebFrame* top_frame = frame->top();
-  // TODO(nasko): Hack around asking about top-frame data source. This means
-  // for out-of-process iframes we are treating the current frame as the
-  // top-level frame, which is wrong.
-  if (!top_frame || top_frame->isWebRemoteFrame())
-    top_frame = frame;
-  WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
-  WebDataSource* top_data_source = top_frame->dataSource();
+  WebDataSource* provisional_data_source = frame->provisionalDataSource();
   WebDataSource* data_source =
-      provisional_data_source ? provisional_data_source : top_data_source;
+      provisional_data_source ? provisional_data_source : frame->dataSource();
 
   DocumentState* document_state = DocumentState::FromDataSource(data_source);
   DCHECK(document_state);
@@ -3295,8 +3313,14 @@
   extra_data->set_stream_override(stream_override.Pass());
   request.setExtraData(extra_data);
 
+  WebFrame* top_frame = frame->top();
+  // TODO(nasko): Hack around asking about top-frame data source. This means
+  // for out-of-process iframes we are treating the current frame as the
+  // top-level frame, which is wrong.
+  if (!top_frame || top_frame->isWebRemoteFrame())
+    top_frame = frame;
   DocumentState* top_document_state =
-      DocumentState::FromDataSource(top_data_source);
+      DocumentState::FromDataSource(top_frame->dataSource());
   if (top_document_state) {
     // TODO(gavinp): separate out prefetching and prerender field trials
     // if the rel=prerender rel type is sticking around.
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 7f03f4e..61fd840 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -33,6 +33,7 @@
 #include "cc/blink/web_external_bitmap_impl.h"
 #include "cc/blink/web_layer_impl.h"
 #include "cc/resources/tile_task_worker_pool.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "content/child/appcache/appcache_dispatcher.h"
 #include "content/child/appcache/appcache_frontend_impl.h"
 #include "content/child/child_discardable_shared_memory_manager.h"
@@ -104,7 +105,6 @@
 #include "content/renderer/render_process_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/renderer_blink_platform_impl.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
 #include "content/renderer/scheduler/resource_dispatch_throttler.h"
 #include "content/renderer/service_worker/embedded_worker_context_message_filter.h"
 #include "content/renderer/service_worker/embedded_worker_dispatcher.h"
@@ -502,7 +502,7 @@
   dom_storage_dispatcher_.reset(new DomStorageDispatcher());
   main_thread_indexed_db_dispatcher_.reset(new IndexedDBDispatcher(
       thread_safe_sender()));
-  renderer_scheduler_ = RendererScheduler::Create();
+  renderer_scheduler_ = scheduler::RendererScheduler::Create();
   channel()->SetListenerTaskRunner(renderer_scheduler_->DefaultTaskRunner());
   main_thread_cache_storage_dispatcher_.reset(
       new CacheStorageDispatcher(thread_safe_sender()));
@@ -1195,6 +1195,7 @@
       --idle_notifications_to_skip_;
     } else {
       base::allocator::ReleaseFreeMemory();
+      discardable_shared_memory_manager()->ReleaseFreeMemory();
     }
     ScheduleIdleHandler(kLongIdleHandlerDelayMs);
     return;
@@ -1442,7 +1443,7 @@
   return gpu_memory_buffer_manager();
 }
 
-RendererScheduler* RenderThreadImpl::GetRendererScheduler() {
+scheduler::RendererScheduler* RenderThreadImpl::GetRendererScheduler() {
   return renderer_scheduler_.get();
 }
 
@@ -1765,6 +1766,7 @@
 void RenderThreadImpl::OnMemoryPressure(
     base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
   base::allocator::ReleaseFreeMemory();
+  discardable_shared_memory_manager()->ReleaseFreeMemory();
 
   // Do not call into blink if it is not initialized.
   if (blink_platform_impl_) {
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index f897fcc..60d4a49 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -70,6 +70,10 @@
 class GpuVideoAcceleratorFactories;
 }
 
+namespace scheduler {
+class RendererScheduler;
+}
+
 namespace v8 {
 class Extension;
 }
@@ -102,7 +106,6 @@
 class RenderProcessObserver;
 class RendererBlinkPlatformImpl;
 class RendererDemuxerAndroid;
-class RendererScheduler;
 class ResourceDispatchThrottler;
 class ResourceSchedulingFilter;
 class V8SamplingProfiler;
@@ -197,7 +200,7 @@
   scoped_refptr<base::SingleThreadTaskRunner>
   GetCompositorImplThreadTaskRunner() override;
   gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
-  RendererScheduler* GetRendererScheduler() override;
+  scheduler::RendererScheduler* GetRendererScheduler() override;
   cc::ContextProvider* GetSharedMainThreadContextProvider() override;
   scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
       int routing_id) override;
@@ -480,7 +483,7 @@
   scoped_ptr<AppCacheDispatcher> appcache_dispatcher_;
   scoped_ptr<DomStorageDispatcher> dom_storage_dispatcher_;
   scoped_ptr<IndexedDBDispatcher> main_thread_indexed_db_dispatcher_;
-  scoped_ptr<RendererScheduler> renderer_scheduler_;
+  scoped_ptr<scheduler::RendererScheduler> renderer_scheduler_;
   scoped_ptr<RendererBlinkPlatformImpl> blink_platform_impl_;
   scoped_ptr<ResourceDispatchThrottler> resource_dispatch_throttler_;
   scoped_ptr<CacheStorageDispatcher> main_thread_cache_storage_dispatcher_;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index e42a1a04..bfef67e2 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -15,6 +15,9 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "cc/blink/context_provider_web_context.h"
+#include "components/scheduler/child/web_scheduler_impl.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
 #include "content/child/database_util.h"
 #include "content/child/file_info_util.h"
 #include "content/child/fileapi/webfilesystem_impl.h"
@@ -22,7 +25,6 @@
 #include "content/child/npapi/npobject_util.h"
 #include "content/child/quota_dispatcher.h"
 #include "content/child/quota_message_filter.h"
-#include "content/child/scheduler/web_scheduler_impl.h"
 #include "content/child/simple_webmimeregistry_impl.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/web_database_observer_impl.h"
@@ -52,8 +54,6 @@
 #include "content/renderer/media/renderer_webmidiaccessor_impl.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/renderer_clipboard_delegate.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
-#include "content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h"
 #include "content/renderer/screen_orientation/screen_orientation_observer.h"
 #include "content/renderer/webclipboard_impl.h"
 #include "content/renderer/webgraphicscontext3d_provider_impl.h"
@@ -221,9 +221,10 @@
 //------------------------------------------------------------------------------
 
 RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
-    RendererScheduler* renderer_scheduler)
+    scheduler::RendererScheduler* renderer_scheduler)
     : BlinkPlatformImpl(renderer_scheduler->DefaultTaskRunner()),
-      main_thread_(new WebThreadImplForRendererScheduler(renderer_scheduler)),
+      main_thread_(
+          new scheduler::WebThreadImplForRendererScheduler(renderer_scheduler)),
       clipboard_delegate_(new RendererClipboardDelegate),
       clipboard_(new WebClipboardImpl(clipboard_delegate_.get())),
       mime_registry_(new RendererBlinkPlatformImpl::MimeRegistry),
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index da3ec90..d5fc8d360 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -37,6 +37,11 @@
 class WebServiceWorkerCacheStorage;
 }
 
+namespace scheduler {
+class RendererScheduler;
+class WebThreadImplForRendererScheduler;
+}
+
 namespace content {
 class BatteryStatusDispatcher;
 class DeviceLightEventPump;
@@ -45,17 +50,16 @@
 class PlatformEventObserverBase;
 class QuotaMessageFilter;
 class RendererClipboardDelegate;
-class RendererScheduler;
 class RenderView;
 class ThreadSafeSender;
 class WebClipboardImpl;
 class WebDatabaseObserverImpl;
 class WebFileSystemImpl;
-class WebThreadImplForRendererScheduler;
 
 class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
  public:
-  explicit RendererBlinkPlatformImpl(RendererScheduler* renderer_scheduler);
+  explicit RendererBlinkPlatformImpl(
+      scheduler::RendererScheduler* renderer_scheduler);
   virtual ~RendererBlinkPlatformImpl();
 
   void set_plugin_refresh_allowed(bool plugin_refresh_allowed) {
@@ -208,7 +212,7 @@
   void SendFakeDeviceEventDataForTesting(blink::WebPlatformEventType type);
   device::VibrationManagerPtr& GetConnectedVibrationManagerService();
 
-  scoped_ptr<WebThreadImplForRendererScheduler> main_thread_;
+  scoped_ptr<scheduler::WebThreadImplForRendererScheduler> main_thread_;
 
   scoped_ptr<RendererClipboardDelegate> clipboard_delegate_;
   scoped_ptr<WebClipboardImpl> clipboard_;
diff --git a/content/renderer/scheduler/resource_dispatch_throttler.cc b/content/renderer/scheduler/resource_dispatch_throttler.cc
index 927db73d..d2f7916 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler.cc
+++ b/content/renderer/scheduler/resource_dispatch_throttler.cc
@@ -6,8 +6,8 @@
 
 #include "base/auto_reset.h"
 #include "base/trace_event/trace_event.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 #include "content/common/resource_messages.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
 #include "ipc/ipc_message_macros.h"
 
 namespace content {
@@ -21,7 +21,7 @@
 
 ResourceDispatchThrottler::ResourceDispatchThrottler(
     IPC::Sender* proxied_sender,
-    RendererScheduler* scheduler,
+    scheduler::RendererScheduler* scheduler,
     base::TimeDelta flush_period,
     uint32 max_requests_per_flush)
     : proxied_sender_(proxied_sender),
diff --git a/content/renderer/scheduler/resource_dispatch_throttler.h b/content/renderer/scheduler/resource_dispatch_throttler.h
index 233dea5a..66fc786 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler.h
+++ b/content/renderer/scheduler/resource_dispatch_throttler.h
@@ -13,9 +13,11 @@
 #include "content/common/content_export.h"
 #include "ipc/ipc_sender.h"
 
-namespace content {
-
+namespace scheduler {
 class RendererScheduler;
+}
+
+namespace content {
 
 // Utility class for throttling a stream of resource requests targetted to a
 // specific IPC sender. The throttling itself is very basic:
@@ -31,7 +33,7 @@
   // |flush_period| and |max_requests_per_flush| must be strictly positive
   // in duration/value.
   ResourceDispatchThrottler(IPC::Sender* proxied_sender,
-                            RendererScheduler* scheduler,
+                            scheduler::RendererScheduler* scheduler,
                             base::TimeDelta flush_period,
                             uint32 max_requests_per_flush);
   ~ResourceDispatchThrottler() override;
@@ -53,7 +55,7 @@
   base::ThreadChecker thread_checker_;
 
   IPC::Sender* const proxied_sender_;
-  RendererScheduler* const scheduler_;
+  scheduler::RendererScheduler* const scheduler_;
   const base::TimeDelta flush_period_;
   const uint32 max_requests_per_flush_;
 
diff --git a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
index 8217f7a..8b9dc14 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
+++ b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
@@ -65,7 +65,7 @@
 class ResourceDispatchThrottlerForTest : public ResourceDispatchThrottler {
  public:
   ResourceDispatchThrottlerForTest(IPC::Sender* sender,
-                                   RendererScheduler* scheduler)
+                                   scheduler::RendererScheduler* scheduler)
       : ResourceDispatchThrottler(
             sender,
             scheduler,
diff --git a/content/renderer/speech_recognition_dispatcher.cc b/content/renderer/speech_recognition_dispatcher.cc
index dea16bc..cb78735 100644
--- a/content/renderer/speech_recognition_dispatcher.cc
+++ b/content/renderer/speech_recognition_dispatcher.cc
@@ -164,21 +164,25 @@
     case SPEECH_RECOGNITION_ERROR_NONE:
       NOTREACHED();
       return WebSpeechRecognizerClient::OtherError;
+    case SPEECH_RECOGNITION_ERROR_NO_SPEECH:
+      return WebSpeechRecognizerClient::NoSpeechError;
     case SPEECH_RECOGNITION_ERROR_ABORTED:
       return WebSpeechRecognizerClient::AbortedError;
-    case SPEECH_RECOGNITION_ERROR_AUDIO:
+    case SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE:
       return WebSpeechRecognizerClient::AudioCaptureError;
     case SPEECH_RECOGNITION_ERROR_NETWORK:
       return WebSpeechRecognizerClient::NetworkError;
     case SPEECH_RECOGNITION_ERROR_NOT_ALLOWED:
       return WebSpeechRecognizerClient::NotAllowedError;
-    case SPEECH_RECOGNITION_ERROR_NO_SPEECH:
-      return WebSpeechRecognizerClient::NoSpeechError;
+    case SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED:
+      return WebSpeechRecognizerClient::ServiceNotAllowedError;
+    case SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR:
+      return WebSpeechRecognizerClient::BadGrammarError;
+    case SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED:
+      return WebSpeechRecognizerClient::LanguageNotSupportedError;
     case SPEECH_RECOGNITION_ERROR_NO_MATCH:
       NOTREACHED();
       return WebSpeechRecognizerClient::OtherError;
-    case SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR:
-      return WebSpeechRecognizerClient::BadGrammarError;
   }
   NOTREACHED();
   return WebSpeechRecognizerClient::OtherError;
diff --git a/content/renderer/web_ui_runner.cc b/content/renderer/web_ui_runner.cc
index 560342f..5d6f05c 100644
--- a/content/renderer/web_ui_runner.cc
+++ b/content/renderer/web_ui_runner.cc
@@ -45,14 +45,8 @@
                                         v8::Handle<v8::Value> receiver,
                                         int argc,
                                         v8::Handle<v8::Value> argv[]) {
-#ifdef WEB_FRAME_USES_V8_LOCAL
-  v8::Local<v8::Value>* cast_argv =
-      reinterpret_cast<v8::Local<v8::Value>*>(argv);
-#else
-  v8::Handle<v8::Value>* cast_argv = argv;
-#endif
   return frame_->callFunctionEvenIfScriptDisabled(function, receiver, argc,
-                                                  cast_argv);
+                                                  argv);
 }
 
 gin::ContextHolder* WebUIRunner::GetContextHolder() {
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index e1d9b116..08a5e56 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -249,6 +249,7 @@
     "//base/third_party/dynamic_annotations",
     "//cc",
     "//components/crash/app",
+    "//components/devtools_discovery",
     "//components/devtools_http_handler",
     "//components/web_cache/renderer",
     "//content:resources",
diff --git a/content/shell/DEPS b/content/shell/DEPS
index 44638c3..552ba8e 100644
--- a/content/shell/DEPS
+++ b/content/shell/DEPS
@@ -24,6 +24,7 @@
   "+ui/views",
 
   "+components/crash",
+  "+components/devtools_discovery",
   "+components/devtools_http_handler",
 
   # For enabling media related features.
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index 096ac679..3ad831e 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -157,6 +157,7 @@
   datadeps = [
     ":content_shell_apk",
   ]
+  apk_under_test = ":content_shell_apk"
   apk_name = "ContentShellTest"
   android_manifest = "javatests/AndroidManifest.xml"
 }
diff --git a/content/shell/android/java/src/org/chromium/content_shell/Shell.java b/content/shell/android/java/src/org/chromium/content_shell/Shell.java
index 6795c16..29d9ecd 100644
--- a/content/shell/android/java/src/org/chromium/content_shell/Shell.java
+++ b/content/shell/android/java/src/org/chromium/content_shell/Shell.java
@@ -287,7 +287,7 @@
     private void initFromNativeTabContents(WebContents webContents) {
         Context context = getContext();
         mContentViewCore = new ContentViewCore(context);
-        ContentView cv = ContentView.newInstance(context, mContentViewCore);
+        ContentView cv = new ContentView(context, mContentViewCore);
         mContentViewCore.initialize(cv, cv, webContents, mWindow);
         mContentViewCore.setContentViewClient(mContentViewClient);
         mWebContents = mContentViewCore.getWebContents();
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
index 927496774..15d097d 100644
--- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
+++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
@@ -200,7 +200,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
                 @Override
             public void run() {
-                ContentView cv = ContentView.newInstance(getActivity(), getContentViewCore());
+                ContentView cv = new ContentView(getActivity(), getContentViewCore());
                 ((ViewGroup) getContentViewCore().getContainerView().getParent()).addView(cv);
                 getContentViewCore().setContainerView(cv);
                 getContentViewCore().setContainerViewInternals(cv);
diff --git a/content/shell/browser/layout_test/layout_test_browser_context.cc b/content/shell/browser/layout_test/layout_test_browser_context.cc
index 259a407..be19bb2 100644
--- a/content/shell/browser/layout_test/layout_test_browser_context.cc
+++ b/content/shell/browser/layout_test/layout_test_browser_context.cc
@@ -69,12 +69,6 @@
   return push_messaging_service_.get();
 }
 
-LayoutTestPushMessagingService*
-LayoutTestBrowserContext::GetLayoutTestPushMessagingService() {
-  return static_cast<LayoutTestPushMessagingService*>(
-      GetPushMessagingService());
-}
-
 PermissionManager* LayoutTestBrowserContext::GetPermissionManager() {
   if (!permission_manager_.get())
     permission_manager_.reset(new LayoutTestPermissionManager());
diff --git a/content/shell/browser/layout_test/layout_test_browser_context.h b/content/shell/browser/layout_test/layout_test_browser_context.h
index d9c9832f..93fd10e 100644
--- a/content/shell/browser/layout_test/layout_test_browser_context.h
+++ b/content/shell/browser/layout_test/layout_test_browser_context.h
@@ -30,7 +30,6 @@
   PushMessagingService* GetPushMessagingService() override;
   PermissionManager* GetPermissionManager() override;
 
-  LayoutTestPushMessagingService* GetLayoutTestPushMessagingService();
   LayoutTestPermissionManager* GetLayoutTestPermissionManager();
 
  protected:
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 fcae408c..6b9eaf6 100644
--- a/content/shell/browser/layout_test/layout_test_message_filter.cc
+++ b/content/shell/browser/layout_test/layout_test_message_filter.cc
@@ -12,7 +12,6 @@
 #include "content/shell/browser/layout_test/layout_test_content_browser_client.h"
 #include "content/shell/browser/layout_test/layout_test_notification_manager.h"
 #include "content/shell/browser/layout_test/layout_test_permission_manager.h"
-#include "content/shell/browser/layout_test/layout_test_push_messaging_service.h"
 #include "content/shell/browser/shell_browser_context.h"
 #include "content/shell/browser/shell_content_browser_client.h"
 #include "content/shell/browser/shell_network_delegate.h"
@@ -47,8 +46,6 @@
   if (message.type() == LayoutTestHostMsg_ClearAllDatabases::ID)
     *thread = BrowserThread::FILE;
   if (message.type() == LayoutTestHostMsg_SimulateWebNotificationClick::ID ||
-      message.type() == LayoutTestHostMsg_SetPushMessagingPermission::ID ||
-      message.type() == LayoutTestHostMsg_ClearPushMessagingPermissions::ID ||
       message.type() == LayoutTestHostMsg_SetPermission::ID ||
       message.type() == LayoutTestHostMsg_ResetPermissions::ID)
     *thread = BrowserThread::UI;
@@ -69,10 +66,6 @@
                         OnClearWebNotificationPermissions)
     IPC_MESSAGE_HANDLER(LayoutTestHostMsg_SimulateWebNotificationClick,
                         OnSimulateWebNotificationClick)
-    IPC_MESSAGE_HANDLER(LayoutTestHostMsg_SetPushMessagingPermission,
-                        OnSetPushMessagingPermission)
-    IPC_MESSAGE_HANDLER(LayoutTestHostMsg_ClearPushMessagingPermissions,
-                        OnClearPushMessagingPermissions)
     IPC_MESSAGE_HANDLER(LayoutTestHostMsg_AcceptAllCookies, OnAcceptAllCookies)
     IPC_MESSAGE_HANDLER(LayoutTestHostMsg_DeleteAllCookies, OnDeleteAllCookies)
     IPC_MESSAGE_HANDLER(LayoutTestHostMsg_SetPermission, OnSetPermission)
@@ -143,23 +136,6 @@
     manager->SimulateClick(title);
 }
 
-void LayoutTestMessageFilter::OnSetPushMessagingPermission(const GURL& origin,
-                                                           bool allowed) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  LayoutTestContentBrowserClient::Get()
-      ->GetLayoutTestBrowserContext()
-      ->GetLayoutTestPushMessagingService()
-      ->SetPermission(origin, allowed);
-}
-
-void LayoutTestMessageFilter::OnClearPushMessagingPermissions() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  LayoutTestContentBrowserClient::Get()
-      ->GetLayoutTestBrowserContext()
-      ->GetLayoutTestPushMessagingService()
-      ->ClearPermissions();
-}
-
 void LayoutTestMessageFilter::OnAcceptAllCookies(bool accept) {
   ShellNetworkDelegate::SetAcceptAllCookies(accept);
 }
diff --git a/content/shell/browser/layout_test/layout_test_permission_manager.cc b/content/shell/browser/layout_test/layout_test_permission_manager.cc
index 53159fbe..36c96c8 100644
--- a/content/shell/browser/layout_test/layout_test_permission_manager.cc
+++ b/content/shell/browser/layout_test/layout_test_permission_manager.cc
@@ -88,9 +88,9 @@
     return;
   }
 
-  callback.Run(GetPermissionStatus(permission,
-                                   requesting_origin,
-                                   web_contents->GetLastCommittedURL()));
+  callback.Run(GetPermissionStatus(
+      permission, requesting_origin,
+      web_contents->GetLastCommittedURL().GetOrigin()));
 }
 
 void LayoutTestPermissionManager::CancelPermissionRequest(
diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.cc b/content/shell/browser/layout_test/layout_test_push_messaging_service.cc
index 85c0932..b3a255b2 100644
--- a/content/shell/browser/layout_test/layout_test_push_messaging_service.cc
+++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.cc
@@ -6,25 +6,38 @@
 
 #include "base/callback.h"
 #include "base/logging.h"
+#include "content/public/browser/permission_type.h"
+#include "content/shell/browser/layout_test/layout_test_browser_context.h"
+#include "content/shell/browser/layout_test/layout_test_content_browser_client.h"
+#include "content/shell/browser/layout_test/layout_test_permission_manager.h"
 
 namespace content {
 
+namespace {
+
+blink::WebPushPermissionStatus ToWebPushPermissionStatus(
+    PermissionStatus status) {
+  switch (status) {
+    case PERMISSION_STATUS_GRANTED:
+      return blink::WebPushPermissionStatusGranted;
+    case PERMISSION_STATUS_DENIED:
+      return blink::WebPushPermissionStatusDenied;
+    case PERMISSION_STATUS_ASK:
+      return blink::WebPushPermissionStatusDefault;
+  }
+
+  NOTREACHED();
+  return blink::WebPushPermissionStatusLast;
+}
+
+}  // anonymous namespace
+
 LayoutTestPushMessagingService::LayoutTestPushMessagingService() {
 }
 
 LayoutTestPushMessagingService::~LayoutTestPushMessagingService() {
 }
 
-void LayoutTestPushMessagingService::SetPermission(const GURL& origin,
-                                                   bool allowed) {
-  permission_map_[origin] = allowed ? blink::WebPushPermissionStatusGranted
-                                    : blink::WebPushPermissionStatusDenied;
-}
-
-void LayoutTestPushMessagingService::ClearPermissions() {
-  permission_map_.clear();
-}
-
 GURL LayoutTestPushMessagingService::GetPushEndpoint() {
   return GURL("https://example.com/LayoutTestEndpoint");
 }
@@ -61,10 +74,12 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_visible) {
-  const auto& it = permission_map_.find(requesting_origin);
-  if (it == permission_map_.end())
-    return blink::WebPushPermissionStatusDefault;
-  return it->second;
+  return ToWebPushPermissionStatus(LayoutTestContentBrowserClient::Get()
+      ->GetLayoutTestBrowserContext()
+      ->GetLayoutTestPermissionManager()
+      ->GetPermissionStatus(PermissionType::PUSH_MESSAGING,
+                            requesting_origin,
+                            embedding_origin));
 }
 
 void LayoutTestPushMessagingService::Unregister(
diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.h b/content/shell/browser/layout_test/layout_test_push_messaging_service.h
index 2fac0b0..1158963 100644
--- a/content/shell/browser/layout_test/layout_test_push_messaging_service.h
+++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.h
@@ -19,9 +19,6 @@
   LayoutTestPushMessagingService();
   ~LayoutTestPushMessagingService() override;
 
-  void SetPermission(const GURL& origin, bool allowed);
-  void ClearPermissions();
-
   // PushMessagingService implementation:
   GURL GetPushEndpoint() override;
   void RegisterFromDocument(
@@ -48,9 +45,6 @@
                   const UnregisterCallback& callback) override;
 
  private:
-  // Map from origin to permission status.
-  std::map<GURL, blink::WebPushPermissionStatus> permission_map_;
-
   DISALLOW_COPY_AND_ASSIGN(LayoutTestPushMessagingService);
 };
 
diff --git a/content/shell/browser/shell_devtools_manager_delegate.cc b/content/shell/browser/shell_devtools_manager_delegate.cc
index 8011145..5384e39 100644
--- a/content/shell/browser/shell_devtools_manager_delegate.cc
+++ b/content/shell/browser/shell_devtools_manager_delegate.cc
@@ -12,6 +12,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/devtools_discovery/basic_target_descriptor.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
 #include "components/devtools_http_handler/devtools_http_handler.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_frontend_host.h"
@@ -45,9 +47,6 @@
 const char kFrontEndURL[] =
     "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/inspector.html";
 #endif
-const char kTargetTypePage[] = "page";
-const char kTargetTypeServiceWorker[] = "service_worker";
-const char kTargetTypeOther[] = "other";
 
 const int kBackLog = 10;
 
@@ -133,62 +132,6 @@
 #endif
 }
 
-class Target : public DevToolsTarget {
- public:
-  explicit Target(scoped_refptr<DevToolsAgentHost> agent_host);
-
-  std::string GetId() const override { return agent_host_->GetId(); }
-  std::string GetParentId() const override { return std::string(); }
-  std::string GetType() const override {
-    switch (agent_host_->GetType()) {
-      case DevToolsAgentHost::TYPE_WEB_CONTENTS:
-        return kTargetTypePage;
-      case DevToolsAgentHost::TYPE_SERVICE_WORKER:
-        return kTargetTypeServiceWorker;
-      default:
-        break;
-    }
-    return kTargetTypeOther;
-  }
-  std::string GetTitle() const override { return agent_host_->GetTitle(); }
-  std::string GetDescription() const override { return std::string(); }
-  GURL GetURL() const override { return agent_host_->GetURL(); }
-  GURL GetFaviconURL() const override { return favicon_url_; }
-  base::TimeTicks GetLastActivityTime() const override {
-    return last_activity_time_;
-  }
-  bool IsAttached() const override { return agent_host_->IsAttached(); }
-  scoped_refptr<DevToolsAgentHost> GetAgentHost() const override {
-    return agent_host_;
-  }
-  bool Activate() const override;
-  bool Close() const override;
-
- private:
-  scoped_refptr<DevToolsAgentHost> agent_host_;
-  GURL favicon_url_;
-  base::TimeTicks last_activity_time_;
-};
-
-Target::Target(scoped_refptr<DevToolsAgentHost> agent_host)
-    : agent_host_(agent_host) {
-  if (WebContents* web_contents = agent_host_->GetWebContents()) {
-    NavigationController& controller = web_contents->GetController();
-    NavigationEntry* entry = controller.GetActiveEntry();
-    if (entry != NULL && entry->GetURL().is_valid())
-      favicon_url_ = entry->GetFavicon().url;
-    last_activity_time_ = web_contents->GetLastActiveTime();
-  }
-}
-
-bool Target::Activate() const {
-  return agent_host_->Activate();
-}
-
-bool Target::Close() const {
-  return agent_host_->Close();
-}
-
 // ShellDevToolsDelegate ----------------------------------------------------
 
 class ShellDevToolsDelegate :
@@ -277,14 +220,16 @@
                                         NULL,
                                         gfx::Size());
   return scoped_ptr<DevToolsTarget>(
-      new Target(DevToolsAgentHost::GetOrCreateFor(shell->web_contents())));
+      new devtools_discovery::BasicTargetDescriptor(
+          DevToolsAgentHost::GetOrCreateFor(shell->web_contents())));
 }
 
 void ShellDevToolsManagerDelegate::EnumerateTargets(TargetCallback callback) {
   TargetList targets;
-  for (const auto& agent_host : DevToolsAgentHost::GetOrCreateAll()) {
-    targets.push_back(new Target(agent_host));
-  }
+  devtools_discovery::DevToolsDiscoveryManager* discovery_manager =
+      devtools_discovery::DevToolsDiscoveryManager::GetInstance();
+  for (const auto& descriptor : discovery_manager->GetDescriptors())
+    targets.push_back(descriptor);
   callback.Run(targets);
 }
 
diff --git a/content/shell/common/layout_test/layout_test_messages.h b/content/shell/common/layout_test/layout_test_messages.h
index ed3a56b..15160744 100644
--- a/content/shell/common/layout_test/layout_test_messages.h
+++ b/content/shell/common/layout_test/layout_test_messages.h
@@ -33,10 +33,6 @@
 IPC_MESSAGE_ROUTED0(LayoutTestHostMsg_ClearWebNotificationPermissions)
 IPC_MESSAGE_ROUTED1(LayoutTestHostMsg_SimulateWebNotificationClick,
                     std::string /* title */)
-IPC_MESSAGE_ROUTED2(LayoutTestHostMsg_SetPushMessagingPermission,
-                    GURL /* origin */,
-                    bool /* allowed */)
-IPC_MESSAGE_ROUTED0(LayoutTestHostMsg_ClearPushMessagingPermissions)
 IPC_MESSAGE_ROUTED1(LayoutTestHostMsg_AcceptAllCookies,
                     bool /* accept */)
 IPC_MESSAGE_ROUTED0(LayoutTestHostMsg_DeleteAllCookies)
diff --git a/content/shell/renderer/layout_test/webkit_test_runner.cc b/content/shell/renderer/layout_test/webkit_test_runner.cc
index e025926a..97222a9 100644
--- a/content/shell/renderer/layout_test/webkit_test_runner.cc
+++ b/content/shell/renderer/layout_test/webkit_test_runner.cc
@@ -439,16 +439,6 @@
   Send(new LayoutTestHostMsg_SimulateWebNotificationClick(routing_id(), title));
 }
 
-void WebKitTestRunner::SetPushMessagingPermission(const GURL& origin,
-                                                  bool allowed) {
-  Send(new LayoutTestHostMsg_SetPushMessagingPermission(routing_id(), origin,
-                                                        allowed));
-}
-
-void WebKitTestRunner::ClearPushMessagingPermissions() {
-  Send(new LayoutTestHostMsg_ClearPushMessagingPermissions(routing_id()));
-}
-
 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 e63ed68..a8271459 100644
--- a/content/shell/renderer/layout_test/webkit_test_runner.h
+++ b/content/shell/renderer/layout_test/webkit_test_runner.h
@@ -92,8 +92,6 @@
                                       bool permission_granted) override;
   void ClearWebNotificationPermissions() override;
   void SimulateWebNotificationClick(const std::string& title) override;
-  void SetPushMessagingPermission(const GURL& origin, bool allowed) override;
-  void ClearPushMessagingPermissions() override;
   void SetDeviceScaleFactor(float factor) override;
   void SetDeviceColorProfile(const std::string& name) override;
   void SetBluetoothMockDataSet(const std::string& name) override;
diff --git a/content/shell/renderer/test_runner/accessibility_controller.cc b/content/shell/renderer/test_runner/accessibility_controller.cc
index 4aafbed4..678f56d 100644
--- a/content/shell/renderer/test_runner/accessibility_controller.cc
+++ b/content/shell/renderer/test_runner/accessibility_controller.cc
@@ -191,11 +191,7 @@
     return;
 
   // Call global notification listeners.
-#ifdef WEB_FRAME_USES_V8_LOCAL
-  v8::Local<v8::Value> argv[] = {
-#else
   v8::Handle<v8::Value> argv[] = {
-#endif
     element_handle,
     v8::String::NewFromUtf8(isolate, notification_name.data(),
                             v8::String::kNormalString,
diff --git a/content/shell/renderer/test_runner/test_runner.cc b/content/shell/renderer/test_runner/test_runner.cc
index 7177151..3b017d9 100644
--- a/content/shell/renderer/test_runner/test_runner.cc
+++ b/content/shell/renderer/test_runner/test_runner.cc
@@ -41,7 +41,6 @@
 #include "third_party/WebKit/public/web/WebInputElement.h"
 #include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebMIDIClientMock.h"
 #include "third_party/WebKit/public/web/WebPageOverlay.h"
 #include "third_party/WebKit/public/web/WebScriptSource.h"
 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
@@ -105,15 +104,9 @@
 
     v8::Context::Scope context_scope(context);
 
-#ifdef WEB_FRAME_USES_V8_LOCAL
-    scoped_ptr<v8::Local<v8::Value>[]> local_argv;
-    if (argc_) {
-      local_argv.reset(new v8::Local<v8::Value>[argc_]);
-#else
     scoped_ptr<v8::Handle<v8::Value>[]> local_argv;
     if (argc_) {
         local_argv.reset(new v8::Handle<v8::Value>[argc_]);
-#endif
         for (int i = 0; i < argc_; ++i)
           local_argv[i] = v8::Local<v8::Value>::New(isolate, argv_[i]);
     }
@@ -307,8 +300,6 @@
                                             v8::Handle<v8::Function> callback);
   void SetCustomTextOutput(std::string output);
   void SetViewSourceForFrame(const std::string& name, bool enabled);
-  void SetPushMessagingPermission(const std::string& origin, bool allowed);
-  void ClearPushMessagingPermissions();
   void SetBluetoothMockDataSet(const std::string& dataset_name);
   void SetGeofencingMockProvider(bool service_available);
   void ClearGeofencingMockProvider();
@@ -562,10 +553,6 @@
                  &TestRunnerBindings::SetCustomTextOutput)
       .SetMethod("setViewSourceForFrame",
                  &TestRunnerBindings::SetViewSourceForFrame)
-      .SetMethod("setPushMessagingPermission",
-                 &TestRunnerBindings::SetPushMessagingPermission)
-      .SetMethod("clearPushMessagingPermissions",
-                 &TestRunnerBindings::ClearPushMessagingPermissions)
       .SetMethod("setBluetoothMockDataSet",
                  &TestRunnerBindings::SetBluetoothMockDataSet)
       .SetMethod("forceNextWebGLContextCreationToFail",
@@ -1337,8 +1324,6 @@
 }
 
 void TestRunnerBindings::SetMIDISysexPermission(bool value) {
-  if (runner_)
-    runner_->SetMIDISysexPermission(value);
 }
 
 void TestRunnerBindings::GrantWebNotificationPermission(gin::Arguments* args) {
@@ -1441,17 +1426,6 @@
   }
 }
 
-void TestRunnerBindings::SetPushMessagingPermission(const std::string& origin,
-                                                    bool allowed) {
-  if (runner_)
-    runner_->SetPushMessagingPermission(GURL(origin), allowed);
-}
-
-void TestRunnerBindings::ClearPushMessagingPermissions() {
-  if (runner_)
-    runner_->ClearPushMessagingPermissions();
-}
-
 void TestRunnerBindings::SetGeofencingMockProvider(bool service_available) {
   if (runner_)
     runner_->SetGeofencingMockProvider(service_available);
@@ -2855,11 +2829,6 @@
   midi_accessor_result_ = result;
 }
 
-void TestRunner::SetMIDISysexPermission(bool value) {
-  for (auto* window : test_interfaces_->GetWindowList())
-    window->GetMIDIClientMock()->setSysexPermission(value);
-}
-
 void TestRunner::GrantWebNotificationPermission(const GURL& origin,
                                                 bool permission_granted) {
   delegate_->GrantWebNotificationPermission(origin, permission_granted);
@@ -3010,14 +2979,6 @@
   InvokeCallback(task.Pass());
 }
 
-void TestRunner::SetPushMessagingPermission(const GURL& origin, bool allowed) {
-  delegate_->SetPushMessagingPermission(origin, allowed);
-}
-
-void TestRunner::ClearPushMessagingPermissions() {
-  delegate_->ClearPushMessagingPermissions();
-}
-
 void TestRunner::LocationChangeDone() {
   web_history_item_count_ = delegate_->NavigationEntryCount();
 
diff --git a/content/shell/renderer/test_runner/test_runner.h b/content/shell/renderer/test_runner/test_runner.h
index 94d83ec..c55ab4b 100644
--- a/content/shell/renderer/test_runner/test_runner.h
+++ b/content/shell/renderer/test_runner/test_runner.h
@@ -547,7 +547,6 @@
 
   // MIDI function to control permission handling.
   void SetMIDIAccessorResult(bool result);
-  void SetMIDISysexPermission(bool value);
 
   // Grants permission for desktop notifications to an origin
   void GrantWebNotificationPermission(const GURL& origin,
@@ -592,12 +591,6 @@
   void CopyImageAtAndCapturePixelsAsyncThen(
       int x, int y, const v8::Handle<v8::Function> callback);
 
-  // Sets the origin's permission to use the Push API to granted or denied.
-  void SetPushMessagingPermission(const GURL& origin, bool allowed);
-
-  // Clears all previously granted Push API permissions.
-  void ClearPushMessagingPermissions();
-
   void GetManifestThen(v8::Handle<v8::Function> callback);
 
   ///////////////////////////////////////////////////////////////////////////
diff --git a/content/shell/renderer/test_runner/web_ax_object_proxy.cc b/content/shell/renderer/test_runner/web_ax_object_proxy.cc
index b0d6d66..cdff16e 100644
--- a/content/shell/renderer/test_runner/web_ax_object_proxy.cc
+++ b/content/shell/renderer/test_runner/web_ax_object_proxy.cc
@@ -492,9 +492,6 @@
                    &WebAXObjectProxy::SelectionStartLineNumber)
       .SetProperty("selectionEndLineNumber",
                    &WebAXObjectProxy::SelectionEndLineNumber)
-      .SetProperty("insertionPointLineNumber",
-                   &WebAXObjectProxy::InsertionPointLineNumber)
-      .SetProperty("selectedTextRange", &WebAXObjectProxy::SelectedTextRange)
       .SetProperty("isEnabled", &WebAXObjectProxy::IsEnabled)
       .SetProperty("isRequired", &WebAXObjectProxy::IsRequired)
       .SetProperty("isFocused", &WebAXObjectProxy::IsFocused)
@@ -513,6 +510,8 @@
       .SetProperty("isValid", &WebAXObjectProxy::IsValid)
       .SetProperty("isReadOnly", &WebAXObjectProxy::IsReadOnly)
       .SetProperty("orientation", &WebAXObjectProxy::Orientation)
+      .SetProperty("posInSet", &WebAXObjectProxy::PosInSet)
+      .SetProperty("setSize", &WebAXObjectProxy::SetSize)
       .SetProperty("clickPointX", &WebAXObjectProxy::ClickPointX)
       .SetProperty("clickPointY", &WebAXObjectProxy::ClickPointY)
       .SetProperty("rowCount", &WebAXObjectProxy::RowCount)
@@ -622,11 +621,7 @@
 
   v8::Isolate* isolate = blink::mainThreadIsolate();
 
-#ifdef WEB_FRAME_USES_V8_LOCAL
-  v8::Local<v8::Value> argv[] = {
-#else
   v8::Handle<v8::Value> argv[] = {
-#endif
     v8::String::NewFromUtf8(isolate, notification_name.data(),
                             v8::String::kNormalString,
                             notification_name.size()),
@@ -745,23 +740,6 @@
   return accessibility_object_.selectionEndLineNumber();
 }
 
-// TODO(nektar): Remove this function after updating tests.
-int WebAXObjectProxy::InsertionPointLineNumber() {
-  accessibility_object_.updateLayoutAndCheckValidity();
-  if (!accessibility_object_.isFocused())
-    return -1;
-  return accessibility_object_.selectionEndLineNumber();
-}
-
-// TODO(nektar): Remove this function after updating tests.
-std::string WebAXObjectProxy::SelectedTextRange() {
-  accessibility_object_.updateLayoutAndCheckValidity();
-  unsigned selection_start = accessibility_object_.selectionStart();
-  unsigned selection_end = accessibility_object_.selectionEnd();
-  return base::StringPrintf("{%d, %d}",
-                            selection_start, selection_end - selection_start);
-}
-
 bool WebAXObjectProxy::IsEnabled() {
   accessibility_object_.updateLayoutAndCheckValidity();
   return accessibility_object_.isEnabled();
@@ -853,6 +831,16 @@
   return std::string();
 }
 
+int WebAXObjectProxy::PosInSet() {
+  accessibility_object_.updateLayoutAndCheckValidity();
+  return accessibility_object_.posInSet();
+}
+
+int WebAXObjectProxy::SetSize() {
+  accessibility_object_.updateLayoutAndCheckValidity();
+  return accessibility_object_.setSize();
+}
+
 int WebAXObjectProxy::ClickPointX() {
   accessibility_object_.updateLayoutAndCheckValidity();
   return accessibility_object_.clickPoint().x;
diff --git a/content/shell/renderer/test_runner/web_ax_object_proxy.h b/content/shell/renderer/test_runner/web_ax_object_proxy.h
index 0c1eea0..7e86e620 100644
--- a/content/shell/renderer/test_runner/web_ax_object_proxy.h
+++ b/content/shell/renderer/test_runner/web_ax_object_proxy.h
@@ -73,10 +73,6 @@
   int SelectionEnd();
   int SelectionStartLineNumber();
   int SelectionEndLineNumber();
-  // TODO(nektar): Remove this function after updating tests.
-  int InsertionPointLineNumber();
-  // TODO(nektar): Remove this function after updating tests.
-  std::string SelectedTextRange();
   bool IsEnabled();
   bool IsRequired();
   bool IsFocused();
@@ -94,6 +90,8 @@
   bool IsValid();
   bool IsReadOnly();
   std::string Orientation();
+  int PosInSet();
+  int SetSize();
   int ClickPointX();
   int ClickPointY();
   int32_t RowCount();
diff --git a/content/shell/renderer/test_runner/web_frame_test_proxy.h b/content/shell/renderer/test_runner/web_frame_test_proxy.h
index c0541eb..8d860ff 100644
--- a/content/shell/renderer/test_runner/web_frame_test_proxy.h
+++ b/content/shell/renderer/test_runner/web_frame_test_proxy.h
@@ -266,10 +266,6 @@
     return base_proxy_->GetUserMediaClient();
   }
 
-  virtual blink::WebMIDIClient* webMIDIClient() {
-    return base_proxy_->GetWebMIDIClient();
-  }
-
   virtual bool willCheckAndDispatchMessageEvent(
       blink::WebLocalFrame* source_frame,
       blink::WebFrame* target_frame,
diff --git a/content/shell/renderer/test_runner/web_test_delegate.h b/content/shell/renderer/test_runner/web_test_delegate.h
index 304f8c9..ee03798 100644
--- a/content/shell/renderer/test_runner/web_test_delegate.h
+++ b/content/shell/renderer/test_runner/web_test_delegate.h
@@ -140,10 +140,6 @@
   virtual void ClearWebNotificationPermissions() = 0;
   virtual void SimulateWebNotificationClick(const std::string& title) = 0;
 
-  // Controls the Push API.
-  virtual void SetPushMessagingPermission(const GURL& origin, bool allowed) = 0;
-  virtual void ClearPushMessagingPermissions() = 0;
-
   // Controls the device scale factor of the main WebView for hidpi tests.
   virtual void SetDeviceScaleFactor(float factor) = 0;
 
diff --git a/content/shell/renderer/test_runner/web_test_proxy.cc b/content/shell/renderer/test_runner/web_test_proxy.cc
index d602bbc..ae522d3 100644
--- a/content/shell/renderer/test_runner/web_test_proxy.cc
+++ b/content/shell/renderer/test_runner/web_test_proxy.cc
@@ -46,7 +46,6 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebHistoryItem.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebMIDIClientMock.h"
 #include "third_party/WebKit/public/web/WebNode.h"
 #include "third_party/WebKit/public/web/WebPagePopup.h"
 #include "third_party/WebKit/public/web/WebPluginParams.h"
@@ -407,8 +406,6 @@
   animate_scheduled_ = false;
   resource_identifier_map_.clear();
   log_console_output_ = true;
-  if (midi_client_.get())
-    midi_client_->resetMock();
   accept_languages_ = "";
 }
 
@@ -678,12 +675,6 @@
   return screen_orientation_client_.get();
 }
 
-blink::WebMIDIClientMock* WebTestProxyBase::GetMIDIClientMock() {
-  if (!midi_client_.get())
-    midi_client_.reset(new blink::WebMIDIClientMock);
-  return midi_client_.get();
-}
-
 MockWebSpeechRecognizer* WebTestProxyBase::GetSpeechRecognizerMock() {
   if (!speech_recognizer_.get()) {
     speech_recognizer_.reset(new MockWebSpeechRecognizer());
@@ -938,10 +929,6 @@
   frame->printEnd();
 }
 
-blink::WebMIDIClient* WebTestProxyBase::GetWebMIDIClient() {
-  return GetMIDIClientMock();
-}
-
 blink::WebSpeechRecognizer* WebTestProxyBase::GetSpeechRecognizer() {
   return GetSpeechRecognizerMock();
 }
diff --git a/content/shell/renderer/test_runner/web_test_proxy.h b/content/shell/renderer/test_runner/web_test_proxy.h
index d170c95..944b67c2 100644
--- a/content/shell/renderer/test_runner/web_test_proxy.h
+++ b/content/shell/renderer/test_runner/web_test_proxy.h
@@ -48,8 +48,6 @@
 class WebLocalFrame;
 class WebMIDIAccessor;
 class WebMIDIAccessorClient;
-class WebMIDIClient;
-class WebMIDIClientMock;
 class WebNode;
 class WebPlugin;
 class WebRange;
@@ -128,7 +126,6 @@
 
   void GetScreenOrientationForTesting(blink::WebScreenInfo&);
   MockScreenOrientationClient* GetScreenOrientationClientMock();
-  blink::WebMIDIClientMock* GetMIDIClientMock();
   MockWebSpeechRecognizer* GetSpeechRecognizerMock();
   MockCredentialManagerClient* GetCredentialManagerClientMock();
 
@@ -168,7 +165,6 @@
                        const blink::WebContextMenuData& data);
   blink::WebUserMediaClient* GetUserMediaClient();
   void PrintPage(blink::WebLocalFrame* frame);
-  blink::WebMIDIClient* GetWebMIDIClient();
   blink::WebSpeechRecognizer* GetSpeechRecognizer();
   bool RequestPointerLock();
   void RequestPointerUnlock();
@@ -268,7 +264,6 @@
   int chooser_count_;
 
   scoped_ptr<MockCredentialManagerClient> credential_manager_client_;
-  scoped_ptr<blink::WebMIDIClientMock> midi_client_;
   scoped_ptr<MockWebSpeechRecognizer> speech_recognizer_;
   scoped_ptr<MockScreenOrientationClient> screen_orientation_client_;
 
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index fddbb5c..81823f0 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -54,6 +54,7 @@
 
     public_deps += [ "//third_party/WebKit/public:blink" ]
     deps += [
+      "//components/scheduler:scheduler",
       "//content/browser/speech/proto",
       "//content/public/child:child_sources",
       "//content/gpu",
diff --git a/content/test/DEPS b/content/test/DEPS
index b0b89c0..12876fd 100644
--- a/content/test/DEPS
+++ b/content/test/DEPS
@@ -1,4 +1,8 @@
 include_rules = [
+  # Allow inclusion of specific components that we depend on. We may only
+  # depend on components which we share with the mojo html_viewer.
+  "+components/scheduler/renderer",
+
   "+cc/blink",
   "+chromeos/audio", # For WebRTC tests.
   # Testing utilities can access anything in content/
diff --git a/content/test/data/accessibility/aria/aria-posinset-expected-android.txt b/content/test/data/accessibility/aria/aria-posinset-expected-android.txt
new file mode 100644
index 0000000..4d08881
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-posinset-expected-android.txt
@@ -0,0 +1,12 @@
+android.webkit.WebView focusable focused scrollable
+++android.widget.ListView collection item_count=4 row_count=4
+++++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
+++++android.view.View clickable collection_item focusable name='Item 3' item_index=2 row_index=2
+++++android.view.View clickable collection_item focusable name='Item 4' item_index=3 row_index=3
+++android.widget.ListView collection item_count=5 row_count=5
+++++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
+++++android.view.View clickable collection_item focusable name='Item 3' item_index=2 row_index=2
+++++android.view.View clickable collection_item focusable name='Item 4' item_index=3 row_index=3
+++++android.view.View clickable collection_item focusable name='Item 5' item_index=4 row_index=4
diff --git a/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt b/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
new file mode 100644
index 0000000..36811b7e
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
@@ -0,0 +1,12 @@
+AXWebArea AXRoleDescription='HTML content'
+++AXList AXRoleDescription='list'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 1' AXARIASetSize='4' AXARIAPosInSet='1'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 2' AXARIASetSize='4' AXARIAPosInSet='2'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 3' AXARIASetSize='4' AXARIAPosInSet='3'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 4' AXARIASetSize='4' AXARIAPosInSet='4'
+++AXList AXRoleDescription='list'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 1' AXARIASetSize='5' AXARIAPosInSet='1'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 2' AXARIASetSize='5' AXARIAPosInSet='2'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 3' AXARIASetSize='5' AXARIAPosInSet='3'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 4' AXARIASetSize='5' AXARIAPosInSet='4'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 5' AXARIASetSize='5' AXARIAPosInSet='5'
diff --git a/content/test/data/accessibility/aria/aria-posinset-expected-win.txt b/content/test/data/accessibility/aria/aria-posinset-expected-win.txt
new file mode 100644
index 0000000..6cae42b
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-posinset-expected-win.txt
@@ -0,0 +1,12 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+++ROLE_SYSTEM_LIST
+++++ROLE_SYSTEM_LISTITEM name='Item 1' FOCUSABLE setsize:4 posinset:1
+++++ROLE_SYSTEM_LISTITEM name='Item 2' FOCUSABLE setsize:4 posinset:2
+++++ROLE_SYSTEM_LISTITEM name='Item 3' FOCUSABLE setsize:4 posinset:3
+++++ROLE_SYSTEM_LISTITEM name='Item 4' FOCUSABLE setsize:4 posinset:4
+++ROLE_SYSTEM_LIST
+++++ROLE_SYSTEM_LISTITEM name='Item 1' FOCUSABLE setsize:5 posinset:1
+++++ROLE_SYSTEM_LISTITEM name='Item 2' FOCUSABLE setsize:5 posinset:2
+++++ROLE_SYSTEM_LISTITEM name='Item 3' FOCUSABLE setsize:5 posinset:3
+++++ROLE_SYSTEM_LISTITEM name='Item 4' FOCUSABLE setsize:5 posinset:4
+++++ROLE_SYSTEM_LISTITEM name='Item 5' FOCUSABLE setsize:5 posinset:5
diff --git a/content/test/data/accessibility/aria/aria-posinset.html b/content/test/data/accessibility/aria/aria-posinset.html
new file mode 100644
index 0000000..e9ffd1c
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-posinset.html
@@ -0,0 +1,23 @@
+<!--
+@MAC-ALLOW:AXRole*
+@MAC-ALLOW:AXARIA*
+@WIN-ALLOW:setsize*
+@WIN-ALLOW:posinset*
+-->
+<html>
+<body>
+<div role="listbox">
+  <div tabIndex="0" aria-setsize="4" aria-posinset="1" role="option">Item 1</div>
+  <div tabIndex="0" aria-setsize="4" aria-posinset="2" role="option">Item 2</div>
+  <div tabIndex="0" aria-setsize="4" aria-posinset="3" role="option">Item 3</div>
+  <div tabIndex="0" aria-setsize="4" aria-posinset="4" role="option">Item 4</div>
+</div>
+<div role="listbox">
+  <div tabIndex="0" role="option">Item 1</div>
+  <div tabIndex="0" role="option">Item 2</div>
+  <div tabIndex="0" role="option">Item 3</div>
+  <div tabIndex="0" role="option">Item 4</div>
+  <div tabIndex="0" role="option">Item 5</div>
+</div>
+</body>
+</html>
diff --git a/content/test/data/accessibility/aria/aria-setsize-expected-android.txt b/content/test/data/accessibility/aria/aria-setsize-expected-android.txt
new file mode 100644
index 0000000..4d08881
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-setsize-expected-android.txt
@@ -0,0 +1,12 @@
+android.webkit.WebView focusable focused scrollable
+++android.widget.ListView collection item_count=4 row_count=4
+++++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
+++++android.view.View clickable collection_item focusable name='Item 3' item_index=2 row_index=2
+++++android.view.View clickable collection_item focusable name='Item 4' item_index=3 row_index=3
+++android.widget.ListView collection item_count=5 row_count=5
+++++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
+++++android.view.View clickable collection_item focusable name='Item 3' item_index=2 row_index=2
+++++android.view.View clickable collection_item focusable name='Item 4' item_index=3 row_index=3
+++++android.view.View clickable collection_item focusable name='Item 5' item_index=4 row_index=4
diff --git a/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt b/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt
new file mode 100644
index 0000000..36811b7e
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt
@@ -0,0 +1,12 @@
+AXWebArea AXRoleDescription='HTML content'
+++AXList AXRoleDescription='list'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 1' AXARIASetSize='4' AXARIAPosInSet='1'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 2' AXARIASetSize='4' AXARIAPosInSet='2'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 3' AXARIASetSize='4' AXARIAPosInSet='3'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 4' AXARIASetSize='4' AXARIAPosInSet='4'
+++AXList AXRoleDescription='list'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 1' AXARIASetSize='5' AXARIAPosInSet='1'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 2' AXARIASetSize='5' AXARIAPosInSet='2'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 3' AXARIASetSize='5' AXARIAPosInSet='3'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 4' AXARIASetSize='5' AXARIAPosInSet='4'
+++++AXStaticText AXRoleDescription='text' AXTitle='Item 5' AXARIASetSize='5' AXARIAPosInSet='5'
diff --git a/content/test/data/accessibility/aria/aria-setsize-expected-win.txt b/content/test/data/accessibility/aria/aria-setsize-expected-win.txt
new file mode 100644
index 0000000..6cae42b
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-setsize-expected-win.txt
@@ -0,0 +1,12 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+++ROLE_SYSTEM_LIST
+++++ROLE_SYSTEM_LISTITEM name='Item 1' FOCUSABLE setsize:4 posinset:1
+++++ROLE_SYSTEM_LISTITEM name='Item 2' FOCUSABLE setsize:4 posinset:2
+++++ROLE_SYSTEM_LISTITEM name='Item 3' FOCUSABLE setsize:4 posinset:3
+++++ROLE_SYSTEM_LISTITEM name='Item 4' FOCUSABLE setsize:4 posinset:4
+++ROLE_SYSTEM_LIST
+++++ROLE_SYSTEM_LISTITEM name='Item 1' FOCUSABLE setsize:5 posinset:1
+++++ROLE_SYSTEM_LISTITEM name='Item 2' FOCUSABLE setsize:5 posinset:2
+++++ROLE_SYSTEM_LISTITEM name='Item 3' FOCUSABLE setsize:5 posinset:3
+++++ROLE_SYSTEM_LISTITEM name='Item 4' FOCUSABLE setsize:5 posinset:4
+++++ROLE_SYSTEM_LISTITEM name='Item 5' FOCUSABLE setsize:5 posinset:5
diff --git a/content/test/data/accessibility/aria/aria-setsize.html b/content/test/data/accessibility/aria/aria-setsize.html
new file mode 100644
index 0000000..e9ffd1c
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-setsize.html
@@ -0,0 +1,23 @@
+<!--
+@MAC-ALLOW:AXRole*
+@MAC-ALLOW:AXARIA*
+@WIN-ALLOW:setsize*
+@WIN-ALLOW:posinset*
+-->
+<html>
+<body>
+<div role="listbox">
+  <div tabIndex="0" aria-setsize="4" aria-posinset="1" role="option">Item 1</div>
+  <div tabIndex="0" aria-setsize="4" aria-posinset="2" role="option">Item 2</div>
+  <div tabIndex="0" aria-setsize="4" aria-posinset="3" role="option">Item 3</div>
+  <div tabIndex="0" aria-setsize="4" aria-posinset="4" role="option">Item 4</div>
+</div>
+<div role="listbox">
+  <div tabIndex="0" role="option">Item 1</div>
+  <div tabIndex="0" role="option">Item 2</div>
+  <div tabIndex="0" role="option">Item 3</div>
+  <div tabIndex="0" role="option">Item 4</div>
+  <div tabIndex="0" role="option">Item 5</div>
+</div>
+</body>
+</html>
diff --git a/content/test/fake_compositor_dependencies.cc b/content/test/fake_compositor_dependencies.cc
index ee533a4..98aa6b5 100644
--- a/content/test/fake_compositor_dependencies.cc
+++ b/content/test/fake_compositor_dependencies.cc
@@ -80,7 +80,8 @@
   return &gpu_memory_buffer_manager_;
 }
 
-RendererScheduler* FakeCompositorDependencies::GetRendererScheduler() {
+scheduler::RendererScheduler*
+FakeCompositorDependencies::GetRendererScheduler() {
   return &renderer_scheduler_;
 }
 
diff --git a/content/test/fake_compositor_dependencies.h b/content/test/fake_compositor_dependencies.h
index 7c6606b..0dac57b7 100644
--- a/content/test/fake_compositor_dependencies.h
+++ b/content/test/fake_compositor_dependencies.h
@@ -36,7 +36,7 @@
   GetCompositorImplThreadTaskRunner() override;
   cc::SharedBitmapManager* GetSharedBitmapManager() override;
   gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
-  RendererScheduler* GetRendererScheduler() override;
+  scheduler::RendererScheduler* GetRendererScheduler() override;
   cc::ContextProvider* GetSharedMainThreadContextProvider() override;
   scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
       int routing_id) override;
diff --git a/content/test/fake_renderer_scheduler.cc b/content/test/fake_renderer_scheduler.cc
index 07c85a5..1424706 100644
--- a/content/test/fake_renderer_scheduler.cc
+++ b/content/test/fake_renderer_scheduler.cc
@@ -27,7 +27,7 @@
   return nullptr;
 }
 
-scoped_refptr<SingleThreadIdleTaskRunner>
+scoped_refptr<scheduler::SingleThreadIdleTaskRunner>
 FakeRendererScheduler::IdleTaskRunner() {
   return nullptr;
 }
diff --git a/content/test/fake_renderer_scheduler.h b/content/test/fake_renderer_scheduler.h
index d1d39de..7de65cee 100644
--- a/content/test/fake_renderer_scheduler.h
+++ b/content/test/fake_renderer_scheduler.h
@@ -5,11 +5,11 @@
 #ifndef CONTENT_TEST_FAKE_RENDERER_SCHEDULER_H_
 #define CONTENT_TEST_FAKE_RENDERER_SCHEDULER_H_
 
-#include "content/renderer/scheduler/renderer_scheduler.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
 
 namespace content {
 
-class FakeRendererScheduler : public RendererScheduler {
+class FakeRendererScheduler : public scheduler::RendererScheduler {
  public:
   FakeRendererScheduler();
   ~FakeRendererScheduler() override;
@@ -18,7 +18,8 @@
   scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override;
   scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
   scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() override;
-  scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override;
+  scoped_refptr<scheduler::SingleThreadIdleTaskRunner> IdleTaskRunner()
+      override;
   scoped_refptr<base::SingleThreadTaskRunner> TimerTaskRunner() override;
   void WillBeginFrame(const cc::BeginFrameArgs& args) override;
   void BeginFrameNotExpectedSoon() override;
diff --git a/content/test/gpu/OWNERS b/content/test/gpu/OWNERS
index 84f8217..74fe357 100644
--- a/content/test/gpu/OWNERS
+++ b/content/test/gpu/OWNERS
@@ -1,2 +1,3 @@
+bajones@chromium.org
 kbr@chromium.org
 zmo@chromium.org
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index d91520ed..522911e 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -9,14 +9,6 @@
 class WebGLConformanceExpectations(GpuTestExpectations):
   def SetExpectations(self):
     # Fails on all platforms
-    self.Fail('conformance/glsl/misc/shaders-with-invariance.html',
-        bug=421710)
-    self.Fail('conformance/glsl/bugs/essl3-shaders-with-webgl1.html',
-        bug=428845)
-    self.Fail('conformance/glsl/misc/expression-list-in-declarator-initializer.html',
-        bug=428845)
-    self.Fail('conformance/uniforms/gl-uniform-arrays.html',
-        bug=433385)
     self.Fail(
         'conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html',
         bug=478570)
@@ -34,23 +26,10 @@
         bug=478572)
 
     # Win failures
-    self.Fail('conformance/glsl/misc/struct-equals.html',
-        ['win'], bug=391957)
-    self.Fail('conformance/glsl/bugs/conditional-discard-in-loop.html',
-        ['win'], bug=402195)
     self.Fail('conformance/glsl/misc/ternary-operators-in-global-initializers.html',
         ['win'], bug=415694)
     self.Fail('conformance/glsl/misc/struct-specifiers-in-uniforms.html',
         ['win'], bug=433412)
-    # 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)
-
-    self.Fail('conformance/rendering/framebuffer-switch.html',
-        ['win'], bug=428849)
-    self.Fail('conformance/rendering/framebuffer-texture-switch.html',
-        ['win'], bug=428849)
 
     # Win7 / Intel failures
     self.Fail('conformance/rendering/gl-scissor-test.html',
@@ -64,10 +43,6 @@
     self.Fail('conformance/glsl/misc/shader-with-array-of-structs-uniform.html',
         ['win7', 'intel', 'nvidia'], bug=373972)
 
-    # Win8 / NVIDIA failures
-    self.Fail('conformance/textures/tex-image-and-sub-image-2d-with-array-buffer-view.html',
-        ['win', 'nvidia'], bug=459265)
-
     # Win / AMD failures
     self.Fail('conformance/textures/texparameter-test.html',
         ['win', 'amd', 'd3d9'], bug=839) # angle bug ID
@@ -83,6 +58,10 @@
     self.Skip('conformance/extensions/oes-texture-half-float-with-canvas.html',
         ['win', 'd3d9'], bug=896) # angle bug ID
 
+    # Mac failures
+    self.Fail('conformance/glsl/misc/shaders-with-invariance.html',
+        ['mac'], bug=421710)
+
     # Mac / Intel failures
     # Radar 13499466
     self.Fail('conformance/limits/gl-max-texture-dimensions.html',
@@ -118,6 +97,10 @@
         'conformance/glsl/bugs/array-of-struct-with-int-first-position.html',
         ['mac', ('nvidia', 0xfd5), ('nvidia', 0xfe9)], bug=368912)
 
+    # Mac / AMD Failures
+    self.Fail('deqp/data/gles2/shaders/conversions.html',
+        ['mac', 'amd'], bug=478572)
+
     # Mac 10.8 / ATI failures
     self.Fail(
         'conformance/rendering/' +
@@ -201,6 +184,8 @@
     self.Fail('conformance/more/functions/texSubImage2DHTML.html',
         ['linux', ('amd', 0x68f9)], bug=436212)
     # AMD Radeon 6450
+    self.Fail('conformance/extensions/angle-instanced-arrays.html',
+        ['linux', ('amd', 0x6779)], bug=479260)
     self.Fail('conformance/extensions/ext-texture-filter-anisotropic.html',
         ['linux', ('amd', 0x6779)], bug=436212)
     self.Fail('conformance/glsl/misc/shader-struct-scope.html',
@@ -215,6 +200,15 @@
         ['linux', ('amd', 0x6779)], bug=436212)
 
     # Android failures
+    self.Fail('deqp/data/gles2/shaders/constants.html',
+        ['android'], bug=478572)
+    self.Fail('deqp/data/gles2/shaders/conversions.html',
+        ['android'], bug=478572)
+    self.Fail('deqp/data/gles2/shaders/declarations.html',
+        ['android'], bug=478572)
+    self.Fail('deqp/data/gles2/shaders/linkage.html',
+        ['android'], bug=478572)
+
     # The following test is very slow and therefore times out on Android bot.
     self.Skip('conformance/rendering/multisample-corruption.html',
         ['android'])
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index 3b24701..07f53ea 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -9,8 +9,8 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/renderer/scheduler/renderer_scheduler.h"
-#include "content/renderer/scheduler/webthread_impl_for_renderer_scheduler.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
 #include "content/test/mock_webclipboard_impl.h"
 #include "content/test/web_gesture_curve_mock.h"
 #include "content/test/web_layer_tree_view_impl_for_testing.h"
@@ -56,9 +56,9 @@
 #endif
 
   if (base::MessageLoopProxy::current()) {
-    renderer_scheduler_ = RendererScheduler::Create();
-    web_thread_.reset(
-        new WebThreadImplForRendererScheduler(renderer_scheduler_.get()));
+    renderer_scheduler_ = scheduler::RendererScheduler::Create();
+    web_thread_.reset(new scheduler::WebThreadImplForRendererScheduler(
+        renderer_scheduler_.get()));
   }
 
   blink::initialize(this);
diff --git a/content/test/test_blink_web_unit_test_support.h b/content/test/test_blink_web_unit_test_support.h
index 0b27e7b..66761cf 100644
--- a/content/test/test_blink_web_unit_test_support.h
+++ b/content/test/test_blink_web_unit_test_support.h
@@ -24,8 +24,11 @@
 class WebLayerTreeView;
 }
 
-namespace content {
+namespace scheduler {
 class RendererScheduler;
+}
+
+namespace content {
 
 // An implementation of blink::WebUnitTestSupport and BlinkPlatformImpl for
 // tests.
@@ -94,7 +97,7 @@
   base::ScopedTempDir file_system_root_;
   scoped_ptr<WebURLLoaderMockFactory> url_loader_factory_;
   cc_blink::WebCompositorSupportImpl compositor_support_;
-  scoped_ptr<RendererScheduler> renderer_scheduler_;
+  scoped_ptr<scheduler::RendererScheduler> renderer_scheduler_;
   scoped_ptr<blink::WebThread> web_thread_;
 
 #if defined(OS_WIN) || defined(OS_MACOSX)
diff --git a/content/test/test_frame_navigation_observer.cc b/content/test/test_frame_navigation_observer.cc
index c6d151bc..e3cbccecd 100644
--- a/content/test/test_frame_navigation_observer.cc
+++ b/content/test/test_frame_navigation_observer.cc
@@ -67,6 +67,7 @@
 
   ++navigations_completed_;
   if (navigations_completed_ == number_of_navigations_) {
+    load_committed_details_ = details;
     navigation_started_ = false;
     message_loop_runner_->Quit();
   }
diff --git a/content/test/test_frame_navigation_observer.h b/content/test/test_frame_navigation_observer.h
index 9ff42c53..5330c48 100644
--- a/content/test/test_frame_navigation_observer.h
+++ b/content/test/test_frame_navigation_observer.h
@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
+#include "content/public/browser/navigation_details.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/test/test_utils.h"
 
@@ -19,7 +20,6 @@
 class FrameTreeNode;
 class RenderFrameHostImpl;
 class WebContents;
-struct LoadCommittedDetails;
 
 // For content_browsertests, which run on the UI thread, run a second
 // MessageLoop and quit when the navigation in a specific frame completes
@@ -38,6 +38,11 @@
   // navigations are complete.
   void Wait();
 
+  // Returns the LoadCommittedDetails for the last navigation to commit.
+  const LoadCommittedDetails& load_committed_details() const {
+    return load_committed_details_;
+  }
+
  private:
   // WebContentsObserver
   void DidStartProvisionalLoadForFrame(RenderFrameHost* render_frame_host,
@@ -60,6 +65,8 @@
   // The number of navigations to wait for.
   int number_of_navigations_;
 
+  LoadCommittedDetails load_committed_details_;
+
   // The MessageLoopRunner used to spin the message loop.
   scoped_refptr<MessageLoopRunner> message_loop_runner_;
 
diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn
index 9f944e5b..27e786c 100644
--- a/crypto/BUILD.gn
+++ b/crypto/BUILD.gn
@@ -136,9 +136,6 @@
       "ec_signature_creator_nss.cc",
       "encryptor_nss.cc",
       "hmac_nss.cc",
-      "nss_util.cc",
-      "nss_util.h",
-      "nss_util_internal.h",
       "rsa_private_key_nss.cc",
       "secure_hash_default.cc",
       "signature_creator_nss.cc",
@@ -170,6 +167,16 @@
     ]
   }
 
+  # Remove nss_util when NSS is used for neither the internal crypto library
+  # nor the platform certificate library.
+  if (use_openssl && !use_nss_certs) {
+    sources -= [
+      "nss_util.cc",
+      "nss_util.h",
+      "nss_util_internal.h",
+    ]
+  }
+
   defines = [ "CRYPTO_IMPLEMENTATION" ]
 }
 
@@ -205,53 +212,54 @@
   }
 }
 
-# TODO(GYP): Make this link on win as well.
-if (!is_win) {
-  test("crypto_unittests") {
-    sources = [
-      # Tests.
-      "curve25519_unittest.cc",
-      "ec_private_key_unittest.cc",
-      "ec_signature_creator_unittest.cc",
-      "encryptor_unittest.cc",
-      "ghash_unittest.cc",
-      "hkdf_unittest.cc",
-      "hmac_unittest.cc",
-      "nss_util_unittest.cc",
-      "openssl_bio_string_unittest.cc",
-      "p224_spake_unittest.cc",
-      "p224_unittest.cc",
-      "random_unittest.cc",
-      "rsa_private_key_nss_unittest.cc",
-      "rsa_private_key_unittest.cc",
-      "secure_hash_unittest.cc",
-      "sha2_unittest.cc",
-      "signature_creator_unittest.cc",
-      "signature_verifier_unittest.cc",
-      "symmetric_key_unittest.cc",
-    ]
+test("crypto_unittests") {
+  sources = [
+    # Tests.
+    "curve25519_unittest.cc",
+    "ec_private_key_unittest.cc",
+    "ec_signature_creator_unittest.cc",
+    "encryptor_unittest.cc",
+    "ghash_unittest.cc",
+    "hkdf_unittest.cc",
+    "hmac_unittest.cc",
+    "nss_util_unittest.cc",
+    "openssl_bio_string_unittest.cc",
+    "p224_spake_unittest.cc",
+    "p224_unittest.cc",
+    "random_unittest.cc",
+    "rsa_private_key_nss_unittest.cc",
+    "rsa_private_key_unittest.cc",
+    "secure_hash_unittest.cc",
+    "sha2_unittest.cc",
+    "signature_creator_unittest.cc",
+    "signature_verifier_unittest.cc",
+    "symmetric_key_unittest.cc",
+  ]
 
-    if (use_openssl || !is_linux) {
-      sources -= [ "rsa_private_key_nss_unittest.cc" ]
-    }
-
-    if (use_openssl) {
-      sources -= [ "nss_util_unittest.cc" ]
-    } else {
-      sources -= [ "openssl_bio_string_unittest.cc" ]
-    }
-
-    deps = [
-      ":crypto",
-      ":platform",
-      ":test_support",
-      "//base",
-      "//base/test:run_all_unittests",
-      "//base/test:test_support",
-      "//testing/gmock",
-      "//testing/gtest",
-    ]
+  # Remove nss_util when NSS is used for neither the internal crypto library
+  # nor the platform certificate library.
+  if (use_openssl && !use_nss_certs) {
+    sources -= [ "nss_util_unittest.cc" ]
   }
+
+  if (use_openssl) {
+    sources -= [ "rsa_private_key_nss_unittest.cc" ]
+  } else {
+    sources -= [ "openssl_bio_string_unittest.cc" ]
+  }
+
+  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+  deps = [
+    ":crypto",
+    ":platform",
+    ":test_support",
+    "//base",
+    "//base/test:run_all_unittests",
+    "//base/test:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
 }
 
 source_set("test_support") {
@@ -287,7 +295,7 @@
 }
 
 config("platform_config") {
-  if (!use_openssl && is_clang) {
+  if ((!use_openssl || use_nss_certs) && is_clang) {
     # There is a broken header guard in /usr/include/nss/secmod.h:
     # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
     cflags = [ "-Wno-header-guard" ]
@@ -306,21 +314,26 @@
     deps = [
       "//net/third_party/nss/ssl:libssl",
     ]
+  }
+
+  # Link in NSS if it is used for either the internal crypto library
+  # (!use_openssl) or platform certificate library (use_nss_certs).
+  if (!use_openssl || use_nss_certs) {
     if (is_linux) {
       # On Linux, we use the system NSS (excepting SSL where we always use our
       # own).
-      #
-      # We always need our SSL header search path to come before the system one
-      # so our versions are used. The libssl target will add the search path we
-      # want, but according to GN's ordering rules, public_configs' search path
-      # will get applied before ones inherited from our dependencies.
-      # Therefore, we need to explicitly list our custom libssl's config here
-      # before the system one.
-      public_configs = [
-        ":platform_config",
-        "//net/third_party/nss/ssl:ssl_config",
-        "//third_party/nss:system_nss_no_ssl_config",
-      ]
+      public_configs = [ ":platform_config" ]
+      if (!use_openssl) {
+        # If using a bundled copy of NSS's SSL library, ensure the bundled SSL
+        # header search path comes before the system one so our versions are
+        # used. The libssl target will add the search path we want, but
+        # according to GN's ordering rules, public_configs' search path will get
+        # applied before ones inherited from our dependencies.  Therefore, we
+        # need to explicitly list our custom libssl's config here before the
+        # system one.
+        public_configs += [ "//net/third_party/nss/ssl:ssl_config" ]
+      }
+      public_configs += [ "//third_party/nss:system_nss_no_ssl_config" ]
     } else {
       # Non-Linux platforms use the hermetic NSS from the tree.
       deps += [
diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp
index c8551e70..a9cff553 100644
--- a/crypto/crypto.gyp
+++ b/crypto/crypto.gyp
@@ -108,9 +108,6 @@
               'ec_signature_creator_nss.cc',
               'encryptor_nss.cc',
               'hmac_nss.cc',
-              'nss_util.cc',
-              'nss_util.h',
-              'nss_util_internal.h',
               'rsa_private_key_nss.cc',
               'secure_hash_default.cc',
               'signature_creator_nss.cc',
@@ -143,6 +140,15 @@
               'symmetric_key_openssl.cc',
             ],
         },],
+        [ 'use_openssl==1 and use_nss_certs==0', {
+            # NSS is used for neither the internal crypto library nor the
+            # platform certificate library.
+            'sources!': [
+              'nss_util.cc',
+              'nss_util.h',
+              'nss_util_internal.h',
+            ],
+        },],
       ],
       'sources': [
         '<@(crypto_sources)',
@@ -182,7 +188,7 @@
         '../testing/gtest.gyp:gtest',
       ],
       'conditions': [
-        [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
+        [ 'use_nss_certs == 1', {
           'conditions': [
             [ 'use_allocator!="none"', {
                 'dependencies': [
@@ -194,10 +200,13 @@
           'dependencies': [
             '../build/linux/system.gyp:ssl',
           ],
-        }, {  # os_posix != 1 or OS == "mac" or OS == "android" or OS == "ios"
+        }],
+        [ 'use_openssl == 1 and use_nss_certs == 0', {
+          # nss_util is built if NSS is used for either the internal crypto
+          # library or the platform certificate library.
           'sources!': [
-            'rsa_private_key_nss_unittest.cc',
-          ]
+            'nss_util_unittest.cc',
+          ],
         }],
         [ 'use_openssl == 0 and (OS == "mac" or OS == "ios" or OS == "win")', {
           'dependencies': [
@@ -213,7 +222,6 @@
             '../third_party/boringssl/boringssl.gyp:boringssl',
           ],
           'sources!': [
-            'nss_util_unittest.cc',
             'rsa_private_key_nss_unittest.cc',
           ],
         }, {
diff --git a/crypto/crypto_nacl.gyp b/crypto/crypto_nacl.gyp
index 4451610..255c42c 100644
--- a/crypto/crypto_nacl.gyp
+++ b/crypto/crypto_nacl.gyp
@@ -23,7 +23,6 @@
       },
       'dependencies': [
         '../third_party/boringssl/boringssl_nacl.gyp:boringssl_nacl',
-        '../native_client/tools.gyp:prep_toolchain',
         '../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
       ],
       'defines': [
diff --git a/crypto/rsa_private_key.h b/crypto/rsa_private_key.h
index 78a660e..9ab9c57 100644
--- a/crypto/rsa_private_key.h
+++ b/crypto/rsa_private_key.h
@@ -180,7 +180,22 @@
   static RSAPrivateKey* CreateFromPrivateKeyInfo(
       const std::vector<uint8>& input);
 
-#if defined(USE_NSS_CERTS)
+#if defined(USE_OPENSSL)
+  // Create a new instance from an existing EVP_PKEY, taking a
+  // reference to it. |key| must be an RSA key. Returns NULL on
+  // failure.
+  static RSAPrivateKey* CreateFromKey(EVP_PKEY* key);
+#else
+  // Create a new instance by referencing an existing private key
+  // structure.  Does not import the key.
+  static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
+#endif
+
+  // TODO(davidben): These functions are used when NSS is the platform key
+  // store, but they also assume that the internal crypto library is NSS. Split
+  // out the convenience NSS platform key methods from the logic which expects
+  // an RSAPrivateKey. See https://crbug.com/478777.
+#if defined(USE_NSS_CERTS) && !defined(USE_OPENSSL)
   // Create a new random instance in |slot|. Can return NULL if initialization
   // fails.  The created key is permanent and is not exportable in plaintext
   // form.
@@ -194,10 +209,6 @@
       PK11SlotInfo* slot,
       const std::vector<uint8>& input);
 
-  // Create a new instance by referencing an existing private key
-  // structure.  Does not import the key.
-  static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
-
   // Import an existing public key, and then search for the private
   // half in the key database. The format of the public key blob is is
   // an X509 SubjectPublicKeyInfo block. This can return NULL if
@@ -216,13 +227,7 @@
   static RSAPrivateKey* FindFromPublicKeyInfoInSlot(
       const std::vector<uint8>& input,
       PK11SlotInfo* slot);
-#elif defined(USE_OPENSSL)
-  // Create a new instance from an existing EVP_PKEY, taking a
-  // reference to it. |key| must be an RSA key. Returns NULL on
-  // failure.
-  static RSAPrivateKey* CreateFromKey(EVP_PKEY* key);
-
-#endif
+#endif  // USE_NSS_CERTS && !USE_OPENSSL
 
 #if defined(USE_OPENSSL)
   EVP_PKEY* key() { return key_; }
diff --git a/crypto/rsa_private_key_nss.cc b/crypto/rsa_private_key_nss.cc
index 45b2be76..c9e6a87f 100644
--- a/crypto/rsa_private_key_nss.cc
+++ b/crypto/rsa_private_key_nss.cc
@@ -104,6 +104,22 @@
       false /* not sensitive */);
 }
 
+// static
+RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) {
+  DCHECK(key);
+  if (SECKEY_GetPrivateKeyType(key) != rsaKey)
+    return NULL;
+  RSAPrivateKey* copy = new RSAPrivateKey();
+  copy->key_ = SECKEY_CopyPrivateKey(key);
+  copy->public_key_ = SECKEY_ConvertToPublicKey(key);
+  if (!copy->key_ || !copy->public_key_) {
+    NOTREACHED();
+    delete copy;
+    return NULL;
+  }
+  return copy;
+}
+
 #if defined(USE_NSS_CERTS)
 // static
 RSAPrivateKey* RSAPrivateKey::CreateSensitive(PK11SlotInfo* slot,
@@ -125,22 +141,6 @@
 }
 
 // static
-RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) {
-  DCHECK(key);
-  if (SECKEY_GetPrivateKeyType(key) != rsaKey)
-    return NULL;
-  RSAPrivateKey* copy = new RSAPrivateKey();
-  copy->key_ = SECKEY_CopyPrivateKey(key);
-  copy->public_key_ = SECKEY_ConvertToPublicKey(key);
-  if (!copy->key_ || !copy->public_key_) {
-    NOTREACHED();
-    delete copy;
-    return NULL;
-  }
-  return copy;
-}
-
-// static
 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
     const std::vector<uint8>& input) {
   scoped_ptr<RSAPrivateKey> result(InitPublicPart(input));
diff --git a/crypto/rsa_private_key_nss_unittest.cc b/crypto/rsa_private_key_nss_unittest.cc
index 98360e8..dad6688 100644
--- a/crypto/rsa_private_key_nss_unittest.cc
+++ b/crypto/rsa_private_key_nss_unittest.cc
@@ -13,6 +13,10 @@
 
 namespace crypto {
 
+// TODO(davidben): These tests assume NSS is used for both the internal crypto
+// library and the platform key store. See https://crbug.com/478777.
+#if defined(USE_NSS_CERTS)
+
 class RSAPrivateKeyNSSTest : public testing::Test {
  public:
   RSAPrivateKeyNSSTest() {}
@@ -57,4 +61,6 @@
   EXPECT_EQ(NULL, crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
 }
 
+#endif  // USE_NSS_CERTS
+
 }  // namespace crypto
diff --git a/crypto/rsa_private_key_unittest.cc b/crypto/rsa_private_key_unittest.cc
index ee5b1217..b231cac 100644
--- a/crypto/rsa_private_key_unittest.cc
+++ b/crypto/rsa_private_key_unittest.cc
@@ -445,9 +445,6 @@
                           input2.size()));
 }
 
-// The following test can run if either USE_NSS_CERTS or USE_OPENSSL is defined,
-// but not otherwise (since it uses crypto::RSAPrivateKey::CreateFromKey).
-#if defined(USE_NSS_CERTS) || defined(USE_OPENSSL)
 TEST(RSAPrivateKeyUnitTest, CreateFromKeyTest) {
   scoped_ptr<crypto::RSAPrivateKey> key_pair(
       crypto::RSAPrivateKey::Create(256));
@@ -469,5 +466,4 @@
   ASSERT_EQ(privkey, privkey_copy);
   ASSERT_EQ(pubkey, pubkey_copy);
 }
-#endif
 
diff --git a/dbus/mock_object_proxy.h b/dbus/mock_object_proxy.h
index 7c61b47..66f485a 100644
--- a/dbus/mock_object_proxy.h
+++ b/dbus/mock_object_proxy.h
@@ -29,7 +29,7 @@
                Response*(MethodCall* method_call,
                          int timeout_ms,
                          ScopedDBusError* error));
-  virtual scoped_ptr<Response> CallMethodAndBlockWithErrorDetails(
+  scoped_ptr<Response> CallMethodAndBlockWithErrorDetails(
       MethodCall* method_call,
       int timeout_ms,
       ScopedDBusError* error) override {
@@ -38,8 +38,8 @@
   }
   MOCK_METHOD2(MockCallMethodAndBlock, Response*(MethodCall* method_call,
                                                  int timeout_ms));
-  virtual scoped_ptr<Response> CallMethodAndBlock(MethodCall* method_call,
-                                                  int timeout_ms) override {
+  scoped_ptr<Response> CallMethodAndBlock(MethodCall* method_call,
+                                          int timeout_ms) override {
     return scoped_ptr<Response>(MockCallMethodAndBlock(method_call,
                                                        timeout_ms));
   }
@@ -58,7 +58,7 @@
   MOCK_METHOD0(Detach, void());
 
  protected:
-  virtual ~MockObjectProxy();
+  ~MockObjectProxy() override;
 };
 
 }  // namespace dbus
diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc
index fd2e29b3..23fde08 100644
--- a/device/bluetooth/bluetooth_adapter.cc
+++ b/device/bluetooth/bluetooth_adapter.cc
@@ -24,22 +24,30 @@
 }
 #endif  // !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
 
+base::WeakPtr<BluetoothAdapter> BluetoothAdapter::GetWeakPtrForTesting() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 #if defined(OS_CHROMEOS)
 void BluetoothAdapter::Shutdown() {
   NOTIMPLEMENTED();
 }
 #endif
 
-BluetoothAdapter::BluetoothAdapter()
-    : weak_ptr_factory_(this) {
+void BluetoothAdapter::AddObserver(BluetoothAdapter::Observer* observer) {
+  DCHECK(observer);
+  observers_.AddObserver(observer);
 }
 
-BluetoothAdapter::~BluetoothAdapter() {
-  STLDeleteValues(&devices_);
+void BluetoothAdapter::RemoveObserver(BluetoothAdapter::Observer* observer) {
+  DCHECK(observer);
+  observers_.RemoveObserver(observer);
 }
 
-base::WeakPtr<BluetoothAdapter> BluetoothAdapter::GetWeakPtrForTesting() {
-  return weak_ptr_factory_.GetWeakPtr();
+void BluetoothAdapter::StartDiscoverySession(
+    const DiscoverySessionCallback& callback,
+    const ErrorCallback& error_callback) {
+  StartDiscoverySessionWithFilter(nullptr, callback, error_callback);
 }
 
 void BluetoothAdapter::StartDiscoverySessionWithFilter(
@@ -53,50 +61,6 @@
                       error_callback);
 }
 
-void BluetoothAdapter::StartDiscoverySession(
-    const DiscoverySessionCallback& callback,
-    const ErrorCallback& error_callback) {
-  StartDiscoverySessionWithFilter(nullptr, callback, error_callback);
-}
-
-scoped_ptr<BluetoothDiscoveryFilter>
-BluetoothAdapter::GetMergedDiscoveryFilterHelper(
-    const BluetoothDiscoveryFilter* masked_filter,
-    bool omit) const {
-  scoped_ptr<BluetoothDiscoveryFilter> result;
-  bool first_merge = true;
-
-  std::set<BluetoothDiscoverySession*> temp(discovery_sessions_);
-  for (const auto& iter : temp) {
-    const BluetoothDiscoveryFilter* curr_filter = iter->GetDiscoveryFilter();
-
-    if (!iter->IsActive())
-      continue;
-
-    if (omit && curr_filter == masked_filter) {
-      // if masked_filter is pointing to empty filter, and there are
-      // multiple empty filters in discovery_sessions_, make sure we'll
-      // process next empty sessions.
-      omit = false;
-      continue;
-    }
-
-    if (first_merge) {
-      first_merge = false;
-      if (curr_filter) {
-        result.reset(new BluetoothDiscoveryFilter(
-            BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL));
-        result->CopyFrom(*curr_filter);
-      }
-      continue;
-    }
-
-    result = BluetoothDiscoveryFilter::Merge(result.get(), curr_filter);
-  }
-
-  return result.Pass();
-}
-
 scoped_ptr<BluetoothDiscoveryFilter>
 BluetoothAdapter::GetMergedDiscoveryFilter() const {
   return GetMergedDiscoveryFilterHelper(nullptr, false);
@@ -183,6 +147,13 @@
   return pairing_delegates_.front().first;
 }
 
+BluetoothAdapter::BluetoothAdapter() : weak_ptr_factory_(this) {
+}
+
+BluetoothAdapter::~BluetoothAdapter() {
+  STLDeleteValues(&devices_);
+}
+
 void BluetoothAdapter::OnStartDiscoverySession(
     scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
     const DiscoverySessionCallback& callback) {
@@ -213,4 +184,42 @@
   discovery_sessions_.erase(discovery_session);
 }
 
+scoped_ptr<BluetoothDiscoveryFilter>
+BluetoothAdapter::GetMergedDiscoveryFilterHelper(
+    const BluetoothDiscoveryFilter* masked_filter,
+    bool omit) const {
+  scoped_ptr<BluetoothDiscoveryFilter> result;
+  bool first_merge = true;
+
+  std::set<BluetoothDiscoverySession*> temp(discovery_sessions_);
+  for (const auto& iter : temp) {
+    const BluetoothDiscoveryFilter* curr_filter = iter->GetDiscoveryFilter();
+
+    if (!iter->IsActive())
+      continue;
+
+    if (omit && curr_filter == masked_filter) {
+      // if masked_filter is pointing to empty filter, and there are
+      // multiple empty filters in discovery_sessions_, make sure we'll
+      // process next empty sessions.
+      omit = false;
+      continue;
+    }
+
+    if (first_merge) {
+      first_merge = false;
+      if (curr_filter) {
+        result.reset(new BluetoothDiscoveryFilter(
+            BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL));
+        result->CopyFrom(*curr_filter);
+      }
+      continue;
+    }
+
+    result = BluetoothDiscoveryFilter::Merge(result.get(), curr_filter);
+  }
+
+  return result.Pass();
+}
+
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index d764ae97..87734d2 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -36,8 +36,7 @@
 // known to the adapter, discovering new devices, and providing notification of
 // updates to device information.
 class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
-    : public base::RefCountedThreadSafe<BluetoothAdapter,
-                                        BluetoothAdapterDeleter> {
+    : public base::RefCounted<BluetoothAdapter> {
  public:
   // Interface for observing changes from bluetooth adapters.
   class Observer {
@@ -181,6 +180,17 @@
   // initialization, if initialization is asynchronous on the platform.
   typedef base::Callback<void()> InitCallback;
 
+  typedef base::Callback<void(scoped_ptr<BluetoothDiscoverySession>)>
+      DiscoverySessionCallback;
+  typedef std::vector<BluetoothDevice*> DeviceList;
+  typedef std::vector<const BluetoothDevice*> ConstDeviceList;
+  typedef base::Callback<void(scoped_refptr<BluetoothSocket>)>
+      CreateServiceCallback;
+  typedef base::Callback<void(const std::string& message)>
+      CreateServiceErrorCallback;
+  typedef base::Callback<void(scoped_refptr<BluetoothAudioSink>)>
+      AcquiredCallback;
+
   // Returns a weak pointer to a new adapter.  For platforms with asynchronous
   // initialization, the returned adapter will run the |init_callback| once
   // asynchronous initialization is complete.
@@ -204,9 +214,8 @@
   // Adds and removes observers for events on this bluetooth adapter. If
   // monitoring multiple adapters, check the |adapter| parameter of observer
   // methods to determine which adapter is issuing the event.
-  virtual void AddObserver(BluetoothAdapter::Observer* observer) = 0;
-  virtual void RemoveObserver(
-      BluetoothAdapter::Observer* observer) = 0;
+  virtual void AddObserver(BluetoothAdapter::Observer* observer);
+  virtual void RemoveObserver(BluetoothAdapter::Observer* observer);
 
   // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX",
   // where each XX is a hexadecimal number.
@@ -270,8 +279,6 @@
   // that have been discovered so far. Otherwise, clients can be notified of all
   // new and lost devices by implementing the Observer methods "DeviceAdded" and
   // "DeviceRemoved".
-  typedef base::Callback<void(scoped_ptr<BluetoothDiscoverySession>)>
-      DiscoverySessionCallback;
   virtual void StartDiscoverySession(const DiscoverySessionCallback& callback,
                                      const ErrorCallback& error_callback);
   virtual void StartDiscoverySessionWithFilter(
@@ -291,9 +298,7 @@
   // Requests the list of devices from the adapter. All devices are returned,
   // including those currently connected and those paired. Use the returned
   // device pointers to determine which they are.
-  typedef std::vector<BluetoothDevice*> DeviceList;
   virtual DeviceList GetDevices();
-  typedef std::vector<const BluetoothDevice*> ConstDeviceList;
   virtual ConstDeviceList GetDevices() const;
 
   // Returns a pointer to the device with the given address |address| or NULL if
@@ -335,10 +340,6 @@
   // called on success with a BluetoothSocket instance that is to be owned by
   // the received.  |error_callback| will be called on failure with a message
   // indicating the cause.
-  typedef base::Callback<void(scoped_refptr<BluetoothSocket>)>
-      CreateServiceCallback;
-  typedef base::Callback<void(const std::string& message)>
-      CreateServiceErrorCallback;
   virtual void CreateRfcommService(
       const BluetoothUUID& uuid,
       const ServiceOptions& options,
@@ -363,24 +364,22 @@
   // will be called on success with a BluetoothAudioSink which is to be owned by
   // the caller of this method. |error_callback| will be called on failure with
   // a message indicating the cause.
-  typedef base::Callback<void(scoped_refptr<BluetoothAudioSink>)>
-      AcquiredCallback;
   virtual void RegisterAudioSink(
       const BluetoothAudioSink::Options& options,
       const AcquiredCallback& callback,
       const BluetoothAudioSink::ErrorCallback& error_callback) = 0;
 
  protected:
-  friend class base::RefCountedThreadSafe<BluetoothAdapter,
-                                          BluetoothAdapterDeleter>;
-  friend struct BluetoothAdapterDeleter;
+  friend class base::RefCounted<BluetoothAdapter>;
   friend class BluetoothDiscoverySession;
+
+  typedef std::map<const std::string, BluetoothDevice*> DevicesMap;
+  typedef std::pair<BluetoothDevice::PairingDelegate*, PairingDelegatePriority>
+      PairingDelegatePair;
+
   BluetoothAdapter();
   virtual ~BluetoothAdapter();
 
-  // Called by RefCountedThreadSafeDeleteOnCorrectThread to destroy this.
-  virtual void DeleteOnCorrectThread() const = 0;
-
   // Internal methods for initiating and terminating device discovery sessions.
   // An implementation of BluetoothAdapter keeps an internal reference count to
   // make sure that the underlying controller is constantly searching for nearby
@@ -448,16 +447,16 @@
   void DiscoverySessionBecameInactive(
       BluetoothDiscoverySession* discovery_session);
 
+  // Observers of BluetoothAdapter, notified from implementation subclasses.
+  ObserverList<device::BluetoothAdapter::Observer> observers_;
+
   // Devices paired with, connected to, discovered by, or visible to the
   // adapter. The key is the Bluetooth address of the device and the value is
   // the BluetoothDevice object whose lifetime is managed by the adapter
   // instance.
-  typedef std::map<const std::string, BluetoothDevice*> DevicesMap;
   DevicesMap devices_;
 
   // Default pairing delegates registered with the adapter.
-  typedef std::pair<BluetoothDevice::PairingDelegate*,
-                    PairingDelegatePriority> PairingDelegatePair;
   std::list<PairingDelegatePair> pairing_delegates_;
 
  private:
@@ -480,13 +479,6 @@
   base::WeakPtrFactory<BluetoothAdapter> weak_ptr_factory_;
 };
 
-// Trait for RefCountedThreadSafe that deletes BluetoothAdapter.
-struct BluetoothAdapterDeleter {
-  static void Destruct(const BluetoothAdapter* adapter) {
-    adapter->DeleteOnCorrectThread();
-  }
-};
-
 }  // namespace device
 
 #endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc
index b9cdd09..26a029bd 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos.cc
@@ -138,24 +138,6 @@
   Shutdown();
 }
 
-void BluetoothAdapterChromeOS::DeleteOnCorrectThread() const {
-  if (ui_task_runner_->RunsTasksOnCurrentThread() ||
-      !ui_task_runner_->DeleteSoon(FROM_HERE, this))
-    delete this;
-}
-
-void BluetoothAdapterChromeOS::AddObserver(
-    BluetoothAdapter::Observer* observer) {
-  DCHECK(observer);
-  observers_.AddObserver(observer);
-}
-
-void BluetoothAdapterChromeOS::RemoveObserver(
-    BluetoothAdapter::Observer* observer) {
-  DCHECK(observer);
-  observers_.RemoveObserver(observer);
-}
-
 std::string BluetoothAdapterChromeOS::GetAddress() const {
   if (!IsPresent())
     return std::string();
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h
index cc5fb1d..7b17f53 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_chromeos.h
@@ -65,9 +65,6 @@
 
   // BluetoothAdapter:
   void Shutdown() override;
-  void DeleteOnCorrectThread() const override;
-  void AddObserver(device::BluetoothAdapter::Observer* observer) override;
-  void RemoveObserver(device::BluetoothAdapter::Observer* observer) override;
   std::string GetAddress() const override;
   std::string GetName() const override;
   void SetName(const std::string& name,
@@ -156,7 +153,6 @@
       device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
 
  private:
-  friend class base::DeleteHelper<BluetoothAdapterChromeOS>;
   friend class BluetoothChromeOSTest;
   friend class BluetoothChromeOSTest_Shutdown_Test;
   friend class BluetoothChromeOSTest_Shutdown_OnStartDiscovery_Test;
@@ -172,6 +168,10 @@
                      ErrorCallback> DiscoveryParamTuple;
   typedef std::queue<DiscoveryParamTuple> DiscoveryCallbackQueue;
 
+  // Callback pair for the profile registration queue.
+  typedef std::pair<base::Closure, ErrorCompletionCallback>
+      RegisterProfileCompletionPair;
+
   BluetoothAdapterChromeOS();
   ~BluetoothAdapterChromeOS() override;
 
@@ -349,9 +349,6 @@
   // Object path of the adapter we track.
   dbus::ObjectPath object_path_;
 
-  // List of observers interested in event notifications from us.
-  ObserverList<device::BluetoothAdapter::Observer> observers_;
-
   // Instance of the D-Bus agent object used for pairing, initialized with
   // our own class as its delegate.
   scoped_ptr<BluetoothAgentServiceProvider> agent_;
@@ -363,10 +360,6 @@
   // The profiles we have registered with the bluetooth daemon.
   std::map<device::BluetoothUUID, BluetoothAdapterProfileChromeOS*> profiles_;
 
-  // Callback pair for the profile registration queue.
-  typedef std::pair<base::Closure, ErrorCompletionCallback>
-      RegisterProfileCompletionPair;
-
   // Queue of delegates waiting for a profile to register.
   std::map<device::BluetoothUUID, std::vector<RegisterProfileCompletionPair>*>
       profile_queues_;
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h
index bca4389..14d5a2b 100644
--- a/device/bluetooth/bluetooth_adapter_mac.h
+++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -41,8 +41,6 @@
   static base::WeakPtr<BluetoothAdapter> CreateAdapter();
 
   // BluetoothAdapter:
-  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,
@@ -87,14 +85,12 @@
       device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
 
  private:
-  friend class base::DeleteHelper<BluetoothAdapterMac>;
   friend class BluetoothAdapterMacTest;
 
   BluetoothAdapterMac();
   ~BluetoothAdapterMac() override;
 
   // BluetoothAdapter:
-  void DeleteOnCorrectThread() const override;
   void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
                            const base::Closure& callback,
                            const ErrorCallback& error_callback) override;
@@ -129,9 +125,6 @@
 
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
 
-  // List of observers interested in event notifications from us.
-  ObserverList<BluetoothAdapter::Observer> observers_;
-
   base::WeakPtrFactory<BluetoothAdapterMac> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterMac);
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 7c04a433..a528bd7 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -64,16 +64,6 @@
 BluetoothAdapterMac::~BluetoothAdapterMac() {
 }
 
-void BluetoothAdapterMac::AddObserver(BluetoothAdapter::Observer* observer) {
-  DCHECK(observer);
-  observers_.AddObserver(observer);
-}
-
-void BluetoothAdapterMac::RemoveObserver(BluetoothAdapter::Observer* observer) {
-  DCHECK(observer);
-  observers_.RemoveObserver(observer);
-}
-
 std::string BluetoothAdapterMac::GetAddress() const {
   return address_;
 }
@@ -173,12 +163,6 @@
   DeviceAdded(device);
 }
 
-void BluetoothAdapterMac::DeleteOnCorrectThread() const {
-  if (ui_task_runner_->RunsTasksOnCurrentThread() ||
-      !ui_task_runner_->DeleteSoon(FROM_HERE, this))
-    delete this;
-}
-
 void BluetoothAdapterMac::AddDiscoverySession(
     BluetoothDiscoveryFilter* discovery_filter,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc
index 81e2dcb..c028b97 100644
--- a/device/bluetooth/bluetooth_adapter_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -19,10 +19,6 @@
   TestBluetoothAdapter() {
   }
 
-  void AddObserver(BluetoothAdapter::Observer* observer) override {}
-
-  void RemoveObserver(BluetoothAdapter::Observer* observer) override {}
-
   std::string GetAddress() const override { return ""; }
 
   std::string GetName() const override { return ""; }
@@ -49,8 +45,6 @@
 
   bool IsDiscovering() const override { return false; }
 
-  void DeleteOnCorrectThread() const override { delete this; }
-
   void StartDiscoverySessionWithFilter(
       scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
       const DiscoverySessionCallback& callback,
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc
index a9fc20034..4f49788 100644
--- a/device/bluetooth/bluetooth_adapter_win.cc
+++ b/device/bluetooth/bluetooth_adapter_win.cc
@@ -53,16 +53,6 @@
   }
 }
 
-void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
-  DCHECK(observer);
-  observers_.AddObserver(observer);
-}
-
-void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
-  DCHECK(observer);
-  observers_.RemoveObserver(observer);
-}
-
 std::string BluetoothAdapterWin::GetAddress() const {
   return address_;
 }
@@ -291,12 +281,6 @@
   }
 }
 
-void BluetoothAdapterWin::DeleteOnCorrectThread() const {
-  if (ui_task_runner_->RunsTasksOnCurrentThread() ||
-      !ui_task_runner_->DeleteSoon(FROM_HERE, this))
-    delete this;
-}
-
 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
 void BluetoothAdapterWin::AddDiscoverySession(
diff --git a/device/bluetooth/bluetooth_adapter_win.h b/device/bluetooth/bluetooth_adapter_win.h
index 2b086a2f..3bb26c9 100644
--- a/device/bluetooth/bluetooth_adapter_win.h
+++ b/device/bluetooth/bluetooth_adapter_win.h
@@ -41,8 +41,6 @@
       const InitCallback& init_callback);
 
   // 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,
@@ -97,7 +95,6 @@
       device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
 
  private:
-  friend class base::DeleteHelper<BluetoothAdapterWin>;
   friend class BluetoothAdapterWinTest;
 
   enum DiscoveryStatus {
@@ -111,7 +108,6 @@
   virtual ~BluetoothAdapterWin();
 
   // BluetoothAdapter:
-  void DeleteOnCorrectThread() const override;
   virtual void AddDiscoverySession(
       BluetoothDiscoveryFilter* discovery_filter,
       const base::Closure& callback,
@@ -152,9 +148,6 @@
 
   base::ThreadChecker thread_checker_;
 
-  // List of observers interested in event notifications from us.
-  ObserverList<BluetoothAdapter::Observer> observers_;
-
   // NOTE: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAdapterWin> weak_ptr_factory_;
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index f1abf31..1b9b3a9 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -97,6 +97,8 @@
     ERROR_UNSUPPORTED_DEVICE
   };
 
+  typedef std::vector<BluetoothUUID> UUIDList;
+
   // Interface for negotiating pairing of bluetooth devices.
   class PairingDelegate {
    public:
@@ -254,7 +256,6 @@
   // devices this data is collected from both the EIR data and SDP tables,
   // for Low Energy devices this data is collected from AD and GATT primary
   // services, for dual mode devices this may be collected from both./
-  typedef std::vector<BluetoothUUID> UUIDList;
   virtual UUIDList GetUUIDs() const = 0;
 
   // The ErrorCallback is used for methods that can fail in which case it
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h
index ee36d37d..9a6edd5 100644
--- a/device/bluetooth/bluetooth_device_win.h
+++ b/device/bluetooth/bluetooth_device_win.h
@@ -92,6 +92,8 @@
  private:
   friend class BluetoothAdapterWin;
 
+  typedef ScopedVector<BluetoothServiceRecordWin> ServiceRecordList;
+
   // Used by BluetoothAdapterWin to update the visible state during
   // discovery.
   void SetVisible(bool visible);
@@ -127,7 +129,6 @@
   UUIDList uuids_;
 
   // The service records retrieved from SDP.
-  typedef ScopedVector<BluetoothServiceRecordWin> ServiceRecordList;
   ServiceRecordList service_record_list_;
 
   DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWin);
diff --git a/device/bluetooth/bluetooth_gatt_descriptor.h b/device/bluetooth/bluetooth_gatt_descriptor.h
index 442a6ae..c91de1c 100644
--- a/device/bluetooth/bluetooth_gatt_descriptor.h
+++ b/device/bluetooth/bluetooth_gatt_descriptor.h
@@ -21,6 +21,14 @@
 // characteristic's features or to control certain behaviors.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptor {
  public:
+  // The ErrorCallback is used by methods to asynchronously report errors.
+  typedef base::Callback<void(BluetoothGattService::GattErrorCode)>
+      ErrorCallback;
+
+  // The ValueCallback is used to return the value of a remote characteristic
+  // descriptor upon a read request.
+  typedef base::Callback<void(const std::vector<uint8>&)> ValueCallback;
+
   // The Bluetooth Specification declares several predefined descriptors that
   // profiles can use. The following are definitions for the list of UUIDs
   // and descriptions of the characteristic descriptors that they represent.
@@ -106,14 +114,6 @@
   // handled by the subsystem.
   static const BluetoothUUID& CharacteristicAggregateFormatUuid();
 
-  // The ErrorCallback is used by methods to asynchronously report errors.
-  typedef base::Callback<void(BluetoothGattService::GattErrorCode)>
-      ErrorCallback;
-
-  // The ValueCallback is used to return the value of a remote characteristic
-  // descriptor upon a read request.
-  typedef base::Callback<void(const std::vector<uint8>&)> ValueCallback;
-
   // Constructs a BluetoothGattDescriptor that can be associated with a local
   // GATT characteristic when the adapter is in the peripheral role. To
   // associate the returned descriptor with a characteristic, add it to a local
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
index 077aff1..a23a1178 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
@@ -70,6 +70,9 @@
  private:
   friend class BluetoothRemoteGattServiceChromeOS;
 
+  typedef std::pair<NotifySessionCallback, ErrorCallback>
+      PendingStartNotifyCall;
+
   BluetoothRemoteGattCharacteristicChromeOS(
       BluetoothRemoteGattServiceChromeOS* service,
       const dbus::ObjectPath& object_path);
@@ -121,8 +124,6 @@
 
   // Calls to StartNotifySession that are pending. This can happen during the
   // first remote call to start notifications.
-  typedef std::pair<NotifySessionCallback, ErrorCallback>
-      PendingStartNotifyCall;
   std::queue<PendingStartNotifyCall> pending_start_notify_calls_;
 
   // True, if a Start or Stop notify call to bluetoothd is currently pending.
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
index 6694553..9aa8fdd 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
@@ -96,6 +96,9 @@
  private:
   friend class BluetoothDeviceChromeOS;
 
+  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattCharacteristicChromeOS*>
+      CharacteristicMap;
+
   BluetoothRemoteGattServiceChromeOS(BluetoothAdapterChromeOS* adapter,
                                      BluetoothDeviceChromeOS* device,
                                      const dbus::ObjectPath& object_path);
@@ -127,8 +130,6 @@
   // owned by this service. Since the Chrome OS implementation uses object
   // paths as unique identifiers, we also use this mapping to return
   // characteristics by identifier.
-  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattCharacteristicChromeOS*>
-      CharacteristicMap;
   CharacteristicMap characteristics_;
 
   // Indicates whether or not the characteristics of this service are known to
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.cc b/device/bluetooth/test/mock_bluetooth_adapter.cc
index a021bfd..615239b 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.cc
+++ b/device/bluetooth/test/mock_bluetooth_adapter.cc
@@ -19,10 +19,6 @@
 }
 #endif
 
-void MockBluetoothAdapter::DeleteOnCorrectThread() const {
-  delete this;
-};
-
 void MockBluetoothAdapter::AddDiscoverySession(
     BluetoothDiscoveryFilter* discovery_filter,
     const base::Closure& callback,
@@ -39,6 +35,7 @@
     scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
+  SetDiscoveryFilterRaw(discovery_filter.get(), callback, error_callback);
 }
 
 void MockBluetoothAdapter::StartDiscoverySessionWithFilter(
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index 3abe858..37f6450 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -65,6 +65,10 @@
                void(const BluetoothDiscoveryFilter*,
                     const DiscoverySessionCallback& callback,
                     const ErrorCallback& error_callback));
+  MOCK_METHOD3(SetDiscoveryFilterRaw,
+               void(const BluetoothDiscoveryFilter*,
+                    const base::Closure& callback,
+                    const ErrorCallback& error_callback));
   MOCK_CONST_METHOD0(GetDevices, BluetoothAdapter::ConstDeviceList());
   MOCK_METHOD1(GetDevice, BluetoothDevice*(const std::string& address));
   MOCK_CONST_METHOD1(GetDevice,
@@ -96,7 +100,6 @@
       const ErrorCallback& error_callback);
 
  protected:
-  void DeleteOnCorrectThread() const override;
   void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
                            const base::Closure& callback,
                            const ErrorCallback& error_callback) override;
diff --git a/device/bluetooth/test/mock_bluetooth_discovery_session.cc b/device/bluetooth/test/mock_bluetooth_discovery_session.cc
index 1aea85a..08f3dae 100644
--- a/device/bluetooth/test/mock_bluetooth_discovery_session.cc
+++ b/device/bluetooth/test/mock_bluetooth_discovery_session.cc
@@ -21,4 +21,11 @@
 }
 MockBluetoothDiscoverySession::~MockBluetoothDiscoverySession() {}
 
+void MockBluetoothDiscoverySession::SetDiscoveryFilter(
+    scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+    const base::Closure& callback,
+    const ErrorCallback& error_callback) {
+  SetDiscoveryFilterRaw(discovery_filter.get(), callback, error_callback);
+}
+
 }  // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_discovery_session.h b/device/bluetooth/test/mock_bluetooth_discovery_session.h
index bd724a7..e9009a8 100644
--- a/device/bluetooth/test/mock_bluetooth_discovery_session.h
+++ b/device/bluetooth/test/mock_bluetooth_discovery_session.h
@@ -20,6 +20,15 @@
   MOCK_METHOD2(Stop,
                void(const base::Closure& callback,
                     const ErrorCallback& error_callback));
+  MOCK_METHOD3(SetDiscoveryFilterRaw,
+               void(BluetoothDiscoveryFilter* discovery_filter,
+                    const base::Closure& callback,
+                    const ErrorCallback& error_callback));
+
+ protected:
+  void SetDiscoveryFilter(scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+                          const base::Closure& callback,
+                          const ErrorCallback& error_callback) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockBluetoothDiscoverySession);
diff --git a/device/test/data/bluetooth/invalid_uuid.xml b/device/test/data/bluetooth/invalid_uuid.xml
deleted file mode 100644
index 2b333047..0000000
--- a/device/test/data/bluetooth/invalid_uuid.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<record>
-	<attribute id="0x0001">
-		<sequence>
-			<uuid value="01234567:89AB-CDEF-0123-456789ABCDEF" />
-		</sequence>
-	</attribute>
-</record>
diff --git a/device/test/data/bluetooth/medium_uuid.xml b/device/test/data/bluetooth/medium_uuid.xml
deleted file mode 100644
index 432d7fe..0000000
--- a/device/test/data/bluetooth/medium_uuid.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<record>
-	<attribute id="0x0001">
-		<sequence>
-			<uuid value="0x00001101" />
-		</sequence>
-	</attribute>
-</record>
diff --git a/device/test/data/bluetooth/rfcomm.xml b/device/test/data/bluetooth/rfcomm.xml
deleted file mode 100644
index ec3bdec..0000000
--- a/device/test/data/bluetooth/rfcomm.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<record>
-	<attribute id="0x0000">
-		<uint32 value="0x00010003" />
-	</attribute>
-	<attribute id="0x0001">
-		<sequence>
-			<uuid value="01234567-89ab-cdef-0123-456789abcdef" />
-		</sequence>
-	</attribute>
-	<attribute id="0x0004">
-		<sequence>
-			<sequence>
-				<uuid value="0x0100" />
-			</sequence>
-			<sequence>
-				<uuid value="0x0003" />
-				<uint8 value="0x0c" />
-			</sequence>
-		</sequence>
-	</attribute>
-	<attribute id="0x0005">
-		<sequence>
-			<uuid value="0x1002" />
-		</sequence>
-	</attribute>
-	<attribute id="0x0009">
-		<sequence>
-			<sequence>
-				<uuid value="0x1108" />
-				<uint16 value="0x0102" />
-			</sequence>
-		</sequence>
-	</attribute>
-	<attribute id="0x0100">
-		<text value="Headset Audio Gateway" />
-	</attribute>
-</record>
diff --git a/device/test/data/bluetooth/short_uuid.xml b/device/test/data/bluetooth/short_uuid.xml
deleted file mode 100644
index 9ad3c9f5..0000000
--- a/device/test/data/bluetooth/short_uuid.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<record>
-	<attribute id="0x0001">
-		<sequence>
-			<uuid value="0x1101" />
-		</sequence>
-	</attribute>
-</record>
diff --git a/device/test/data/bluetooth/uppercase_uuid.xml b/device/test/data/bluetooth/uppercase_uuid.xml
deleted file mode 100644
index 4e0574f..0000000
--- a/device/test/data/bluetooth/uppercase_uuid.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<record>
-	<attribute id="0x0001">
-		<sequence>
-			<uuid value="01234567-89AB-CDEF-0123-456789ABCDEF" />
-		</sequence>
-	</attribute>
-</record>
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc
index f04092f9..0d9ac46 100644
--- a/device/usb/usb_device_impl.cc
+++ b/device/usb/usb_device_impl.cc
@@ -99,6 +99,7 @@
     const base::string16& manufacturer_string,
     const base::string16& product_string,
     const base::string16& serial_number,
+    const std::string& device_node,
     scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
     : UsbDevice(vendor_id,
                 product_id,
@@ -107,6 +108,9 @@
                 product_string,
                 serial_number),
       platform_device_(platform_device),
+#if defined(OS_CHROMEOS)
+      devnode_(device_node),
+#endif  // defined(OS_CHROMEOS)
       context_(context),
       task_runner_(base::ThreadTaskRunnerHandle::Get()),
       blocking_task_runner_(blocking_task_runner) {
diff --git a/device/usb/usb_device_impl.h b/device/usb/usb_device_impl.h
index a865ea21..71edf1f0 100644
--- a/device/usb/usb_device_impl.h
+++ b/device/usb/usb_device_impl.h
@@ -56,6 +56,7 @@
                 const base::string16& manufacturer_string,
                 const base::string16& product_string,
                 const base::string16& serial_number,
+                const std::string& device_node,
                 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
 
   ~UsbDeviceImpl() override;
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc
index ce5b51a4..bd737c7 100644
--- a/device/usb/usb_service_impl.cc
+++ b/device/usb/usb_service_impl.cc
@@ -537,7 +537,7 @@
   scoped_refptr<UsbDeviceImpl> device(
       new UsbDeviceImpl(context_, platform_device, vendor_id, product_id,
                         unique_id, manufacturer_string, product_string,
-                        serial_number, blocking_task_runner_));
+                        serial_number, device_node, blocking_task_runner_));
 
   platform_devices_[platform_device] = device;
   devices_[unique_id] = device;
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_api.cc b/extensions/browser/api/bluetooth/bluetooth_private_api.cc
index 27cc124..1fd4870 100644
--- a/extensions/browser/api/bluetooth/bluetooth_private_api.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_private_api.cc
@@ -9,13 +9,13 @@
 #include "base/strings/string_util.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
 #include "extensions/browser/api/bluetooth/bluetooth_api.h"
 #include "extensions/browser/api/bluetooth/bluetooth_event_router.h"
 #include "extensions/common/api/bluetooth_private.h"
 
 namespace bt_private = extensions::core_api::bluetooth_private;
-namespace SetDiscoveryFilter =
-    extensions::core_api::bluetooth_private::SetDiscoveryFilter;
+namespace SetDiscoveryFilter = bt_private::SetDiscoveryFilter;
 
 namespace extensions {
 
@@ -347,16 +347,71 @@
   SendResponse(false);
 }
 
+void BluetoothPrivateSetDiscoveryFilterFunction::OnSuccessCallback() {
+  SendResponse(true);
+}
+
+void BluetoothPrivateSetDiscoveryFilterFunction::OnErrorCallback() {
+  SetError(kSetDiscoveryFilterFailed);
+  SendResponse(false);
+}
+
 bool BluetoothPrivateSetDiscoveryFilterFunction::DoWork(
     scoped_refptr<device::BluetoothAdapter> adapter) {
   scoped_ptr<SetDiscoveryFilter::Params> params(
       SetDiscoveryFilter::Params::Create(*args_));
+  auto& df_param = params->discovery_filter;
 
-  // TODO(jpawlowski): parse arguments, and call event router when method is
-  // implemented.
+  scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter;
 
-  SetError(kSetDiscoveryFilterFailed);
-  SendResponse(false);
+  // If all filter fields are empty, we are clearing filter. If any field is
+  // set, then create proper filter.
+  if (df_param.uuids.get() || df_param.rssi.get() || df_param.pathloss.get() ||
+      df_param.transport != bt_private::TransportType::TRANSPORT_TYPE_NONE) {
+    uint8_t transport;
+
+    switch (df_param.transport) {
+      case bt_private::TransportType::TRANSPORT_TYPE_LE:
+        transport = device::BluetoothDiscoveryFilter::Transport::TRANSPORT_LE;
+        break;
+      case bt_private::TransportType::TRANSPORT_TYPE_BREDR:
+        transport =
+            device::BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC;
+        break;
+      default:  // TRANSPORT_TYPE_NONE is included here
+        transport = device::BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL;
+        break;
+    }
+
+    discovery_filter.reset(new device::BluetoothDiscoveryFilter(transport));
+
+    if (df_param.uuids.get()) {
+      std::vector<device::BluetoothUUID> uuids;
+      if (df_param.uuids->as_string.get()) {
+        discovery_filter->AddUUID(
+            device::BluetoothUUID(*df_param.uuids->as_string));
+      } else if (df_param.uuids->as_strings.get()) {
+        for (const auto& iter : *df_param.uuids->as_strings) {
+          discovery_filter->AddUUID(device::BluetoothUUID(iter));
+        }
+      }
+    }
+
+    if (df_param.rssi.get())
+      discovery_filter->SetRSSI(*df_param.rssi);
+
+    if (df_param.pathloss.get())
+      discovery_filter->SetPathloss(*df_param.pathloss);
+  }
+
+  BluetoothAPI::Get(browser_context())->event_router()->SetDiscoveryFilter(
+          discovery_filter.Pass(), adapter.get(), extension_id(),
+          base::Bind(
+              &BluetoothPrivateSetDiscoveryFilterFunction::OnSuccessCallback,
+              this),
+          base::Bind(
+              &BluetoothPrivateSetDiscoveryFilterFunction::OnErrorCallback,
+              this));
   return true;
 }
 
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc b/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
index 203d749..85d88be8 100644
--- a/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
 #include "device/bluetooth/test/mock_bluetooth_device.h"
+#include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
 #include "extensions/browser/api/bluetooth/bluetooth_api.h"
 #include "extensions/browser/api/bluetooth/bluetooth_event_router.h"
 #include "extensions/browser/event_router.h"
@@ -15,9 +16,13 @@
 #include "extensions/common/switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
+using device::BluetoothDiscoveryFilter;
+using device::BluetoothUUID;
 using device::MockBluetoothAdapter;
 using device::MockBluetoothDevice;
+using device::MockBluetoothDiscoverySession;
 using testing::_;
+using testing::Eq;
 using testing::InSequence;
 using testing::NiceMock;
 using testing::Return;
@@ -31,10 +36,13 @@
 namespace extensions {
 
 namespace {
-
 const char kTestExtensionId[] = "jofgjdphhceggjecimellaapdjjadibj";
 const char kAdapterName[] = "Helix";
 const char kDeviceName[] = "Red";
+
+MATCHER_P(IsFilterEqual, a, "") {
+  return arg->Equals(*a);
+}
 }
 
 class BluetoothPrivateApiTest : public ExtensionApiTest {
@@ -111,6 +119,14 @@
     DispatchPairingEvent(bt_private::PAIRING_EVENT_TYPE_REQUESTPASSKEY);
   }
 
+  void CallSetDiscoveryFilterCallback(
+      device::BluetoothAdapter::DiscoverySessionCallback callback) {
+    auto session_ptr = scoped_ptr<NiceMock<MockBluetoothDiscoverySession>>(
+        mock_discovery_session_);
+
+    callback.Run(session_ptr.Pass());
+  }
+
  protected:
   std::string adapter_name_;
   bool adapter_powered_;
@@ -118,6 +134,10 @@
 
   scoped_refptr<NiceMock<MockBluetoothAdapter> > mock_adapter_;
   scoped_ptr<NiceMock<MockBluetoothDevice> > mock_device_;
+
+  // This discovery session will be owned by EventRouter, we'll only keep
+  // pointer to it.
+  NiceMock<MockBluetoothDiscoverySession>* mock_discovery_session_;
 };
 
 ACTION_TEMPLATE(InvokeCallbackArgument,
@@ -205,4 +225,30 @@
       << message_;
 }
 
+IN_PROC_BROWSER_TEST_F(BluetoothPrivateApiTest, DiscoveryFilter) {
+  mock_discovery_session_ = new NiceMock<MockBluetoothDiscoverySession>();
+
+  BluetoothDiscoveryFilter discovery_filter(
+      BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+  discovery_filter.SetPathloss(50);
+  discovery_filter.AddUUID(BluetoothUUID("cafe"));
+  discovery_filter.AddUUID(
+      BluetoothUUID("0000bebe-0000-1000-8000-00805f9b34fb"));
+
+  EXPECT_CALL(*mock_adapter_.get(), StartDiscoverySessionWithFilterRaw(
+                                        IsFilterEqual(&discovery_filter), _, _))
+      .Times(1)
+      .WillOnce(WithArgs<1>(Invoke(
+          this, &BluetoothPrivateApiTest::CallSetDiscoveryFilterCallback)));
+  EXPECT_CALL(*mock_discovery_session_, IsActive())
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(*mock_discovery_session_,
+              SetDiscoveryFilterRaw(Eq(nullptr), _, _))
+      .Times(1)
+      .WillOnce(InvokeCallbackArgument<1>());
+  ASSERT_TRUE(RunComponentExtensionTest("bluetooth_private/discovery_filter"))
+      << message_;
+}
+
 }  // namespace extensions
diff --git a/extensions/browser/api/mime_handler_private/mime_handler_private.cc b/extensions/browser/api/mime_handler_private/mime_handler_private.cc
index b7d557d..13caee2 100644
--- a/extensions/browser/api/mime_handler_private/mime_handler_private.cc
+++ b/extensions/browser/api/mime_handler_private/mime_handler_private.cc
@@ -4,8 +4,10 @@
 
 #include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
 
+#include "base/strings/string_util.h"
 #include "content/public/browser/stream_handle.h"
 #include "content/public/browser/stream_info.h"
+#include "content/public/common/content_constants.h"
 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
 #include "extensions/common/constants.h"
 #include "net/http/http_response_headers.h"
@@ -24,6 +26,15 @@
   std::string header_name;
   std::string header_value;
   while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
+    // mojo strings must be UTF-8 and headers might not be, so drop any headers
+    // that aren't ASCII. The PDF plugin does not use any headers with non-ASCII
+    // names and non-ASCII values are never useful for the headers the plugin
+    // does use.
+    //
+    // TODO(sammc): Send as bytes instead of a string and let the client decide
+    // how to decode.
+    if (!base::IsStringASCII(header_name) || !base::IsStringASCII(header_value))
+      continue;
     auto& current_value = result[header_name];
     if (!current_value.empty())
       current_value += ", ";
@@ -89,7 +100,18 @@
   result->tab_id = stream.tab_id();
   const content::StreamInfo* info = stream.stream_info();
   result->mime_type = info->mime_type;
-  result->original_url = info->original_url.spec();
+
+  // If the URL is too long, mojo will give up on sending the URL. In these
+  // cases truncate it. Only data: URLs should ever really suffer this problem
+  // so only worry about those for now.
+  // TODO(raymes): This appears to be a bug in mojo somewhere. crbug.com/480099.
+  if (info->original_url.SchemeIs(url::kDataScheme) &&
+      info->original_url.spec().size() > content::kMaxURLDisplayChars) {
+    result->original_url = info->original_url.scheme() + ":";
+  } else {
+    result->original_url = info->original_url.spec();
+  }
+
   result->stream_url = info->handle->GetURL().spec();
   result->response_headers =
       extensions::CreateResponseHeadersMap(info->response_headers.get());
diff --git a/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc b/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
index 999576d0..aa5df440 100644
--- a/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
+++ b/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
@@ -5,6 +5,7 @@
 #include "extensions/browser/api/networking_private/networking_private_event_router.h"
 
 #include "base/json/json_writer.h"
+#include "chromeos/network/device_state.h"
 #include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -20,6 +21,7 @@
 #include "extensions/common/api/networking_private.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
+using chromeos::DeviceState;
 using chromeos::NetworkHandler;
 using chromeos::NetworkPortalDetector;
 using chromeos::NetworkState;
@@ -47,6 +49,7 @@
   void NetworkListChanged() override;
   void DeviceListChanged() override;
   void NetworkPropertiesUpdated(const NetworkState* network) override;
+  void DevicePropertiesUpdated(const DeviceState* device) override;
 
   // NetworkPortalDetector::Observer overrides:
   void OnPortalDetectionCompleted(
@@ -206,6 +209,21 @@
   event_router->BroadcastEvent(extension_event.Pass());
 }
 
+void NetworkingPrivateEventRouterImpl::DevicePropertiesUpdated(
+    const DeviceState* device) {
+  // DeviceState changes may affect Cellular networks.
+  if (device->type() != shill::kTypeCellular)
+    return;
+
+  NetworkStateHandler::NetworkStateList cellular_networks;
+  NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
+      chromeos::NetworkTypePattern::Cellular(), false /* configured_only */,
+      true /* visible_only */, -1 /* default limit */, &cellular_networks);
+  for (const NetworkState* network : cellular_networks) {
+    NetworkPropertiesUpdated(network);
+  }
+}
+
 void NetworkingPrivateEventRouterImpl::OnPortalDetectionCompleted(
     const NetworkState* network,
     const NetworkPortalDetector::CaptivePortalState& state) {
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 160462a..73a8dd8 100644
--- a/extensions/browser/api/web_request/web_request_api_helpers.cc
+++ b/extensions/browser/api/web_request/web_request_api_helpers.cc
@@ -218,9 +218,8 @@
 
 // Creates NetLog parameters to indicate that an extension modified a request.
 // Caller takes ownership of returned value.
-base::Value* NetLogModificationCallback(
-    const EventResponseDelta* delta,
-    net::NetLog::LogLevel log_level) {
+base::Value* NetLogModificationCallback(const EventResponseDelta* delta,
+                                        net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("extension_id", delta->extension_id);
 
diff --git a/extensions/browser/content_hash_reader.cc b/extensions/browser/content_hash_reader.cc
index 76c7e60..499587b 100644
--- a/extensions/browser/content_hash_reader.cc
+++ b/extensions/browser/content_hash_reader.cc
@@ -53,7 +53,7 @@
 
   // Check that this is a valid resource to verify (i.e., it exists).
   base::FilePath content_path = extension_root_.Append(relative_path_);
-  if (!base::PathExists(content_path))
+  if (!base::PathExists(content_path) || base::DirectoryExists(content_path))
     return false;
 
   content_exists_ = true;
diff --git a/extensions/browser/guest_view/extensions_guest_view_message_filter.cc b/extensions/browser/guest_view/extensions_guest_view_message_filter.cc
new file mode 100644
index 0000000..215bf816
--- /dev/null
+++ b/extensions/browser/guest_view/extensions_guest_view_message_filter.cc
@@ -0,0 +1,178 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "extensions/browser/guest_view/guest_view_base.h"
+#include "extensions/browser/guest_view/guest_view_manager.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_constants.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/browser/guest_view/web_view/web_view_content_script_manager.h"
+#include "extensions/browser/guest_view/web_view/web_view_guest.h"
+#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
+#include "ipc/ipc_message_macros.h"
+
+using content::BrowserContext;
+using content::BrowserThread;
+using content::RenderFrameHost;
+using content::WebContents;
+
+namespace extensions {
+
+ExtensionsGuestViewMessageFilter::ExtensionsGuestViewMessageFilter(
+    int render_process_id,
+    BrowserContext* context)
+    : BrowserMessageFilter(ExtensionsGuestViewMsgStart),
+      render_process_id_(render_process_id),
+      browser_context_(context),
+      weak_ptr_factory_(this) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+ExtensionsGuestViewMessageFilter::~ExtensionsGuestViewMessageFilter() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
+void ExtensionsGuestViewMessageFilter::OverrideThreadForMessage(
+    const IPC::Message& message,
+    BrowserThread::ID* thread) {
+  switch (message.type()) {
+    case ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest::ID:
+    case ExtensionsGuestViewHostMsg_ResizeGuest::ID:
+      *thread = BrowserThread::UI;
+      break;
+    default:
+      break;
+  }
+}
+
+void ExtensionsGuestViewMessageFilter::OnDestruct() const {
+  // Destroy the filter on the IO thread since that's where its weak pointers
+  // are being used.
+  BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
+bool ExtensionsGuestViewMessageFilter::OnMessageReceived(
+    const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(ExtensionsGuestViewMessageFilter, message)
+    IPC_MESSAGE_HANDLER(ExtensionsGuestViewHostMsg_CanExecuteContentScriptSync,
+                        OnCanExecuteContentScript)
+    IPC_MESSAGE_HANDLER(ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest,
+                        OnCreateMimeHandlerViewGuest)
+    IPC_MESSAGE_HANDLER(ExtensionsGuestViewHostMsg_ResizeGuest, OnResizeGuest)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void ExtensionsGuestViewMessageFilter::OnCanExecuteContentScript(
+    int render_view_id,
+    int script_id,
+    bool* allowed) {
+  WebViewRendererState::WebViewInfo info;
+  WebViewRendererState::GetInstance()->GetInfo(render_process_id_,
+                                               render_view_id, &info);
+
+  *allowed =
+      info.content_script_ids.find(script_id) != info.content_script_ids.end();
+}
+
+void ExtensionsGuestViewMessageFilter::OnCreateMimeHandlerViewGuest(
+    int render_frame_id,
+    const std::string& view_id,
+    int element_instance_id,
+    const gfx::Size& element_size) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  // Since we are creating a new guest, we will create a GuestViewManager
+  // if we don't already have one.
+  auto manager = GuestViewManager::FromBrowserContext(browser_context_);
+  DCHECK(manager);
+
+  auto rfh = RenderFrameHost::FromID(render_process_id_, render_frame_id);
+  auto embedder_web_contents = WebContents::FromRenderFrameHost(rfh);
+  if (!embedder_web_contents)
+    return;
+
+  GuestViewManager::WebContentsCreatedCallback callback =
+      base::Bind(
+          &ExtensionsGuestViewMessageFilter::
+              MimeHandlerViewGuestCreatedCallback,
+          this,
+          element_instance_id,
+          render_process_id_,
+          render_frame_id,
+          element_size);
+
+  base::DictionaryValue create_params;
+  create_params.SetString(mime_handler_view::kViewId, view_id);
+  create_params.SetInteger(guestview::kElementWidth, element_size.width());
+  create_params.SetInteger(guestview::kElementHeight, element_size.height());
+  manager->CreateGuest(MimeHandlerViewGuest::Type,
+                       embedder_web_contents,
+                       create_params,
+                       callback);
+}
+
+void ExtensionsGuestViewMessageFilter::OnResizeGuest(
+    int render_frame_id,
+    int element_instance_id,
+    const gfx::Size& new_size) {
+  auto manager =
+      GuestViewManager::FromBrowserContextIfAvailable(browser_context_);
+  // We should have a GuestViewManager at this point. If we don't then the
+  // embedder is misbehaving.
+  if (!manager)
+    return;
+
+  auto guest_web_contents =
+      manager->GetGuestByInstanceID(render_process_id_, element_instance_id);
+  auto mhvg = MimeHandlerViewGuest::FromWebContents(guest_web_contents);
+  if (!mhvg)
+    return;
+
+  SetSizeParams set_size_params;
+  set_size_params.enable_auto_size.reset(new bool(false));
+  set_size_params.normal_size.reset(new gfx::Size(new_size));
+  mhvg->SetSize(set_size_params);
+}
+
+void ExtensionsGuestViewMessageFilter::MimeHandlerViewGuestCreatedCallback(
+    int element_instance_id,
+    int embedder_render_process_id,
+    int embedder_render_frame_id,
+    const gfx::Size& element_size,
+    WebContents* web_contents) {
+  auto guest_view = MimeHandlerViewGuest::FromWebContents(web_contents);
+  if (!guest_view)
+    return;
+
+  int guest_instance_id = guest_view->guest_instance_id();
+  auto rfh = RenderFrameHost::FromID(embedder_render_process_id,
+                                     embedder_render_frame_id);
+  if (!rfh)
+    return;
+
+  base::DictionaryValue attach_params;
+  attach_params.SetInteger(guestview::kElementWidth, element_size.width());
+  attach_params.SetInteger(guestview::kElementHeight, element_size.height());
+  auto manager =
+      GuestViewManager::FromBrowserContextIfAvailable(browser_context_);
+  CHECK(manager);
+  manager->AttachGuest(embedder_render_process_id,
+                       element_instance_id,
+                       guest_instance_id,
+                       attach_params);
+
+  rfh->Send(
+      new ExtensionsGuestViewMsg_CreateMimeHandlerViewGuestACK(
+          element_instance_id));
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/guest_view/extensions_guest_view_message_filter.h b/extensions/browser/guest_view/extensions_guest_view_message_filter.h
new file mode 100644
index 0000000..6e07d41
--- /dev/null
+++ b/extensions/browser/guest_view/extensions_guest_view_message_filter.h
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSIONS_GUEST_VIEW_MESSAGE_FILTER_H_
+#define EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSIONS_GUEST_VIEW_MESSAGE_FILTER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/browser_message_filter.h"
+
+namespace content {
+class BrowserContext;
+class WebContents;
+}
+
+namespace gfx {
+class Size;
+}
+
+namespace extensions {
+
+// This class filters out incoming extensions GuestView-specific IPC messages
+// from thw renderer process. It is created on the UI thread. Messages may be
+// handled on the IO thread or the UI thread.
+class ExtensionsGuestViewMessageFilter : public content::BrowserMessageFilter {
+ public:
+  ExtensionsGuestViewMessageFilter(int render_process_id,
+                                   content::BrowserContext* context);
+
+ private:
+  friend class content::BrowserThread;
+  friend class base::DeleteHelper<ExtensionsGuestViewMessageFilter>;
+
+  ~ExtensionsGuestViewMessageFilter() override;
+
+  // content::BrowserMessageFilter implementation.
+  void OverrideThreadForMessage(const IPC::Message& message,
+                                content::BrowserThread::ID* thread) override;
+  void OnDestruct() const override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+
+  // Message handlers on the UI thread.
+  void OnCanExecuteContentScript(int render_view_id,
+                                 int script_id,
+                                 bool* allowed);
+
+  void OnCreateMimeHandlerViewGuest(int render_frame_id,
+                                    const std::string& view_id,
+                                    int element_instance_id,
+                                    const gfx::Size& element_size);
+  void OnResizeGuest(int render_frame_id,
+                     int element_instance_id,
+                     const gfx::Size& new_size);
+
+  // Runs on UI thread.
+  void MimeHandlerViewGuestCreatedCallback(int element_instance_id,
+                                           int embedder_render_process_id,
+                                           int embedder_render_frame_id,
+                                           const gfx::Size& element_size,
+                                           content::WebContents* web_contents);
+
+  const int render_process_id_;
+
+  // Should only be accessed on the UI thread.
+  content::BrowserContext* const browser_context_;
+
+  // Weak pointers produced by this factory are bound to the IO thread.
+  base::WeakPtrFactory<ExtensionsGuestViewMessageFilter> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionsGuestViewMessageFilter);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSIONS_GUEST_VIEW_MESSAGE_FILTER_H_
diff --git a/extensions/browser/guest_view/guest_view_base.cc b/extensions/browser/guest_view/guest_view_base.cc
index 9a095629..134c326 100644
--- a/extensions/browser/guest_view/guest_view_base.cc
+++ b/extensions/browser/guest_view/guest_view_base.cc
@@ -341,6 +341,13 @@
 }
 
 // static
+WebContents* GuestViewBase::GetTopLevelWebContents(WebContents* web_contents) {
+  while (GuestViewBase* guest = FromWebContents(web_contents))
+    web_contents = guest->owner_web_contents();
+  return web_contents;
+}
+
+// static
 bool GuestViewBase::IsGuest(WebContents* web_contents) {
   return !!GuestViewBase::FromWebContents(web_contents);
 }
diff --git a/extensions/browser/guest_view/guest_view_base.h b/extensions/browser/guest_view/guest_view_base.h
index e342889..7969cb9 100644
--- a/extensions/browser/guest_view/guest_view_base.h
+++ b/extensions/browser/guest_view/guest_view_base.h
@@ -65,6 +65,12 @@
 
   static GuestViewBase* From(int owner_process_id, int instance_id);
 
+  // Given a |web_contents|, returns the top level owner WebContents. If
+  // |web_contents| does not belong to a GuestView, it will be returned
+  // unchanged.
+  static content::WebContents* GetTopLevelWebContents(
+      content::WebContents* web_contents);
+
   static bool IsGuest(content::WebContents* web_contents);
 
   virtual const char* GetViewType() const = 0;
diff --git a/extensions/browser/guest_view/guest_view_message_filter.cc b/extensions/browser/guest_view/guest_view_message_filter.cc
index 7f43a3e..3e833d5 100644
--- a/extensions/browser/guest_view/guest_view_message_filter.cc
+++ b/extensions/browser/guest_view/guest_view_message_filter.cc
@@ -10,11 +10,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "extensions/browser/guest_view/guest_view_base.h"
 #include "extensions/browser/guest_view/guest_view_manager.h"
-#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_constants.h"
-#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
-#include "extensions/browser/guest_view/web_view/web_view_content_script_manager.h"
-#include "extensions/browser/guest_view/web_view/web_view_guest.h"
-#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
 #include "extensions/common/guest_view/guest_view_messages.h"
 #include "ipc/ipc_message_macros.h"
 
@@ -43,8 +38,6 @@
     BrowserThread::ID* thread) {
   switch (message.type()) {
     case GuestViewHostMsg_AttachGuest::ID:
-    case GuestViewHostMsg_CreateMimeHandlerViewGuest::ID:
-    case GuestViewHostMsg_ResizeGuest::ID:
       *thread = BrowserThread::UI;
       break;
     default:
@@ -62,11 +55,6 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(GuestViewMessageFilter, message)
     IPC_MESSAGE_HANDLER(GuestViewHostMsg_AttachGuest, OnAttachGuest)
-    IPC_MESSAGE_HANDLER(GuestViewHostMsg_CreateMimeHandlerViewGuest,
-                        OnCreateMimeHandlerViewGuest)
-    IPC_MESSAGE_HANDLER(GuestViewHostMsg_ResizeGuest, OnResizeGuest)
-    IPC_MESSAGE_HANDLER(GuestViewHostMsg_CanExecuteContentScriptSync,
-                        OnCanExecuteContentScript)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -90,102 +78,4 @@
                        params);
 }
 
-void GuestViewMessageFilter::OnCreateMimeHandlerViewGuest(
-    int render_frame_id,
-    const std::string& view_id,
-    int element_instance_id,
-    const gfx::Size& element_size) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // Since we are creating a new guest, we will create a GuestViewManager
-  // if we don't already have one.
-  auto manager = GuestViewManager::FromBrowserContext(browser_context_);
-  DCHECK(manager);
-
-  auto rfh = RenderFrameHost::FromID(render_process_id_, render_frame_id);
-  auto embedder_web_contents = WebContents::FromRenderFrameHost(rfh);
-  if (!embedder_web_contents)
-    return;
-
-  GuestViewManager::WebContentsCreatedCallback callback =
-      base::Bind(&GuestViewMessageFilter::MimeHandlerViewGuestCreatedCallback,
-                 this,
-                 element_instance_id,
-                 render_process_id_,
-                 render_frame_id,
-                 element_size);
-
-  base::DictionaryValue create_params;
-  create_params.SetString(mime_handler_view::kViewId, view_id);
-  create_params.SetInteger(guestview::kElementWidth, element_size.width());
-  create_params.SetInteger(guestview::kElementHeight, element_size.height());
-  manager->CreateGuest(MimeHandlerViewGuest::Type,
-                       embedder_web_contents,
-                       create_params,
-                       callback);
-}
-
-void GuestViewMessageFilter::OnResizeGuest(int render_frame_id,
-                                           int element_instance_id,
-                                           const gfx::Size& new_size) {
-  auto manager =
-      GuestViewManager::FromBrowserContextIfAvailable(browser_context_);
-  // We should have a GuestViewManager at this point. If we don't then the
-  // embedder is misbehaving.
-  if (!manager)
-    return;
-
-  auto guest_web_contents =
-      manager->GetGuestByInstanceID(render_process_id_, element_instance_id);
-  auto mhvg = MimeHandlerViewGuest::FromWebContents(guest_web_contents);
-  if (!mhvg)
-    return;
-
-  SetSizeParams set_size_params;
-  set_size_params.enable_auto_size.reset(new bool(false));
-  set_size_params.normal_size.reset(new gfx::Size(new_size));
-  mhvg->SetSize(set_size_params);
-}
-
-void GuestViewMessageFilter::OnCanExecuteContentScript(int render_view_id,
-                                                       int script_id,
-                                                       bool* allowed) {
-  WebViewRendererState::WebViewInfo info;
-  WebViewRendererState::GetInstance()->GetInfo(render_process_id_,
-                                               render_view_id, &info);
-
-  *allowed =
-      info.content_script_ids.find(script_id) != info.content_script_ids.end();
-}
-
-void GuestViewMessageFilter::MimeHandlerViewGuestCreatedCallback(
-    int element_instance_id,
-    int embedder_render_process_id,
-    int embedder_render_frame_id,
-    const gfx::Size& element_size,
-    WebContents* web_contents) {
-  auto guest_view = MimeHandlerViewGuest::FromWebContents(web_contents);
-  if (!guest_view)
-    return;
-
-  int guest_instance_id = guest_view->guest_instance_id();
-  auto rfh = RenderFrameHost::FromID(embedder_render_process_id,
-                                     embedder_render_frame_id);
-  if (!rfh)
-    return;
-
-  base::DictionaryValue attach_params;
-  attach_params.SetInteger(guestview::kElementWidth, element_size.width());
-  attach_params.SetInteger(guestview::kElementHeight, element_size.height());
-  auto manager =
-      GuestViewManager::FromBrowserContextIfAvailable(browser_context_);
-  CHECK(manager);
-  manager->AttachGuest(embedder_render_process_id,
-                       element_instance_id,
-                       guest_instance_id,
-                       attach_params);
-
-  rfh->Send(
-      new GuestViewMsg_CreateMimeHandlerViewGuestACK(element_instance_id));
-}
-
 }  // namespace extensions
diff --git a/extensions/browser/guest_view/guest_view_message_filter.h b/extensions/browser/guest_view/guest_view_message_filter.h
index 27e0d1b2..c5fb487 100644
--- a/extensions/browser/guest_view/guest_view_message_filter.h
+++ b/extensions/browser/guest_view/guest_view_message_filter.h
@@ -34,8 +34,6 @@
   GuestViewMessageFilter(int render_process_id,
                          content::BrowserContext* context);
 
-  int render_process_id() const { return render_process_id_; }
-
  private:
   friend class content::BrowserThread;
   friend class base::DeleteHelper<GuestViewMessageFilter>;
@@ -52,24 +50,6 @@
   void OnAttachGuest(int element_instance_id,
                      int guest_instance_id,
                      const base::DictionaryValue& attach_params);
-  void OnCreateMimeHandlerViewGuest(int render_frame_id,
-                                    const std::string& view_id,
-                                    int element_instance_id,
-                                    const gfx::Size& element_size);
-  void OnResizeGuest(int render_frame_id,
-                     int element_instance_id,
-                     const gfx::Size& new_size);
-
-  void OnCanExecuteContentScript(int render_view_id,
-                                 int script_id,
-                                 bool* allowed);
-
-  // Runs on UI thread.
-  void MimeHandlerViewGuestCreatedCallback(int element_instance_id,
-                                           int embedder_render_process_id,
-                                           int embedder_render_frame_id,
-                                           const gfx::Size& element_size,
-                                           content::WebContents* web_contents);
 
   const int render_process_id_;
 
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
index 5b09caf3..5d26145 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -30,21 +30,23 @@
     return extension;
   }
 
-  void RunTest(const std::string& path) {
+  void RunTestWithUrl(const GURL& url) {
     const extensions::Extension* extension = LoadTestExtension();
     ASSERT_TRUE(extension);
 
+    extensions::ResultCatcher catcher;
+    ui_test_utils::NavigateToURL(browser(), url);
+
+    if (!catcher.GetNextResult())
+      FAIL() << catcher.message();
+  }
+
+  void RunTest(const std::string& path) {
     ASSERT_TRUE(StartEmbeddedTestServer());
     embedded_test_server()->ServeFilesFromDirectory(
         test_data_dir_.AppendASCII("mime_handler_view"));
 
-    extensions::ResultCatcher catcher;
-
-    ui_test_utils::NavigateToURL(browser(),
-                                 embedded_test_server()->GetURL("/" + path));
-
-    if (!catcher.GetNextResult())
-      FAIL() << catcher.message();
+    RunTestWithUrl(embedded_test_server()->GetURL("/" + path));
   }
 };
 
@@ -67,3 +69,24 @@
 IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, Abort) {
   RunTest("testAbort.csv");
 }
+
+IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, NonAsciiHeaders) {
+  RunTest("testNonAsciiHeaders.csv");
+}
+
+IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, DataUrl) {
+  const char* kDataUrlCsv = "data:text/csv;base64,Y29udGVudCB0byByZWFkCg==";
+  RunTestWithUrl(GURL(kDataUrlCsv));
+}
+
+IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, EmbeddedDataUrlObject) {
+  RunTest("test_embedded_data_url_object.html");
+}
+
+IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, EmbeddedDataUrlEmbed) {
+  RunTest("test_embedded_data_url_embed.html");
+}
+
+IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, EmbeddedDataUrlLong) {
+  RunTest("test_embedded_data_url_long.html");
+}
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 a15605c0..bf91ebe4 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
@@ -21,8 +21,8 @@
 #include "extensions/browser/process_manager.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension_messages.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
 #include "extensions/common/guest_view/guest_view_constants.h"
-#include "extensions/common/guest_view/guest_view_messages.h"
 #include "extensions/strings/grit/extensions_strings.h"
 #include "ipc/ipc_message_macros.h"
 #include "net/base/url_util.h"
@@ -246,7 +246,7 @@
 
 void MimeHandlerViewGuest::DocumentOnLoadCompletedInMainFrame() {
   embedder_web_contents()->Send(
-      new GuestViewMsg_MimeHandlerViewGuestOnLoadCompleted(
+      new ExtensionsGuestViewMsg_MimeHandlerViewGuestOnLoadCompleted(
           element_instance_id()));
 }
 
diff --git a/extensions/browser/notification_types.h b/extensions/browser/notification_types.h
index 031cb0c..f118ae4 100644
--- a/extensions/browser/notification_types.h
+++ b/extensions/browser/notification_types.h
@@ -128,11 +128,6 @@
   // are no details.
   NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
 
-  // Sent when a browser action's visibility has changed. The source is the
-  // ExtensionPrefs* that changed, and the details are a std::string with the
-  // extension's ID.
-  NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-
   // Sent when an extension command has been removed. The source is the
   // BrowserContext* and the details is an ExtensionCommandRemovedDetails
   // consisting of std::strings representing an extension ID, the name of the
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc
index 29d559a..18823cb9 100644
--- a/extensions/browser/sandboxed_unpacker.cc
+++ b/extensions/browser/sandboxed_unpacker.cc
@@ -322,6 +322,9 @@
 }
 
 SandboxedUnpacker::~SandboxedUnpacker() {
+  // To avoid blocking shutdown, don't delete temporary directory here if it
+  // hasn't been cleaned up or passed on to another owner yet.
+  temp_dir_.Take();
 }
 
 bool SandboxedUnpacker::OnMessageReceived(const IPC::Message& message) {
diff --git a/extensions/common/api/bluetooth_private.json b/extensions/common/api/bluetooth_private.json
index 1b3bb69e..4073220 100644
--- a/extensions/common/api/bluetooth_private.json
+++ b/extensions/common/api/bluetooth_private.json
@@ -56,7 +56,6 @@
       {
         "name": "setDiscoveryFilter",
         "type": "function",
-        "platforms" : ["chromeos"],
         "description": "Set or clear discovery filter",
         "parameters": [
           {
diff --git a/extensions/common/api/mime_handler.mojom b/extensions/common/api/mime_handler.mojom
index 30031e63..7eefc02 100644
--- a/extensions/common/api/mime_handler.mojom
+++ b/extensions/common/api/mime_handler.mojom
@@ -22,7 +22,7 @@
   // The HTTP response headers of the intercepted request stored as a dictionary
   // mapping header name to header value. If a header name appears multiple
   // times, the header values are merged in the dictionary and separated by a
-  // ",".
+  // ",". Non-ASCII headers are dropped.
   map<string, string> response_headers;
 
   // Whether the stream is embedded within another document.
diff --git a/extensions/common/api/mime_handler_private.idl b/extensions/common/api/mime_handler_private.idl
index af402d7..dfd47be 100644
--- a/extensions/common/api/mime_handler_private.idl
+++ b/extensions/common/api/mime_handler_private.idl
@@ -21,7 +21,7 @@
     // The HTTP response headers of the intercepted request stored as a
     // dictionary mapping header name to header value. If a header name appears
     // multiple times, the header values are merged in the dictionary and
-    // separated by a ", ".
+    // separated by a ", ". Non-ASCII headers are dropped.
     object responseHeaders;
 
     // Whether the stream is embedded within another document.
diff --git a/extensions/common/api/networking_private.idl b/extensions/common/api/networking_private.idl
index 5200fb8..8266d4f5 100644
--- a/extensions/common/api/networking_private.idl
+++ b/extensions/common/api/networking_private.idl
@@ -82,6 +82,7 @@
     ActivationStateType? ActivationState;
     DOMString? NetworkTechnology;
     DOMString? RoamingState;
+    boolean? SIMPresent;
     long? SignalStrength;
   };
 
diff --git a/extensions/common/extension_message_generator.h b/extensions/common/extension_message_generator.h
index b5caa8a..664514c 100644
--- a/extensions/common/extension_message_generator.h
+++ b/extensions/common/extension_message_generator.h
@@ -6,4 +6,5 @@
 
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/extension_utility_messages.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
 #include "extensions/common/guest_view/guest_view_messages.h"
diff --git a/extensions/common/guest_view/extensions_guest_view_messages.h b/extensions/common/guest_view/extensions_guest_view_messages.h
new file mode 100644
index 0000000..61da7fc
--- /dev/null
+++ b/extensions/common/guest_view/extensions_guest_view_messages.h
@@ -0,0 +1,47 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// IPC messages for extensions GuestViews.
+// Multiply-included message file, hence no include guard.
+
+#include <string>
+
+#include "ipc/ipc_message_macros.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/ipc/gfx_param_traits.h"
+
+#define IPC_MESSAGE_START ExtensionsGuestViewMsgStart
+// Messages sent from the browser to the renderer.
+
+// The ACK for GuestViewHostMsg_CreateMimeHandlerViewGuest.
+IPC_MESSAGE_CONTROL1(ExtensionsGuestViewMsg_CreateMimeHandlerViewGuestACK,
+                     int /* element_instance_id */)
+
+// Once a MimeHandlerView guest's JavaScript onload function has been called,
+// this IPC is sent to the container to notify it.
+IPC_MESSAGE_CONTROL1(ExtensionsGuestViewMsg_MimeHandlerViewGuestOnLoadCompleted,
+                     int /* element_instance_id */)
+
+// Messages sent from the renderer to the browser.
+
+// Queries whether the RenderView of the provided |routing_id| is allowed to
+// inject the script with the provided |script_id|.
+IPC_SYNC_MESSAGE_CONTROL2_1(
+    ExtensionsGuestViewHostMsg_CanExecuteContentScriptSync,
+    int /* routing_id */,
+    int /* script_id */,
+    bool /* allowed */)
+
+// Tells the browser to create a mime handler guest view for a plugin.
+IPC_MESSAGE_CONTROL4(ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest,
+                     int /* render_frame_id */,
+                     std::string /* view_id */,
+                     int /* element_instance_id */,
+                     gfx::Size /* element_size */)
+
+// A renderer sends this message when it wants to resize a guest.
+IPC_MESSAGE_CONTROL3(ExtensionsGuestViewHostMsg_ResizeGuest,
+                     int /* routing_id */,
+                     int /* element_instance_id*/,
+                     gfx::Size /* new_size */)
diff --git a/extensions/common/guest_view/guest_view_messages.h b/extensions/common/guest_view/guest_view_messages.h
index b1b18ad..9772b6f 100644
--- a/extensions/common/guest_view/guest_view_messages.h
+++ b/extensions/common/guest_view/guest_view_messages.h
@@ -5,26 +5,13 @@
 // IPC messages for GuestViews.
 // Multiply-included message file, hence no include guard.
 
-#include <string>
-
 #include "base/values.h"
 #include "ipc/ipc_message_macros.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/ipc/gfx_param_traits.h"
 
 #define IPC_MESSAGE_START GuestViewMsgStart
 
 // Messages sent from the browser to the renderer.
 
-// The ACK for GuestViewHostMsg_CreateMimeHandlerViewGuest.
-IPC_MESSAGE_CONTROL1(GuestViewMsg_CreateMimeHandlerViewGuestACK,
-                     int /* element_instance_id */)
-
-// Once a MimeHandlerView guest's JavaScript onload function has been called,
-// this IPC is sent to the container to notify it.
-IPC_MESSAGE_CONTROL1(GuestViewMsg_MimeHandlerViewGuestOnLoadCompleted,
-                     int /* element_instance_id */)
-
 // Once a RenderView proxy has been created for the guest in the embedder render
 // process, this IPC informs the embedder of the proxy's routing ID.
 IPC_MESSAGE_CONTROL2(GuestViewMsg_GuestAttached,
@@ -46,21 +33,3 @@
                      int /* element_instance_id */,
                      int /* guest_instance_id */,
                      base::DictionaryValue /* attach_params */)
-
-// Tells the browser to create a mime handler guest view for a plugin.
-IPC_MESSAGE_CONTROL4(GuestViewHostMsg_CreateMimeHandlerViewGuest,
-                     int /* render_frame_id */,
-                     std::string /* view_id */,
-                     int /* element_instance_id */,
-                     gfx::Size /* element_size */)
-
-// A renderer sends this message when it wants to resize a guest.
-IPC_MESSAGE_CONTROL3(GuestViewHostMsg_ResizeGuest,
-                     int /* routing_id */,
-                     int /* element_instance_id*/,
-                     gfx::Size /* new_size */)
-
-IPC_SYNC_MESSAGE_CONTROL2_1(GuestViewHostMsg_CanExecuteContentScriptSync,
-                            int /* routing_id */,
-                            int /* script_id */,
-                            bool /* allowed */)
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi
index 60484bec..79630432 100644
--- a/extensions/extensions.gypi
+++ b/extensions/extensions.gypi
@@ -92,6 +92,7 @@
       'common/features/simple_feature_filter.h',
       'common/file_util.cc',
       'common/file_util.h',
+      'common/guest_view/extensions_guest_view_messages.h',
       'common/guest_view/guest_view_constants.cc',
       'common/guest_view/guest_view_constants.h',
       'common/guest_view/guest_view_messages.h',
@@ -636,6 +637,8 @@
       'browser/guest_view/extension_view/extension_view_guest.h',
       'browser/guest_view/extension_view/extension_view_guest_delegate.cc',
       'browser/guest_view/extension_view/extension_view_guest_delegate.h',
+      'browser/guest_view/extensions_guest_view_message_filter.cc',
+      'browser/guest_view/extensions_guest_view_message_filter.h',
       'browser/guest_view/guest_view.h',
       'browser/guest_view/guest_view_base.cc',
       'browser/guest_view/guest_view_base.h',
diff --git a/extensions/renderer/guest_view/guest_view_container.cc b/extensions/renderer/guest_view/guest_view_container.cc
index 90e94c8..787e439 100644
--- a/extensions/renderer/guest_view/guest_view_container.cc
+++ b/extensions/renderer/guest_view/guest_view_container.cc
@@ -7,6 +7,7 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_frame_observer.h"
 #include "content/public/renderer/render_view.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
 #include "extensions/common/guest_view/guest_view_constants.h"
 #include "extensions/common/guest_view/guest_view_messages.h"
 
@@ -49,10 +50,10 @@
 // static.
 bool GuestViewContainer::HandlesMessage(const IPC::Message& msg) {
   switch (msg.type()) {
-    case GuestViewMsg_CreateMimeHandlerViewGuestACK::ID:
+    case ExtensionsGuestViewMsg_CreateMimeHandlerViewGuestACK::ID:
+    case ExtensionsGuestViewMsg_MimeHandlerViewGuestOnLoadCompleted::ID:
     case GuestViewMsg_GuestAttached::ID:
     case GuestViewMsg_GuestDetached::ID:
-    case GuestViewMsg_MimeHandlerViewGuestOnLoadCompleted::ID:
       return true;
     default:
       return false;
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
index 7688771..d71d6a2 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
@@ -12,6 +12,7 @@
 #include "content/public/renderer/render_view.h"
 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_constants.h"
 #include "extensions/common/extension_messages.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
 #include "extensions/common/guest_view/guest_view_constants.h"
 #include "extensions/common/guest_view/guest_view_messages.h"
 #include "gin/arguments.h"
@@ -164,11 +165,12 @@
 bool MimeHandlerViewContainer::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewContainer, message)
-  IPC_MESSAGE_HANDLER(GuestViewMsg_CreateMimeHandlerViewGuestACK,
+  IPC_MESSAGE_HANDLER(ExtensionsGuestViewMsg_CreateMimeHandlerViewGuestACK,
                       OnCreateMimeHandlerViewGuestACK)
+  IPC_MESSAGE_HANDLER(
+      ExtensionsGuestViewMsg_MimeHandlerViewGuestOnLoadCompleted,
+      OnMimeHandlerViewGuestOnLoadCompleted)
   IPC_MESSAGE_HANDLER(GuestViewMsg_GuestAttached, OnGuestAttached)
-  IPC_MESSAGE_HANDLER(GuestViewMsg_MimeHandlerViewGuestOnLoadCompleted,
-                      OnMimeHandlerViewGuestOnLoadCompleted)
   IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -177,7 +179,7 @@
 void MimeHandlerViewContainer::DidResizeElement(const gfx::Size& old_size,
                                                 const gfx::Size& new_size) {
   element_size_ = new_size;
-  render_frame()->Send(new GuestViewHostMsg_ResizeGuest(
+  render_frame()->Send(new ExtensionsGuestViewHostMsg_ResizeGuest(
       render_frame()->GetRoutingID(), element_instance_id(), new_size));
 }
 
@@ -233,11 +235,7 @@
   if (!window_object.Get(std::string(kPostMessageName), &post_message))
     return;
 
-#ifdef WEB_FRAME_USES_V8_LOCAL
-  v8::Local<v8::Value> args[] = {
-#else
   v8::Handle<v8::Value> args[] = {
-#endif
     message,
     // Post the message to any domain inside the browser plugin. The embedder
     // should already know what is embedded.
@@ -315,9 +313,10 @@
   if (!render_frame())
     return;
 
-  render_frame()->Send(new GuestViewHostMsg_CreateMimeHandlerViewGuest(
-      render_frame()->GetRoutingID(), view_id_, element_instance_id(),
-      element_size_));
+  render_frame()->Send(
+      new ExtensionsGuestViewHostMsg_CreateMimeHandlerViewGuest(
+          render_frame()->GetRoutingID(), view_id_, element_instance_id(),
+          element_size_));
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/messaging_bindings.cc b/extensions/renderer/messaging_bindings.cc
index dab2113..1266e5b 100644
--- a/extensions/renderer/messaging_bindings.cc
+++ b/extensions/renderer/messaging_bindings.cc
@@ -186,15 +186,21 @@
                      v8::Handle<v8::Function> callback,
                      v8::Isolate* isolate) {
       GCCallback* cb = new GCCallback(object, callback, isolate);
-      cb->object_.SetWeak(cb, NearDeathCallback);
+      cb->object_.SetWeak(cb, FirstWeakCallback,
+                          v8::WeakCallbackType::kParameter);
     }
 
    private:
-    static void NearDeathCallback(
-        const v8::WeakCallbackData<v8::Object, GCCallback>& data) {
+    static void FirstWeakCallback(
+        const v8::WeakCallbackInfo<GCCallback>& data) {
       // v8 says we need to explicitly reset weak handles from their callbacks.
       // It's not implicit as one might expect.
       data.GetParameter()->object_.Reset();
+      data.SetSecondPassCallback(SecondWeakCallback);
+    }
+
+    static void SecondWeakCallback(
+        const v8::WeakCallbackInfo<GCCallback>& data) {
       base::MessageLoop::current()->PostTask(
           FROM_HERE,
           base::Bind(&GCCallback::RunCallback,
diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc
index 8104fa0..9ed4c23f 100644
--- a/extensions/renderer/script_context.cc
+++ b/extensions/renderer/script_context.cc
@@ -188,19 +188,12 @@
         v8::Local<v8::Primitive>(v8::Undefined(isolate())));
   }
 
-#ifdef WEB_FRAME_USES_V8_LOCAL
-  v8::Local<v8::Value>* call_args =
-      reinterpret_cast<v8::Local<v8::Value>*>(argv);
-#else
-  v8::Handle<v8::Value>* call_args = argv;
-#endif
-
   v8::Handle<v8::Object> global = v8_context()->Global();
   if (!web_frame_)
     return handle_scope.Escape(function->Call(global, argc, argv));
   return handle_scope.Escape(
       v8::Local<v8::Value>(web_frame_->callFunctionEvenIfScriptDisabled(
-          function, global, argc, call_args)));
+          function, global, argc, argv)));
 }
 
 Feature::Availability ScriptContext::GetAvailability(
diff --git a/extensions/renderer/user_script_injector.cc b/extensions/renderer/user_script_injector.cc
index 08afb13..9a5a26d9 100644
--- a/extensions/renderer/user_script_injector.cc
+++ b/extensions/renderer/user_script_injector.cc
@@ -11,7 +11,7 @@
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
 #include "extensions/common/extension.h"
-#include "extensions/common/guest_view/guest_view_messages.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/renderer/injection_host.h"
 #include "extensions/renderer/script_context.h"
@@ -184,7 +184,7 @@
     // webviews, and then only once per host.
     // TODO(hanxi): Find a more efficient way to do this.
     content::RenderThread::Get()->Send(
-        new GuestViewHostMsg_CanExecuteContentScriptSync(
+        new ExtensionsGuestViewHostMsg_CanExecuteContentScriptSync(
             routing_id, script_->id(), &allowed));
     map.insert(std::pair<RoutingInfoKey, bool>(key, allowed));
   }
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index 64accfc..b7bf9ce 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -31,6 +31,7 @@
     ":version_header",
     "//base",
     "//base:prefs",
+    "//components/devtools_discovery",
     "//components/devtools_http_handler",
     "//components/pref_registry",
     "//components/update_client",
diff --git a/extensions/shell/app_shell.gyp b/extensions/shell/app_shell.gyp
index 466637d..25bd151 100644
--- a/extensions/shell/app_shell.gyp
+++ b/extensions/shell/app_shell.gyp
@@ -22,6 +22,7 @@
         'app_shell_version_header',
         '<(DEPTH)/base/base.gyp:base',
         '<(DEPTH)/base/base.gyp:base_prefs',
+        '<(DEPTH)/components/components.gyp:devtools_discovery',
         '<(DEPTH)/components/components.gyp:devtools_http_handler',
         '<(DEPTH)/components/components.gyp:pref_registry',
         '<(DEPTH)/components/components.gyp:update_client',
diff --git a/extensions/shell/browser/DEPS b/extensions/shell/browser/DEPS
index 43dda94..03437fd5 100644
--- a/extensions/shell/browser/DEPS
+++ b/extensions/shell/browser/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+chromeos",
+  "+components/devtools_discovery",
   "+components/devtools_http_handler",
   "+components/keyed_service",
   "+components/nacl/browser",
diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc
index d592b27..dba7763 100644
--- a/gin/array_buffer.cc
+++ b/gin/array_buffer.cc
@@ -73,10 +73,10 @@
   Private(v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> array);
   ~Private();
 
-  static void WeakCallback(
-      const v8::WeakCallbackData<v8::ArrayBuffer, Private>& data);
+  static void FirstWeakCallback(const v8::WeakCallbackInfo<Private>& data);
+  static void SecondWeakCallback(const v8::WeakCallbackInfo<Private>& data);
 
-  v8::Persistent<v8::ArrayBuffer> array_buffer_;
+  v8::Global<v8::ArrayBuffer> array_buffer_;
   scoped_refptr<Private> self_reference_;
   v8::Isolate* isolate_;
   void* buffer_;
@@ -108,18 +108,25 @@
                                           &g_array_buffer_wrapper_info);
   array->SetAlignedPointerInInternalField(kEncodedValueIndex, this);
 
-  self_reference_ = this;  // Cleared in WeakCallback.
-  array_buffer_.SetWeak(this, WeakCallback);
+  self_reference_ = this;  // Cleared in SecondWeakCallback.
+  array_buffer_.SetWeak(this, FirstWeakCallback,
+                        v8::WeakCallbackType::kParameter);
 }
 
 ArrayBuffer::Private::~Private() {
   PerIsolateData::From(isolate_)->allocator()->Free(buffer_, length_);
 }
 
-void ArrayBuffer::Private::WeakCallback(
-    const v8::WeakCallbackData<v8::ArrayBuffer, Private>& data) {
+void ArrayBuffer::Private::FirstWeakCallback(
+    const v8::WeakCallbackInfo<Private>& data) {
   Private* parameter = data.GetParameter();
   parameter->array_buffer_.Reset();
+  data.SetSecondPassCallback(SecondWeakCallback);
+}
+
+void ArrayBuffer::Private::SecondWeakCallback(
+    const v8::WeakCallbackInfo<Private>& data) {
+  Private* parameter = data.GetParameter();
   parameter->self_reference_ = NULL;
 }
 
diff --git a/gin/function_template.cc b/gin/function_template.cc
index f76a05be..7b85170 100644
--- a/gin/function_template.cc
+++ b/gin/function_template.cc
@@ -10,7 +10,8 @@
 
 CallbackHolderBase::CallbackHolderBase(v8::Isolate* isolate)
     : v8_ref_(isolate, v8::External::New(isolate, this)) {
-  v8_ref_.SetWeak(this, &CallbackHolderBase::WeakCallback);
+  v8_ref_.SetWeak(this, &CallbackHolderBase::FirstWeakCallback,
+                  v8::WeakCallbackType::kParameter);
 }
 
 CallbackHolderBase::~CallbackHolderBase() {
@@ -22,9 +23,15 @@
 }
 
 // static
-void CallbackHolderBase::WeakCallback(
-    const v8::WeakCallbackData<v8::External, CallbackHolderBase>& data) {
+void CallbackHolderBase::FirstWeakCallback(
+    const v8::WeakCallbackInfo<CallbackHolderBase>& data) {
   data.GetParameter()->v8_ref_.Reset();
+  data.SetSecondPassCallback(SecondWeakCallback);
+}
+
+// static
+void CallbackHolderBase::SecondWeakCallback(
+    const v8::WeakCallbackInfo<CallbackHolderBase>& data) {
   delete data.GetParameter();
 }
 
diff --git a/gin/function_template.h b/gin/function_template.h
index a2e1755..1c8e2be 100644
--- a/gin/function_template.h
+++ b/gin/function_template.h
@@ -51,10 +51,12 @@
   virtual ~CallbackHolderBase();
 
  private:
-  static void WeakCallback(
-      const v8::WeakCallbackData<v8::External, CallbackHolderBase>& data);
+  static void FirstWeakCallback(
+      const v8::WeakCallbackInfo<CallbackHolderBase>& data);
+  static void SecondWeakCallback(
+      const v8::WeakCallbackInfo<CallbackHolderBase>& data);
 
-  v8::Persistent<v8::External> v8_ref_;
+  v8::Global<v8::External> v8_ref_;
 
   DISALLOW_COPY_AND_ASSIGN(CallbackHolderBase);
 };
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 67b5f88d..a57afc9b 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -136,8 +136,16 @@
     return false;
 
 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
-  return VerifyV8SnapshotFile(g_mapped_natives, g_natives_fingerprint) &&
-         VerifyV8SnapshotFile(g_mapped_snapshot, g_snapshot_fingerprint);
+  // TODO(oth) Remove these temporary CHECKs once http://crbug.com/479537 is
+  // fixed. These are just here to identify whether canary failures are
+  // due to verification or file/vm failures.
+  bool natives_ok =
+      VerifyV8SnapshotFile(g_mapped_natives, g_natives_fingerprint);
+  CHECK(natives_ok);
+  bool snapshot_ok =
+      VerifyV8SnapshotFile(g_mapped_snapshot, g_snapshot_fingerprint);
+  CHECK(snapshot_ok);
+  return natives_ok && snapshot_ok;
 #else
   return true;
 #endif  // V8_VERIFY_EXTERNAL_STARTUP_DATA
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index a330fef..4137609 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -22,10 +22,16 @@
   return ObjectTemplateBuilder(isolate);
 }
 
-void WrappableBase::WeakCallback(
-    const v8::WeakCallbackData<v8::Object, WrappableBase>& data) {
+void WrappableBase::FirstWeakCallback(
+    const v8::WeakCallbackInfo<WrappableBase>& data) {
   WrappableBase* wrappable = data.GetParameter();
   wrappable->wrapper_.Reset();
+  data.SetSecondPassCallback(SecondWeakCallback);
+}
+
+void WrappableBase::SecondWeakCallback(
+    const v8::WeakCallbackInfo<WrappableBase>& data) {
+  WrappableBase* wrappable = data.GetParameter();
   delete wrappable;
 }
 
@@ -55,7 +61,7 @@
   wrapper->SetAlignedPointerInInternalField(kWrapperInfoIndex, info);
   wrapper->SetAlignedPointerInInternalField(kEncodedValueIndex, this);
   wrapper_.Reset(isolate, wrapper);
-  wrapper_.SetWeak(this, WeakCallback);
+  wrapper_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kParameter);
   return wrapper;
 }
 
diff --git a/gin/wrappable.h b/gin/wrappable.h
index ff52b19a..ea4edcf 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -68,10 +68,12 @@
                                         WrapperInfo* wrapper_info);
 
  private:
-  static void WeakCallback(
-      const v8::WeakCallbackData<v8::Object, WrappableBase>& data);
+  static void FirstWeakCallback(
+      const v8::WeakCallbackInfo<WrappableBase>& data);
+  static void SecondWeakCallback(
+      const v8::WeakCallbackInfo<WrappableBase>& data);
 
-  v8::Persistent<v8::Object> wrapper_;  // Weak
+  v8::Global<v8::Object> wrapper_;  // Weak
 
   DISALLOW_COPY_AND_ASSIGN(WrappableBase);
 };
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn
index a595bd88..6cf7526b 100644
--- a/google_apis/BUILD.gn
+++ b/google_apis/BUILD.gn
@@ -67,13 +67,14 @@
     defines += [ "USE_OFFICIAL_GOOGLE_API_KEYS=1" ]
   }
   if (google_api_key != "") {
-    defines += [ "GOOGLE_API_KEY=$google_api_key" ]
+    defines += [ "GOOGLE_API_KEY=\"$google_api_key\"" ]
   }
   if (google_default_client_id != "") {
-    defines += [ "GOOGLE_DEFAULT_CLIENT_ID=$google_default_client_id" ]
+    defines += [ "GOOGLE_DEFAULT_CLIENT_ID=\"$google_default_client_id\"" ]
   }
   if (google_default_client_secret != "") {
-    defines += [ "GOOGLE_DEFAULT_CLIENT_SECRET=$google_default_client_secret" ]
+    defines +=
+        [ "GOOGLE_DEFAULT_CLIENT_SECRET=\"$google_default_client_secret\"" ]
   }
 }
 
@@ -102,10 +103,10 @@
     "gaia/oauth2_access_token_consumer.h",
     "gaia/oauth2_access_token_fetcher.cc",
     "gaia/oauth2_access_token_fetcher.h",
-    "gaia/oauth2_access_token_fetcher_impl.cc",
-    "gaia/oauth2_access_token_fetcher_impl.h",
     "gaia/oauth2_access_token_fetcher_immediate_error.cc",
     "gaia/oauth2_access_token_fetcher_immediate_error.h",
+    "gaia/oauth2_access_token_fetcher_impl.cc",
+    "gaia/oauth2_access_token_fetcher_impl.h",
     "gaia/oauth2_api_call_flow.cc",
     "gaia/oauth2_api_call_flow.h",
     "gaia/oauth2_mint_token_flow.cc",
diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc
index 69aac650..0f464c5 100644
--- a/google_apis/gcm/tools/mcs_probe.cc
+++ b/google_apis/gcm/tools/mcs_probe.cc
@@ -359,7 +359,8 @@
   }
   if (log_file.get()) {
     logger_.reset(new net::WriteToFileNetLogObserver());
-    logger_->set_log_level(net::NetLog::LOG_ALL_BUT_BYTES);
+    logger_->set_capture_mode(
+        net::NetLogCaptureMode::IncludeCookiesAndCredentials());
     logger_->StartObserving(&net_log_, log_file.Pass(), nullptr, nullptr);
   }
 
diff --git a/gpu/command_buffer/command_buffer_nacl.gyp b/gpu/command_buffer/command_buffer_nacl.gyp
index 319fc67..e0589996 100644
--- a/gpu/command_buffer/command_buffer_nacl.gyp
+++ b/gpu/command_buffer/command_buffer_nacl.gyp
@@ -27,7 +27,6 @@
             '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/gpu_nacl.gyp b/gpu/gpu_nacl.gyp
index 003f0af..1f38619 100644
--- a/gpu/gpu_nacl.gyp
+++ b/gpu/gpu_nacl.gyp
@@ -36,7 +36,6 @@
           'dependencies': [
             '../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',
@@ -60,7 +59,6 @@
           'dependencies': [
             '../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',
           ],
         },
@@ -82,7 +80,6 @@
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl',
             '../base/base_nacl.gyp:base_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
             'command_buffer_client_nacl',
           ],
         },
@@ -104,7 +101,6 @@
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl',
             '../base/base_nacl.gyp:base_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
             'command_buffer_common_nacl',
           ],
         },
@@ -126,7 +122,6 @@
           'dependencies': [
             '../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/chrome/browser/translate/chrome_ios_translate_client.mm b/ios/chrome/browser/translate/chrome_ios_translate_client.mm
index 7054005..a4d0c27 100644
--- a/ios/chrome/browser/translate/chrome_ios_translate_client.mm
+++ b/ios/chrome/browser/translate/chrome_ios_translate_client.mm
@@ -17,6 +17,7 @@
 #include "components/translate/core/browser/translate_step.h"
 #include "ios/chrome/browser/infobars/infobar.h"
 #include "ios/chrome/browser/infobars/infobar_controller.h"
+#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #include "ios/chrome/browser/pref_names.h"
 #import "ios/chrome/browser/translate/after_translate_infobar_controller.h"
 #import "ios/chrome/browser/translate/before_translate_infobar_controller.h"
@@ -26,7 +27,6 @@
 #include "ios/chrome/browser/translate/translate_service_ios.h"
 #include "ios/chrome/grit/ios_theme_resources.h"
 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #include "ios/web/public/browser_state.h"
 #include "ios/web/public/web_state/web_state.h"
 #include "url/gurl.h"
@@ -103,7 +103,7 @@
   translate::TranslateInfoBarDelegate::Create(
       step != translate::TRANSLATE_STEP_BEFORE_TRANSLATE,
       translate_manager_->GetWeakPtr(),
-      ios::GetChromeBrowserProvider()->GetInfoBarManager(web_state()),
+      InfoBarManagerImpl::FromWebState(web_state()),
       web_state()->GetBrowserState()->IsOffTheRecord(), step, source_language,
       target_language, error_type, triggered_from_menu);
 }
diff --git a/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm b/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm
index 66cb5753..47bf38a 100644
--- a/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm
+++ b/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm
@@ -11,9 +11,9 @@
 namespace {
 
 // The absolute maximum swipe angle from |x = y| for a swipe to begin.
-CGFloat kMaxSwipeYAngle = 65;
+const CGFloat kMaxSwipeYAngle = 65;
 // The distance between touches for a swipe to begin.
-CGFloat kMinSwipeXThreshold = 4;
+const CGFloat kMinSwipeXThreshold = 4;
 
 }  // namespace
 
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.cc b/ios/public/provider/chrome/browser/chrome_browser_provider.cc
index 72a700f..25d98fd 100644
--- a/ios/public/provider/chrome/browser/chrome_browser_provider.cc
+++ b/ios/public/provider/chrome/browser/chrome_browser_provider.cc
@@ -39,11 +39,6 @@
   return nullptr;
 }
 
-infobars::InfoBarManager* ChromeBrowserProvider::GetInfoBarManager(
-    web::WebState* web_state) {
-  return nullptr;
-}
-
 StringProvider* ChromeBrowserProvider::GetStringProvider() {
   return nullptr;
 }
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h
index 99a7b6e..bf7a1fe 100644
--- a/ios/public/provider/chrome/browser/chrome_browser_provider.h
+++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -7,10 +7,6 @@
 
 class PrefService;
 
-namespace infobars {
-class InfoBarManager;
-}
-
 namespace net {
 class URLRequestContextGetter;
 }
@@ -54,8 +50,6 @@
   // Returns an instance of an infobar view. The caller is responsible for
   // initializing the returned object and releasing it when appropriate.
   virtual InfoBarViewPlaceholder* CreateInfoBarView();
-  // Gets the infobar manager associated with |web_state|.
-  virtual infobars::InfoBarManager* GetInfoBarManager(web::WebState* web_state);
   // Returns an instance of a string provider.
   virtual StringProvider* GetStringProvider();
   // Displays the Translate settings screen.
diff --git a/ios/web/public/web_state/web_state_observer.h b/ios/web/public/web_state/web_state_observer.h
index cd254f84..c24e299 100644
--- a/ios/web/public/web_state/web_state_observer.h
+++ b/ios/web/public/web_state/web_state_observer.h
@@ -32,6 +32,9 @@
   // Returns the web state associated with this observer.
   WebState* web_state() const { return web_state_; }
 
+  // This method is invoked when a load request is registered.
+  virtual void ProvisionalNavigationStarted(const GURL& url) {}
+
   // This method is invoked when a new non-pending navigation item is created.
   // This corresponds to one NavigationManager item being created
   // (in the case of new navigations) or renavigated to (for back/forward
diff --git a/ios/web/public/web_state/web_state_observer_bridge.h b/ios/web/public/web_state/web_state_observer_bridge.h
index bc34bd61..e61bea441 100644
--- a/ios/web/public/web_state/web_state_observer_bridge.h
+++ b/ios/web/public/web_state/web_state_observer_bridge.h
@@ -18,6 +18,11 @@
 // web::WebStateObserver, wrap in a web::WebStateObserverBridge.
 @protocol CRWWebStateObserver<NSObject>
 @optional
+
+// Invoked by WebStateObserverBridge::ProvisionalNavigationStarted.
+- (void)webState:(web::WebState*)webState
+    didStartProvisionalNavigationForURL:(const GURL&)URL;
+
 // Invoked by WebStateObserverBridge::NavigationItemCommitted.
 - (void)webState:(web::WebState*)webState
     didCommitNavigationWithDetails:
@@ -82,6 +87,7 @@
   ~WebStateObserverBridge() override;
 
   // web::WebStateObserver methods.
+  void ProvisionalNavigationStarted(const GURL& url) override;
   void NavigationItemCommitted(
       const LoadCommittedDetails& load_details) override;
   void PageLoaded(
diff --git a/ios/web/web_state/web_state_observer_bridge.mm b/ios/web/web_state/web_state_observer_bridge.mm
index eef1be78..c2028fe8 100644
--- a/ios/web/web_state/web_state_observer_bridge.mm
+++ b/ios/web/web_state/web_state_observer_bridge.mm
@@ -14,6 +14,13 @@
 WebStateObserverBridge::~WebStateObserverBridge() {
 }
 
+void WebStateObserverBridge::ProvisionalNavigationStarted(const GURL& url) {
+  SEL selector = @selector(webState:didStartProvisionalNavigationForURL:);
+  if ([observer_ respondsToSelector:selector]) {
+    [observer_ webState:web_state() didStartProvisionalNavigationForURL:url];
+  }
+}
+
 void WebStateObserverBridge::NavigationItemCommitted(
     const web::LoadCommittedDetails& load_detatils) {
   SEL selector = @selector(webState:didCommitNavigationWithDetails:);
diff --git a/ipc/ipc_channel_win.h b/ipc/ipc_channel_win.h
index 3838106..04990d4 100644
--- a/ipc/ipc_channel_win.h
+++ b/ipc/ipc_channel_win.h
@@ -29,26 +29,24 @@
   // Mirror methods of Channel, see ipc_channel.h for description.
   ChannelWin(const IPC::ChannelHandle &channel_handle, Mode mode,
              Listener* listener);
-  ~ChannelWin();
+  ~ChannelWin() override;
 
   // Channel implementation
-  virtual bool Connect() override;
-  virtual void Close() override;
-  virtual bool Send(Message* message) override;
-  virtual base::ProcessId GetPeerPID() const override;
-  virtual base::ProcessId GetSelfPID() const override;
+  bool Connect() override;
+  void Close() override;
+  bool Send(Message* message) override;
+  base::ProcessId GetPeerPID() const override;
+  base::ProcessId GetSelfPID() const override;
 
   static bool IsNamedServerInitialized(const std::string& channel_id);
 
 
  private:
   // ChannelReader implementation.
-  virtual ReadState ReadData(char* buffer,
-                             int buffer_len,
-                             int* bytes_read) override;
-  virtual bool WillDispatchInputMessage(Message* msg) override;
+  ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override;
+  bool WillDispatchInputMessage(Message* msg) override;
   bool DidEmptyInputBuffers() override;
-  virtual void HandleInternalMessage(const Message& msg) override;
+  void HandleInternalMessage(const Message& msg) override;
 
   static const base::string16 PipeName(const std::string& channel_id,
                                        int32* secret);
@@ -59,9 +57,9 @@
                                DWORD bytes_written);
 
   // MessageLoop::IOHandler implementation.
-  virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
-                             DWORD bytes_transfered,
-                             DWORD error) override;
+  void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
+                     DWORD bytes_transfered,
+                     DWORD error) override;
 
  private:
   struct State {
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index 1cec310f..3cf58f921 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -115,6 +115,7 @@
   NavigatorConnectMsgStart,
   CastMediaMsgStart,
   AwMessagePortMsgStart,
+  ExtensionsGuestViewMsgStart,
   GuestViewMsgStart,
   // Note: CastCryptoMsgStart and CastChannelMsgStart reserved for Chromecast
   // internal code. Contact gunsch@ before changing/removing.
diff --git a/ipc/ipc_nacl.gyp b/ipc/ipc_nacl.gyp
index 6f0d522d..5faf9af 100644
--- a/ipc/ipc_nacl.gyp
+++ b/ipc/ipc_nacl.gyp
@@ -26,7 +26,6 @@
           },
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl',
-            '../native_client/tools.gyp:prep_toolchain',
           ],
         },
         {
@@ -56,7 +55,6 @@
           ],
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
           ],
         },
       ],
diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc
index f834ec3..468a18f 100644
--- a/ipc/ipc_sync_channel_unittest.cc
+++ b/ipc/ipc_sync_channel_unittest.cc
@@ -124,7 +124,7 @@
 
  protected:
   SyncChannel* channel() { return channel_.get(); }
-  // Functions for dervied classes to implement if they wish.
+  // Functions for derived classes to implement if they wish.
   virtual void Run() { }
   virtual void OnAnswer(int* answer) { NOTREACHED(); }
   virtual void OnAnswerDelay(Message* reply_msg) {
diff --git a/jingle/jingle_nacl.gyp b/jingle/jingle_nacl.gyp
index d622fbe..b20f6414 100644
--- a/jingle/jingle_nacl.gyp
+++ b/jingle/jingle_nacl.gyp
@@ -31,7 +31,6 @@
       ],
       'dependencies': [
         '../base/base_nacl.gyp:base_nacl',
-        '../native_client/tools.gyp:prep_toolchain',
         '../net/net_nacl.gyp:net_nacl',
         '../third_party/libjingle/libjingle_nacl.gyp:libjingle_nacl',
       ],
diff --git a/mandoline/app/BUILD.gn b/mandoline/app/BUILD.gn
index cc9a9318..0058c1b7 100644
--- a/mandoline/app/BUILD.gn
+++ b/mandoline/app/BUILD.gn
@@ -17,7 +17,6 @@
     "//build/config/sanitizers:deps",
     "//mojo/common",
     "//mojo/environment:chromium",
-    "//mojo/shell:init",
     "//mojo/shell:lib",
   ]
 
diff --git a/media/audio/audio_input_volume_unittest.cc b/media/audio/audio_input_volume_unittest.cc
index d6ee313..19c712a 100644
--- a/media/audio/audio_input_volume_unittest.cc
+++ b/media/audio/audio_input_volume_unittest.cc
@@ -38,13 +38,7 @@
 
 class AudioInputVolumeTest : public ::testing::Test {
  protected:
-  AudioInputVolumeTest()
-      : audio_manager_(AudioManager::CreateForTesting())
-#if defined(OS_WIN)
-       , com_init_(base::win::ScopedCOMInitializer::kMTA)
-#endif
-  {
-  }
+  AudioInputVolumeTest() : audio_manager_(AudioManager::CreateForTesting()) {}
 
   bool HasCoreAudioAndInputDevices() {
 #if defined(OS_WIN)
@@ -70,27 +64,27 @@
         params, device_id);
     EXPECT_TRUE(NULL != ais);
 
-#if defined(OS_LINUX) || defined(OS_OPENBSD)
-    // Some linux devices do not support our settings, we may fail to open
-    // those devices.
+#if defined(OS_MACOSX)
+    EXPECT_TRUE(ais->Open());
+#else
+    // Some linux devices do not support our settings and some Windows devices
+    // may be "currently unavailable", we may fail to open those devices.
     if (!ais->Open()) {
       // Default device should always be able to be opened.
       EXPECT_TRUE(AudioManagerBase::kDefaultDeviceId != device_id);
       ais->Close();
       ais = NULL;
     }
-#elif defined(OS_WIN) || defined(OS_MACOSX)
-    EXPECT_TRUE(ais->Open());
 #endif
 
     return ais;
   }
 
-  scoped_ptr<AudioManager> audio_manager_;
-
 #if defined(OS_WIN)
   base::win::ScopedCOMInitializer com_init_;
 #endif
+
+  scoped_ptr<AudioManager> audio_manager_;
 };
 
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc
index 6ee61d16..2bbffa7 100644
--- a/media/audio/audio_manager.cc
+++ b/media/audio/audio_manager.cc
@@ -11,6 +11,7 @@
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "base/power_monitor/power_monitor.h"
+#include "base/synchronization/waitable_event.h"
 #include "build/build_config.h"
 #include "media/audio/fake_audio_log_factory.h"
 
@@ -157,7 +158,19 @@
 
 // static
 AudioManager* AudioManager::CreateForTesting() {
-  return Create(g_helper.Pointer()->fake_log_factory());
+  AudioManager* manager = Create(g_helper.Pointer()->fake_log_factory());
+
+  // When created for testing, always ensure all methods are ready to run (even
+  // if they end up called from other threads.
+  if (!manager->GetTaskRunner()->BelongsToCurrentThread()) {
+    base::WaitableEvent event(false, false);
+    manager->GetTaskRunner()->PostTask(
+        FROM_HERE,
+        base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
+    event.Wait();
+  }
+
+  return manager;
 }
 
 // static
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index edaabf4c..24e0883 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -83,7 +83,10 @@
       audio_thread_("AudioThread"),
       audio_log_factory_(audio_log_factory) {
 #if defined(OS_WIN)
-  audio_thread_.init_com_with_mta(true);
+  // Do not use MTA mode initalization as it causes hangs for a significant
+  // population of users and is not supported on Windows 8 for audio capture
+  // and rendering.  See http://crbug.com/422522.
+  audio_thread_.init_com_with_mta(false);
 #elif defined(OS_MACOSX)
   // CoreAudio calls must occur on the main thread of the process, which in our
   // case is sadly the browser UI thread.  Failure to execute calls on the right
diff --git a/media/audio/audio_manager_unittest.cc b/media/audio/audio_manager_unittest.cc
index 26c110e..e876dd1 100644
--- a/media/audio/audio_manager_unittest.cc
+++ b/media/audio/audio_manager_unittest.cc
@@ -33,19 +33,7 @@
 // Windows.
 class AudioManagerTest : public ::testing::Test {
  protected:
-  AudioManagerTest()
-      : audio_manager_(AudioManager::CreateForTesting())
-#if defined(OS_WIN)
-      , com_init_(base::win::ScopedCOMInitializer::kMTA)
-#endif
-  {
-    // Wait for audio thread initialization to complete.  Otherwise the
-    // enumeration type may not have been set yet.
-    base::WaitableEvent event(false, false);
-    audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
-        &base::WaitableEvent::Signal, base::Unretained(&event)));
-    event.Wait();
-  }
+  AudioManagerTest() : audio_manager_(AudioManager::CreateForTesting()) {}
 
 #if defined(OS_WIN)
   bool SetMMDeviceEnumeration() {
@@ -55,13 +43,13 @@
     if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
       return false;
 
-    amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
+    amw->set_enumeration_type(AudioManagerWin::kMMDeviceEnumeration);
     return true;
   }
 
   void SetWaveEnumeration() {
     AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
-    amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration);
+    amw->set_enumeration_type(AudioManagerWin::kWaveEnumeration);
   }
 
   std::string GetDeviceIdFromPCMWaveInAudioInputStream(
diff --git a/media/audio/win/audio_device_listener_win.h b/media/audio/win/audio_device_listener_win.h
index 92777a1..9c2ac482 100644
--- a/media/audio/win/audio_device_listener_win.h
+++ b/media/audio/win/audio_device_listener_win.h
@@ -36,15 +36,17 @@
   friend class AudioDeviceListenerWinTest;
 
   // IMMNotificationClient implementation.
-  STDMETHOD_(ULONG, AddRef)();
-  STDMETHOD_(ULONG, Release)();
-  STDMETHOD(QueryInterface)(REFIID iid, void** object);
-  STDMETHOD(OnPropertyValueChanged)(LPCWSTR device_id, const PROPERTYKEY key);
-  STDMETHOD(OnDeviceAdded)(LPCWSTR device_id);
-  STDMETHOD(OnDeviceRemoved)(LPCWSTR device_id);
-  STDMETHOD(OnDeviceStateChanged)(LPCWSTR device_id, DWORD new_state);
-  STDMETHOD(OnDefaultDeviceChanged)(EDataFlow flow, ERole role,
-                                    LPCWSTR new_default_device_id);
+  STDMETHOD_(ULONG, AddRef)() override;
+  STDMETHOD_(ULONG, Release)() override;
+  STDMETHOD(QueryInterface)(REFIID iid, void** object) override;
+  STDMETHOD(OnPropertyValueChanged)(LPCWSTR device_id,
+                                    const PROPERTYKEY key) override;
+  STDMETHOD(OnDeviceAdded)(LPCWSTR device_id) override;
+  STDMETHOD(OnDeviceRemoved)(LPCWSTR device_id) override;
+  STDMETHOD(OnDeviceStateChanged)(LPCWSTR device_id, DWORD new_state) override;
+  STDMETHOD(OnDefaultDeviceChanged)(EDataFlow flow,
+                                    ERole role,
+                                    LPCWSTR new_default_device_id) override;
 
   base::Closure listener_cb_;
   ScopedComPtr<IMMDeviceEnumerator> device_enumerator_;
diff --git a/media/audio/win/audio_device_listener_win_unittest.cc b/media/audio/win/audio_device_listener_win_unittest.cc
index 49a1359..9f9dc2b 100644
--- a/media/audio/win/audio_device_listener_win_unittest.cc
+++ b/media/audio/win/audio_device_listener_win_unittest.cc
@@ -25,9 +25,7 @@
 
 class AudioDeviceListenerWinTest : public testing::Test {
  public:
-  AudioDeviceListenerWinTest()
-      : com_init_(ScopedCOMInitializer::kMTA) {
-  }
+  AudioDeviceListenerWinTest() {}
 
   virtual void SetUp() {
     if (!CoreAudioUtil::IsSupported())
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc
index 72d1d72..674a097 100644
--- a/media/audio/win/audio_low_latency_input_win.cc
+++ b/media/audio/win/audio_low_latency_input_win.cc
@@ -158,6 +158,11 @@
   // using SetAutomaticGainControl().
   StartAgc();
 
+  if (!MarshalComPointers()) {
+    HandleError(S_FALSE);
+    return;
+  }
+
   // Create and start the thread that will drive the capturing by waiting for
   // capture events.
   capture_thread_ =
@@ -172,6 +177,8 @@
     hr = audio_render_client_for_loopback_->Start();
 
   started_ = SUCCEEDED(hr);
+  if (!started_)
+    HandleError(hr);
 }
 
 void WASAPIAudioInputStream::Stop() {
@@ -350,7 +357,7 @@
 }
 
 void WASAPIAudioInputStream::Run() {
-  ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA);
+  ScopedCOMInitializer com_init;
 
   // Increase the thread priority.
   capture_thread_->SetThreadPriority(base::ThreadPriority::REALTIME_AUDIO);
@@ -369,6 +376,10 @@
     LOG(WARNING) << "Failed to enable MMCSS (error code=" << err << ").";
   }
 
+  // Retrieve COM pointers from the main thread.
+  ScopedComPtr<IAudioCaptureClient> audio_capture_client;
+  UnmarshalComPointers(&audio_capture_client);
+
   // Allocate a buffer with a size that enables us to take care of cases like:
   // 1) The recorded buffer size is smaller, or does not match exactly with,
   //    the selected packet size used in each callback.
@@ -383,7 +394,7 @@
   LARGE_INTEGER now_count;
   bool recording = true;
   bool error = false;
-  double volume = GetVolume();
+  double volume = 0;
   HANDLE wait_array[2] =
       { stop_capture_event_.Get(), audio_samples_ready_event_.Get() };
 
@@ -412,11 +423,9 @@
           // Retrieve the amount of data in the capture endpoint buffer,
           // replace it with silence if required, create callbacks for each
           // packet and store non-delivered data for the next event.
-          hr = audio_capture_client_->GetBuffer(&data_ptr,
-                                                &num_frames_to_read,
-                                                &flags,
-                                                &device_position,
-                                                &first_audio_frame_timestamp);
+          hr = audio_capture_client->GetBuffer(
+              &data_ptr, &num_frames_to_read, &flags, &device_position,
+              &first_audio_frame_timestamp);
           if (FAILED(hr)) {
             DLOG(ERROR) << "Failed to get data from the capture buffer";
             continue;
@@ -438,7 +447,7 @@
             buffer_frame_index += num_frames_to_read;
           }
 
-          hr = audio_capture_client_->ReleaseBuffer(num_frames_to_read);
+          hr = audio_capture_client->ReleaseBuffer(num_frames_to_read);
           DLOG_IF(ERROR, FAILED(hr)) << "Failed to release capture buffer";
 
           // Derive a delay estimate for the captured audio packet.
@@ -676,8 +685,11 @@
       &format_,
       (effects_ & AudioParameters::DUCKING) ? &kCommunicationsSessionId : NULL);
 
-  if (FAILED(hr))
+  if (FAILED(hr)) {
+    PLOG(ERROR) << "Failed to initalize IAudioClient: " << std::hex << hr
+                << " : ";
     return hr;
+  }
 
   // Retrieve the length of the endpoint buffer shared between the client
   // and the audio engine. The buffer length determines the maximum amount
@@ -768,4 +780,26 @@
   return hr;
 }
 
+bool WASAPIAudioInputStream::MarshalComPointers() {
+  DCHECK(CalledOnValidThread());
+  DCHECK(!com_stream_);
+  HRESULT hr = CoMarshalInterThreadInterfaceInStream(
+      __uuidof(IAudioCaptureClient), audio_capture_client_.get(),
+      com_stream_.Receive());
+  if (FAILED(hr))
+    DLOG(ERROR) << "Marshal failed for IAudioCaptureClient: " << std::hex << hr;
+  DCHECK_EQ(SUCCEEDED(hr), !!com_stream_);
+  return SUCCEEDED(hr);
+}
+
+void WASAPIAudioInputStream::UnmarshalComPointers(
+    ScopedComPtr<IAudioCaptureClient>* audio_capture_client) {
+  DCHECK_EQ(capture_thread_->tid(), base::PlatformThread::CurrentId());
+  DCHECK(com_stream_);
+  HRESULT hr = CoGetInterfaceAndReleaseStream(
+      com_stream_.Detach(), __uuidof(IAudioCaptureClient),
+      audio_capture_client->ReceiveVoid());
+  CHECK(SUCCEEDED(hr));
+}
+
 }  // namespace media
diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h
index e933a447..00a7de7 100644
--- a/media/audio/win/audio_low_latency_input_win.h
+++ b/media/audio/win/audio_low_latency_input_win.h
@@ -92,17 +92,17 @@
 
   // The dtor is typically called by the AudioManager only and it is usually
   // triggered by calling AudioInputStream::Close().
-  virtual ~WASAPIAudioInputStream();
+  ~WASAPIAudioInputStream() override;
 
   // Implementation of AudioInputStream.
-  virtual bool Open() override;
-  virtual void Start(AudioInputCallback* callback) override;
-  virtual void Stop() override;
-  virtual void Close() override;
-  virtual double GetMaxVolume() override;
-  virtual void SetVolume(double volume) override;
-  virtual double GetVolume() override;
-  virtual bool IsMuted() override;
+  bool Open() override;
+  void Start(AudioInputCallback* callback) override;
+  void Stop() override;
+  void Close() override;
+  double GetMaxVolume() override;
+  void SetVolume(double volume) override;
+  double GetVolume() override;
+  bool IsMuted() override;
 
   bool started() const { return started_; }
 
@@ -111,7 +111,7 @@
 
  private:
   // DelegateSimpleThread::Delegate implementation.
-  virtual void Run() override;
+  void Run() override;
 
   // Issues the OnError() callback to the |sink_|.
   void HandleError(HRESULT err);
@@ -131,6 +131,13 @@
                               WAVEFORMATEX** device_format,
                               int* effects);
 
+  // Handles sharing of COM pointers between the audio and capture threads.  The
+  // marshal method must be called on the audio manager thread, while unmarshal
+  // must be called on |capture_thread_|.
+  bool MarshalComPointers();
+  void UnmarshalComPointers(
+      base::win::ScopedComPtr<IAudioCaptureClient>* audio_capture_client);
+
   // Our creator, the audio manager needs to be notified when we close.
   AudioManagerWin* manager_;
 
@@ -179,8 +186,17 @@
   // Pointer to the object that will receive the recorded audio samples.
   AudioInputCallback* sink_;
 
-  // Windows Multimedia Device (MMDevice) API interfaces.
+  // ------------------------------------------------------
+  // Warning: COM pointers must be marshaled from the audio thread to be used
+  // on any other thread. Do not use any of these interfaces on a thread other
+  // than the audio thread.  See MarshalComPointers() and UnmarshalComPointers()
+  // for marshaling pointers to the capture thread.
 
+  // Stream into which the COM pointers below are marshaled so that they can
+  // be used on another thread.
+  base::win::ScopedComPtr<IStream> com_stream_;
+
+  // Windows Multimedia Device (MMDevice) API interfaces.
   // An IMMDevice interface which represents an audio endpoint device.
   base::win::ScopedComPtr<IMMDevice> endpoint_device_;
 
@@ -198,16 +214,17 @@
   // details.
   base::win::ScopedComPtr<IAudioClient> audio_render_client_for_loopback_;
 
-  // The IAudioCaptureClient interface enables a client to read input data
-  // from a capture endpoint buffer.
-  base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_;
-
   // The ISimpleAudioVolume interface enables a client to control the
   // master volume level of an audio session.
   // The volume-level is a value in the range 0.0 to 1.0.
   // This interface does only work with shared-mode streams.
   base::win::ScopedComPtr<ISimpleAudioVolume> simple_audio_volume_;
 
+  // The IAudioCaptureClient interface enables a client to read input data
+  // from a capture endpoint buffer.
+  base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_;
+  // ------------------------------------------------------
+
   // The audio engine will signal this event each time a buffer has been
   // recorded.
   base::win::ScopedHandle audio_samples_ready_event_;
diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc
index 69a24f8b..60d386d 100644
--- a/media/audio/win/audio_low_latency_input_win_unittest.cc
+++ b/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -163,11 +163,9 @@
 class AudioInputStreamWrapper {
  public:
   explicit AudioInputStreamWrapper(AudioManager* audio_manager)
-      : com_init_(ScopedCOMInitializer::kMTA),
-        audio_man_(audio_manager),
-        default_params_(
-            audio_manager->GetInputStreamParameters(
-                  AudioManagerBase::kDefaultDeviceId)) {
+      : audio_man_(audio_manager),
+        default_params_(audio_man_->GetInputStreamParameters(
+            AudioManagerBase::kDefaultDeviceId)) {
     EXPECT_EQ(format(), AudioParameters::AUDIO_PCM_LOW_LATENCY);
     frames_per_buffer_ = default_params_.frames_per_buffer();
     // We expect the default buffer size to be a 10ms buffer.
@@ -207,7 +205,6 @@
     return ais;
   }
 
-  ScopedCOMInitializer com_init_;
   AudioManager* audio_man_;
   const AudioParameters default_params_;
   int frames_per_buffer_;
@@ -254,17 +251,24 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream);
 };
 
+class WinAudioInputTest : public testing::Test {
+ public:
+  WinAudioInputTest() : audio_manager_(AudioManager::CreateForTesting()) {}
+  ~WinAudioInputTest() override {}
+
+ protected:
+  ScopedCOMInitializer com_init_;
+  scoped_ptr<AudioManager> audio_manager_;
+};
+
 // Verify that we can retrieve the current hardware/mixing sample rate
 // for all available input devices.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
-
-  ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA);
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
 
   // Retrieve a list of all available input devices.
   media::AudioDeviceNames device_names;
-  audio_manager->GetAudioInputDeviceNames(&device_names);
+  audio_manager_->GetAudioInputDeviceNames(&device_names);
 
   // Scan all available input devices and repeat the same test for all of them.
   for (media::AudioDeviceNames::const_iterator it = device_names.begin();
@@ -277,30 +281,27 @@
 }
 
 // Test Create(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   ais.Close();
 }
 
 // Test Open(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   EXPECT_TRUE(ais->Open());
   ais.Close();
 }
 
 // Test Open(), Start(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   EXPECT_TRUE(ais->Open());
   MockAudioInputCallback sink;
   ais->Start(&sink);
@@ -308,11 +309,10 @@
 }
 
 // Test Open(), Start(), Stop(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   EXPECT_TRUE(ais->Open());
   MockAudioInputCallback sink;
   ais->Start(&sink);
@@ -321,11 +321,10 @@
 }
 
 // Test some additional calling sequences.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   WASAPIAudioInputStream* wais =
       static_cast<WASAPIAudioInputStream*>(ais.get());
 
@@ -349,9 +348,8 @@
   ais.Close();
 }
 
-TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
 
   int count = 0;
   base::MessageLoopForUI loop;
@@ -360,7 +358,7 @@
 
   // Create default WASAPI input stream which records in stereo using
   // the shared mixing rate. The default buffer size is 10ms.
-  AudioInputStreamWrapper aisw(audio_manager.get());
+  AudioInputStreamWrapper aisw(audio_manager_.get());
   ScopedAudioInputStream ais(aisw.Create());
   EXPECT_TRUE(ais->Open());
 
@@ -419,21 +417,20 @@
 }
 
 // Test that we can capture a stream in loopback.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_manager->HasAudioOutputDevices() &&
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices() &&
                           CoreAudioUtil::IsSupported());
 
-  AudioParameters params = audio_manager->GetInputStreamParameters(
+  AudioParameters params = audio_manager_->GetInputStreamParameters(
       AudioManagerBase::kLoopbackInputDeviceId);
   EXPECT_EQ(params.effects(), 0);
 
   AudioParameters output_params =
-      audio_manager->GetOutputStreamParameters(std::string());
+      audio_manager_->GetOutputStreamParameters(std::string());
   EXPECT_EQ(params.sample_rate(), output_params.sample_rate());
   EXPECT_EQ(params.channel_layout(), output_params.channel_layout());
 
-  ScopedAudioInputStream stream(audio_manager->MakeAudioInputStream(
+  ScopedAudioInputStream stream(audio_manager_->MakeAudioInputStream(
       params, AudioManagerBase::kLoopbackInputDeviceId));
   ASSERT_TRUE(stream->Open());
   FakeAudioInputCallback sink;
@@ -453,16 +450,15 @@
 // To include disabled tests in test execution, just invoke the test program
 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
 // environment variable to a value greater than 0.
-TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
 
   // Name of the output PCM file containing captured data. The output file
   // will be stored in the directory containing 'media_unittests.exe'.
   // Example of full name: \src\build\Debug\out_stereo_10sec.pcm.
   const char* file_name = "out_stereo_10sec.pcm";
 
-  AudioInputStreamWrapper aisw(audio_manager.get());
+  AudioInputStreamWrapper aisw(audio_manager_.get());
   ScopedAudioInputStream ais(aisw.Create());
   EXPECT_TRUE(ais->Open());
 
diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc
index f7b31a3..a9d637c 100644
--- a/media/audio/win/audio_low_latency_output_win.cc
+++ b/media/audio/win/audio_low_latency_output_win.cc
@@ -249,6 +249,11 @@
   }
   num_written_frames_ = endpoint_buffer_size_frames_;
 
+  if (!MarshalComPointers()) {
+    callback->OnError(this);
+    return;
+  }
+
   // Create and start the thread that will drive the rendering by waiting for
   // render events.
   render_thread_.reset(
@@ -333,7 +338,7 @@
 }
 
 void WASAPIAudioOutputStream::Run() {
-  ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA);
+  ScopedCOMInitializer com_init;
 
   // Increase the thread priority.
   render_thread_->SetThreadPriority(base::ThreadPriority::REALTIME_AUDIO);
@@ -352,6 +357,12 @@
     LOG(WARNING) << "Failed to enable MMCSS (error code=" << err << ").";
   }
 
+  // Retrieve COM pointers from the main thread.
+  ScopedComPtr<IAudioClient> audio_client;
+  ScopedComPtr<IAudioRenderClient> audio_render_client;
+  ScopedComPtr<IAudioClock> audio_clock;
+  UnmarshalComPointers(&audio_client, &audio_render_client, &audio_clock);
+
   HRESULT hr = S_FALSE;
 
   bool playing = true;
@@ -362,7 +373,7 @@
 
   // The device frequency is the frequency generated by the hardware clock in
   // the audio device. The GetFrequency() method reports a constant frequency.
-  hr = audio_clock_->GetFrequency(&device_frequency);
+  hr = audio_clock->GetFrequency(&device_frequency);
   error = FAILED(hr);
   PLOG_IF(ERROR, error) << "Failed to acquire IAudioClock interface: "
                         << std::hex << hr;
@@ -383,7 +394,9 @@
         break;
       case WAIT_OBJECT_0 + 1:
         // |audio_samples_render_event_| has been set.
-        error = !RenderAudioFromSource(device_frequency);
+        error = !RenderAudioFromSource(device_frequency, audio_client.get(),
+                                       audio_render_client.get(),
+                                       audio_clock.get());
         break;
       default:
         error = true;
@@ -391,11 +404,11 @@
     }
   }
 
-  if (playing && error) {
+  if (playing && error && audio_client) {
     // Stop audio rendering since something has gone wrong in our main thread
     // loop. Note that, we are still in a "started" state, hence a Stop() call
     // is required to join the thread properly.
-    audio_client_->Stop();
+    audio_client->Stop();
     PLOG(ERROR) << "WASAPI rendering failed.";
   }
 
@@ -405,7 +418,11 @@
   }
 }
 
-bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
+bool WASAPIAudioOutputStream::RenderAudioFromSource(
+    UINT64 device_frequency,
+    IAudioClient* audio_client,
+    IAudioRenderClient* audio_render_client,
+    IAudioClock* audio_clock) {
   TRACE_EVENT0("audio", "RenderAudioFromSource");
 
   HRESULT hr = S_FALSE;
@@ -420,7 +437,7 @@
   if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) {
     // Get the padding value which represents the amount of rendering
     // data that is queued up to play in the endpoint buffer.
-    hr = audio_client_->GetCurrentPadding(&num_queued_frames);
+    hr = audio_client->GetCurrentPadding(&num_queued_frames);
     num_available_frames =
         endpoint_buffer_size_frames_ - num_queued_frames;
     if (FAILED(hr)) {
@@ -462,8 +479,7 @@
   for (size_t n = 0; n < num_packets; ++n) {
     // Grab all available space in the rendering endpoint buffer
     // into which the client can write a data packet.
-    hr = audio_render_client_->GetBuffer(packet_size_frames_,
-                                         &audio_data);
+    hr = audio_render_client->GetBuffer(packet_size_frames_, &audio_data);
     if (FAILED(hr)) {
       DLOG(ERROR) << "Failed to use rendering audio buffer: "
                  << std::hex << hr;
@@ -477,7 +493,7 @@
     // unit at the render side.
     UINT64 position = 0;
     uint32 audio_delay_bytes = 0;
-    hr = audio_clock_->GetPosition(&position, NULL);
+    hr = audio_clock->GetPosition(&position, NULL);
     if (SUCCEEDED(hr)) {
       // Stream position of the sample that is currently playing
       // through the speaker.
@@ -517,7 +533,7 @@
     // Render silence if we were not able to fill up the buffer totally.
     DWORD flags = (num_filled_bytes < packet_size_bytes_) ?
         AUDCLNT_BUFFERFLAGS_SILENT : 0;
-    audio_render_client_->ReleaseBuffer(packet_size_frames_, flags);
+    audio_render_client->ReleaseBuffer(packet_size_frames_, flags);
 
     num_written_frames_ += packet_size_frames_;
   }
@@ -622,4 +638,73 @@
   source_ = NULL;
 }
 
+bool WASAPIAudioOutputStream::MarshalComPointers() {
+  DCHECK_EQ(creating_thread_id_, base::PlatformThread::CurrentId());
+  DCHECK(!com_stream_);
+
+  ScopedComPtr<IStream> com_stream;
+  HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, com_stream.Receive());
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Failed to create stream for marshaling COM pointers.";
+    return false;
+  }
+
+  hr = CoMarshalInterface(com_stream.get(), __uuidof(IAudioClient),
+                          audio_client_.get(), MSHCTX_INPROC, NULL,
+                          MSHLFLAGS_NORMAL);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Marshal failed for IAudioClient: " << std::hex << hr;
+    return false;
+  }
+
+  hr = CoMarshalInterface(com_stream.get(), __uuidof(IAudioRenderClient),
+                          audio_render_client_.get(), MSHCTX_INPROC, NULL,
+                          MSHLFLAGS_NORMAL);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Marshal failed for IAudioRenderClient: " << std::hex << hr;
+    return false;
+  }
+
+  hr = CoMarshalInterface(com_stream.get(), __uuidof(IAudioClock),
+                          audio_clock_.get(), MSHCTX_INPROC, NULL,
+                          MSHLFLAGS_NORMAL);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Marshal failed for IAudioClock: " << std::hex << hr;
+    return false;
+  }
+
+  LARGE_INTEGER pos = {0};
+  hr = com_stream->Seek(pos, STREAM_SEEK_SET, NULL);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Failed to seek IStream for marshaling: " << std::hex << hr;
+    return false;
+  }
+
+  com_stream_ = com_stream.Pass();
+  return true;
+}
+
+void WASAPIAudioOutputStream::UnmarshalComPointers(
+    ScopedComPtr<IAudioClient>* audio_client,
+    ScopedComPtr<IAudioRenderClient>* audio_render_client,
+    ScopedComPtr<IAudioClock>* audio_clock) {
+  DCHECK_EQ(render_thread_->tid(), base::PlatformThread::CurrentId());
+
+  DCHECK(com_stream_);
+  ScopedComPtr<IStream> com_stream;
+  com_stream = com_stream_.Pass();
+
+  HRESULT hr = CoUnmarshalInterface(com_stream.get(), __uuidof(IAudioClient),
+                                    audio_client->ReceiveVoid());
+  CHECK(SUCCEEDED(hr));
+
+  hr = CoUnmarshalInterface(com_stream.get(), __uuidof(IAudioRenderClient),
+                            audio_render_client->ReceiveVoid());
+  CHECK(SUCCEEDED(hr));
+
+  hr = CoUnmarshalInterface(com_stream.get(), __uuidof(IAudioClock),
+                            audio_clock->ReceiveVoid());
+  CHECK(SUCCEEDED(hr));
+}
+
 }  // namespace media
diff --git a/media/audio/win/audio_low_latency_output_win.h b/media/audio/win/audio_low_latency_output_win.h
index 1584a46..30e791b 100644
--- a/media/audio/win/audio_low_latency_output_win.h
+++ b/media/audio/win/audio_low_latency_output_win.h
@@ -128,15 +128,15 @@
 
   // The dtor is typically called by the AudioManager only and it is usually
   // triggered by calling AudioOutputStream::Close().
-  virtual ~WASAPIAudioOutputStream();
+  ~WASAPIAudioOutputStream() override;
 
   // Implementation of AudioOutputStream.
-  virtual bool Open() override;
-  virtual void Start(AudioSourceCallback* callback) override;
-  virtual void Stop() override;
-  virtual void Close() override;
-  virtual void SetVolume(double volume) override;
-  virtual void GetVolume(double* volume) override;
+  bool Open() override;
+  void Start(AudioSourceCallback* callback) override;
+  void Stop() override;
+  void Close() override;
+  void SetVolume(double volume) override;
+  void GetVolume(double* volume) override;
 
   // Retrieves the sample rate the audio engine uses for its internal
   // processing/mixing of shared-mode streams.  To fetch the settings for the
@@ -151,13 +151,16 @@
 
  private:
   // DelegateSimpleThread::Delegate implementation.
-  virtual void Run() override;
+  void Run() override;
 
   // Core part of the thread loop which controls the actual rendering.
   // Checks available amount of space in the endpoint buffer and reads
   // data from the client to fill up the buffer without causing audio
   // glitches.
-  bool RenderAudioFromSource(UINT64 device_frequency);
+  bool RenderAudioFromSource(UINT64 device_frequency,
+                             IAudioClient* thread_audio_client,
+                             IAudioRenderClient* thread_audio_render_client,
+                             IAudioClock* thread_audio_clock);
 
   // Called when the device will be opened in exclusive mode and use the
   // application specified format.
@@ -172,6 +175,15 @@
   // |source_| is set to NULL.
   void StopThread();
 
+  // Handles sharing of COM pointers between the audio and render threads.  The
+  // marshal method must be called on the audio manager thread, while unmarshal
+  // must be called on |render_thread_|.
+  bool MarshalComPointers();
+  void UnmarshalComPointers(
+      base::win::ScopedComPtr<IAudioClient>* audio_client,
+      base::win::ScopedComPtr<IAudioRenderClient>* audio_render_client,
+      base::win::ScopedComPtr<IAudioClock>* audio_clock);
+
   // Contains the thread ID of the creating thread.
   base::PlatformThreadId creating_thread_id_;
 
@@ -221,6 +233,18 @@
   // Pointer to the client that will deliver audio samples to be played out.
   AudioSourceCallback* source_;
 
+  // ------------------------------------------------------
+  // Warning: COM pointers must be marshaled from the audio thread to be used
+  // on any other thread. Do not use any of these interfaces on a thread other
+  // than the audio thread.  See MarshalComPointers() and UnmarshalComPointers()
+  // for marshaling pointers to the render thread.
+
+  // Stream into which the COM pointers below are marshaled so that they can
+  // be used on another thread.
+  base::win::ScopedComPtr<IStream> com_stream_;
+
+  // Windows Audio Session API (WASAPI) interfaces.
+
   // An IAudioClient interface which enables a client to create and initialize
   // an audio stream between an audio application and the audio engine.
   base::win::ScopedComPtr<IAudioClient> audio_client_;
@@ -229,6 +253,9 @@
   // data to a rendering endpoint buffer.
   base::win::ScopedComPtr<IAudioRenderClient> audio_render_client_;
 
+  base::win::ScopedComPtr<IAudioClock> audio_clock_;
+  // ------------------------------------------------------
+
   // The audio engine will signal this event each time a buffer becomes
   // ready to be filled by the client.
   base::win::ScopedHandle audio_samples_render_event_;
@@ -239,8 +266,6 @@
   // Container for retrieving data from AudioSourceCallback::OnMoreData().
   scoped_ptr<AudioBus> audio_bus_;
 
-  base::win::ScopedComPtr<IAudioClock> audio_clock_;
-
   DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream);
 };
 
diff --git a/media/audio/win/audio_low_latency_output_win_unittest.cc b/media/audio/win/audio_low_latency_output_win_unittest.cc
index afd565a9..193c0821 100644
--- a/media/audio/win/audio_low_latency_output_win_unittest.cc
+++ b/media/audio/win/audio_low_latency_output_win_unittest.cc
@@ -6,6 +6,7 @@
 #include <mmsystem.h>
 
 #include "base/basictypes.h"
+#include "base/bind.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
 #include "base/memory/scoped_ptr.h"
@@ -226,14 +227,24 @@
   return aos;
 }
 
+class WASAPIAudioOutputStreamTest : public testing::Test {
+ public:
+  WASAPIAudioOutputStreamTest()
+      : audio_manager_(AudioManager::CreateForTesting()) {}
+  ~WASAPIAudioOutputStreamTest() override {}
+
+ protected:
+  ScopedCOMInitializer com_init_;
+  scoped_ptr<AudioManager> audio_manager_;
+};
+
 // Verify that we can retrieve the current hardware/mixing sample rate
 // for the default audio device.
 // TODO(henrika): modify this test when we support full device enumeration.
-TEST(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
+TEST_F(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
   // Skip this test in exclusive mode since the resulting rate is only utilized
   // for shared mode streams.
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
   // Default device intended for games, system notification sounds,
@@ -244,27 +255,24 @@
 }
 
 // Test Create(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, CreateAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, CreateAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   aos->Close();
 }
 
 // Test Open(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, OpenAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, OpenAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   EXPECT_TRUE(aos->Open());
   aos->Close();
 }
 
 // Test Open(), Start(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   EXPECT_TRUE(aos->Open());
   MockAudioSourceCallback source;
   EXPECT_CALL(source, OnError(aos))
@@ -274,10 +282,9 @@
 }
 
 // Test Open(), Start(), Stop(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   EXPECT_TRUE(aos->Open());
   MockAudioSourceCallback source;
   EXPECT_CALL(source, OnError(aos))
@@ -288,10 +295,9 @@
 }
 
 // Test SetVolume(), GetVolume()
-TEST(WASAPIAudioOutputStreamTest, Volume) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, Volume) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
 
   // Initial volume should be full volume (1.0).
   double volume = 0.0;
@@ -324,11 +330,10 @@
 }
 
 // Test some additional calling sequences.
-TEST(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+TEST_F(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   WASAPIAudioOutputStream* waos = static_cast<WASAPIAudioOutputStream*>(aos);
 
   // Open(), Open() is a valid calling sequence (second call does nothing).
@@ -363,16 +368,15 @@
 }
 
 // Use preferred packet size and verify that rendering starts.
-TEST(WASAPIAudioOutputStreamTest, ValidPacketSize) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+TEST_F(WASAPIAudioOutputStreamTest, ValidPacketSize) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
   base::MessageLoopForUI loop;
   MockAudioSourceCallback source;
 
   // Create default WASAPI output stream which plays out in stereo using
   // the shared mixing rate. The default buffer size is 10ms.
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create();
   EXPECT_TRUE(aos->Open());
 
@@ -401,11 +405,10 @@
 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
 // environment variable to a value greater than 0.
 // The test files are approximately 20 seconds long.
-TEST(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+TEST_F(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create();
   EXPECT_TRUE(aos->Open());
 
@@ -450,12 +453,11 @@
 // certain set of audio parameters and a sample rate of 48kHz.
 // The expected outcomes of each setting in this test has been derived
 // manually using log outputs (--v=1).
-TEST(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt48kHz) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+TEST_F(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt48kHz) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
 
   // 10ms @ 48kHz shall work.
   // Note that, this is the same size as we can use for shared-mode streaming
@@ -498,12 +500,11 @@
 // certain set of audio parameters and a sample rate of 44.1kHz.
 // The expected outcomes of each setting in this test has been derived
 // manually using log outputs (--v=1).
-TEST(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt44kHz) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+TEST_F(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt44kHz) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
 
   // 10ms @ 44.1kHz does not work due to misalignment.
   // This test will propose an aligned buffer size of 10.1587ms.
@@ -553,9 +554,8 @@
 
 // Verify that we can open and start the output stream in exclusive mode at
 // the lowest possible delay at 48kHz.
-TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt48kHz) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+TEST_F(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt48kHz) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
   base::MessageLoopForUI loop;
@@ -563,7 +563,7 @@
 
   // Create exclusive-mode WASAPI output stream which plays out in stereo
   // using the minimum buffer size at 48kHz sample rate.
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create(48000, 160);
   EXPECT_TRUE(aos->Open());
 
@@ -588,16 +588,15 @@
 
 // Verify that we can open and start the output stream in exclusive mode at
 // the lowest possible delay at 44.1kHz.
-TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt44kHz) {
+TEST_F(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt44kHz) {
   ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled());
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
 
   base::MessageLoopForUI loop;
   MockAudioSourceCallback source;
 
   // Create exclusive-mode WASAPI output stream which plays out in stereo
   // using the minimum buffer size at 44.1kHz sample rate.
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create(44100, 160);
   EXPECT_TRUE(aos->Open());
 
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index ce61eb6..afd1ef9b 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -21,35 +21,35 @@
   AudioManagerWin(AudioLogFactory* audio_log_factory);
 
   // Implementation of AudioManager.
-  virtual bool HasAudioOutputDevices() override;
-  virtual bool HasAudioInputDevices() override;
-  virtual base::string16 GetAudioInputDeviceModel() override;
-  virtual void ShowAudioInputSettings() override;
-  virtual void GetAudioInputDeviceNames(
-      AudioDeviceNames* device_names) override;
-  virtual void GetAudioOutputDeviceNames(
-      AudioDeviceNames* device_names) override;
-  virtual AudioParameters GetInputStreamParameters(
+  bool HasAudioOutputDevices() override;
+  bool HasAudioInputDevices() override;
+  base::string16 GetAudioInputDeviceModel() override;
+  void ShowAudioInputSettings() override;
+  void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override;
+  void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override;
+  AudioParameters GetInputStreamParameters(
       const std::string& device_id) override;
-  virtual std::string GetAssociatedOutputDeviceID(
+  std::string GetAssociatedOutputDeviceID(
       const std::string& input_device_id) override;
 
   // Implementation of AudioManagerBase.
-  virtual AudioOutputStream* MakeLinearOutputStream(
+  AudioOutputStream* MakeLinearOutputStream(
       const AudioParameters& params) override;
-  virtual AudioOutputStream* MakeLowLatencyOutputStream(
+  AudioOutputStream* MakeLowLatencyOutputStream(
       const AudioParameters& params,
       const std::string& device_id) override;
-  virtual AudioInputStream* MakeLinearInputStream(
-      const AudioParameters& params, const std::string& device_id) override;
-  virtual AudioInputStream* MakeLowLatencyInputStream(
-      const AudioParameters& params, const std::string& device_id) override;
-  virtual std::string GetDefaultOutputDeviceID() override;
+  AudioInputStream* MakeLinearInputStream(
+      const AudioParameters& params,
+      const std::string& device_id) override;
+  AudioInputStream* MakeLowLatencyInputStream(
+      const AudioParameters& params,
+      const std::string& device_id) override;
+  std::string GetDefaultOutputDeviceID() override;
 
  protected:
-  virtual ~AudioManagerWin();
+  ~AudioManagerWin() override;
 
-  virtual AudioParameters GetPreferredOutputStreamParameters(
+  AudioParameters GetPreferredOutputStreamParameters(
       const std::string& output_device_id,
       const AudioParameters& input_params) override;
 
@@ -64,9 +64,7 @@
 
   EnumerationType enumeration_type_;
   EnumerationType enumeration_type() { return enumeration_type_; }
-  void SetEnumerationType(EnumerationType type) {
-    enumeration_type_ = type;
-  }
+  void set_enumeration_type(EnumerationType type) { enumeration_type_ = type; }
 
   inline bool core_audio_supported() const {
     return enumeration_type_ == kMMDeviceEnumeration;
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index 93454fc9..c1dc5b4 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -427,7 +427,7 @@
   ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
 
   // The WASAPI API requires a correct COM environment.
-  ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA);
+  ScopedCOMInitializer com_init;
 
   // Use 10 ms buffer size for WASAPI and 50 ms buffer size for Wave.
   // Take the existing native sample rate into account.
diff --git a/media/audio/win/core_audio_util_win.cc b/media/audio/win/core_audio_util_win.cc
index 53530dfc..4f72564 100644
--- a/media/audio/win/core_audio_util_win.cc
+++ b/media/audio/win/core_audio_util_win.cc
@@ -178,10 +178,12 @@
     // fail with CO_E_NOTINITIALIZED in combination with certain 3rd party
     // modules. Calling CoInitializeEx is an attempt to resolve the reported
     // issues. See http://crbug.com/378465 for details.
-    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
     if (SUCCEEDED(hr)) {
-      hr = device_enumerator.CreateInstance(__uuidof(MMDeviceEnumerator),
-                                            NULL, CLSCTX_INPROC_SERVER);
+      hr = device_enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), NULL,
+                                            CLSCTX_INPROC_SERVER);
+    } else {
+      LOG(ERROR) << "CoCreateInstance still failed! " << std::hex << hr;
     }
   }
   return device_enumerator;
diff --git a/media/audio/win/core_audio_util_win_unittest.cc b/media/audio/win/core_audio_util_win_unittest.cc
index 31f91e9..1a24e5d2 100644
--- a/media/audio/win/core_audio_util_win_unittest.cc
+++ b/media/audio/win/core_audio_util_win_unittest.cc
@@ -19,13 +19,10 @@
 
 class CoreAudioUtilWinTest : public ::testing::Test {
  protected:
-  // The test runs on a COM thread in the multithreaded apartment (MTA).
+  // The test runs on a COM thread in the singlethreaded apartment (STA).
   // If we don't initialize the COM library on a thread before using COM,
   // all function calls will return CO_E_NOTINITIALIZED.
-  CoreAudioUtilWinTest()
-      : com_init_(ScopedCOMInitializer::kMTA) {
-    DCHECK(com_init_.succeeded());
-  }
+  CoreAudioUtilWinTest() { DCHECK(com_init_.succeeded()); }
   virtual ~CoreAudioUtilWinTest() {}
 
   bool DevicesAvailable() {
diff --git a/media/audio/win/device_enumeration_win.h b/media/audio/win/device_enumeration_win.h
index e61a3318..e6485db0 100644
--- a/media/audio/win/device_enumeration_win.h
+++ b/media/audio/win/device_enumeration_win.h
@@ -17,7 +17,7 @@
 // Example record in the output list:
 // - device_name: "Microphone (Realtek High Definition Audio)".
 // - unique_id: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}"
-// This method must be called from a COM thread using MTA.
+// This method must be called from a COM thread using STA.
 bool GetInputDeviceNamesWin(media::AudioDeviceNames* device_names);
 bool GetOutputDeviceNamesWin(media::AudioDeviceNames* device_names);
 
diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h
index 6b98d0d..a2c77c34 100644
--- a/media/audio/win/wavein_input_win.h
+++ b/media/audio/win/wavein_input_win.h
@@ -32,20 +32,20 @@
                             const AudioParameters& params,
                             int num_buffers,
                             const std::string& device_id);
-  virtual ~PCMWaveInAudioInputStream();
+  ~PCMWaveInAudioInputStream() override;
 
   // Implementation of AudioInputStream.
-  virtual bool Open() override;
-  virtual void Start(AudioInputCallback* callback) override;
-  virtual void Stop() override;
-  virtual void Close() override;
+  bool Open() override;
+  void Start(AudioInputCallback* callback) override;
+  void Stop() override;
+  void Close() override;
   // TODO(henrika): Add volume support using the Audio Mixer API.
-  virtual double GetMaxVolume() override;
-  virtual void SetVolume(double volume) override;
-  virtual double GetVolume() override;
-  virtual bool SetAutomaticGainControl(bool enabled) override;
-  virtual bool GetAutomaticGainControl() override;
-  virtual bool IsMuted() override;
+  double GetMaxVolume() override;
+  void SetVolume(double volume) override;
+  double GetVolume() override;
+  bool SetAutomaticGainControl(bool enabled) override;
+  bool GetAutomaticGainControl() override;
+  bool IsMuted() override;
 
  private:
   enum State {
diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h
index 5c7009d..bd9da5e 100644
--- a/media/audio/win/waveout_output_win.h
+++ b/media/audio/win/waveout_output_win.h
@@ -38,15 +38,15 @@
                               const AudioParameters& params,
                               int num_buffers,
                               UINT device_id);
-  virtual ~PCMWaveOutAudioOutputStream();
+  ~PCMWaveOutAudioOutputStream() override;
 
   // Implementation of AudioOutputStream.
-  virtual bool Open();
-  virtual void Close();
-  virtual void Start(AudioSourceCallback* callback);
-  virtual void Stop();
-  virtual void SetVolume(double volume);
-  virtual void GetVolume(double* volume);
+  bool Open() override;
+  void Close() override;
+  void Start(AudioSourceCallback* callback) override;
+  void Stop() override;
+  void SetVolume(double volume) override;
+  void GetVolume(double* volume) override;
 
   // Sends a buffer to the audio driver for playback.
   void QueueNextPacket(WAVEHDR* buffer);
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index 861fb678..1f05d4467 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/android/config.gni")
 import("//build/config/arm.gni")
+import("//build/config/features.gni")
 import("//build/config/ui.gni")
 import("//build/config/linux/pkg_config.gni")
 import("//media/media_options.gni")
@@ -241,9 +242,7 @@
     sources += [ "user_input_monitor_mac.cc" ]
 
     # Required by video_frame.cc.
-    libs = [
-      "CoreVideo.framework"
-    ]
+    libs = [ "CoreVideo.framework" ]
   } else if (is_win) {
     sources += [ "user_input_monitor_win.cc" ]
   } else {
diff --git a/media/base/eme_constants.h b/media/base/eme_constants.h
index 8bb3883..0b246709 100644
--- a/media/base/eme_constants.h
+++ b/media/base/eme_constants.h
@@ -58,37 +58,30 @@
 
 typedef uint32_t SupportedCodecs;
 
-enum EmeSessionTypeSupport {
+enum class EmeSessionTypeSupport {
   // Invalid default value.
-  EME_SESSION_TYPE_INVALID,
+  INVALID,
   // The session type is not supported.
-  EME_SESSION_TYPE_NOT_SUPPORTED,
+  NOT_SUPPORTED,
   // The session type is supported if a distinctive identifier is available.
-  EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER,
+  SUPPORTED_WITH_IDENTIFIER,
   // The session type is always supported.
-  EME_SESSION_TYPE_SUPPORTED,
+  SUPPORTED,
 };
 
 // Used to declare support for distinctive identifier and persistent state.
 // These are purposefully limited to not allow one to require the other, so that
 // transitive requirements are not possible. Non-trivial refactoring would be
 // required to support transitive requirements.
-enum EmeFeatureSupport {
+enum class EmeFeatureSupport {
   // Invalid default value.
-  EME_FEATURE_INVALID,
+  INVALID,
   // Access to the feature is not supported at all.
-  EME_FEATURE_NOT_SUPPORTED,
+  NOT_SUPPORTED,
   // Access to the feature may be requested.
-  EME_FEATURE_REQUESTABLE,
+  REQUESTABLE,
   // Access to the feature cannot be blocked.
-  EME_FEATURE_ALWAYS_ENABLED,
-};
-
-// Used to query support for distinctive identifier and persistent state.
-enum EmeFeatureRequirement {
-  EME_FEATURE_NOT_ALLOWED,
-  EME_FEATURE_OPTIONAL,
-  EME_FEATURE_REQUIRED,
+  ALWAYS_ENABLED,
 };
 
 enum class EmeMediaType {
diff --git a/media/base/key_system_info.cc b/media/base/key_system_info.cc
index f5ca112..8eec5b1c 100644
--- a/media/base/key_system_info.cc
+++ b/media/base/key_system_info.cc
@@ -11,10 +11,10 @@
       supported_codecs(EME_CODEC_NONE),
       max_audio_robustness(EmeRobustness::INVALID),
       max_video_robustness(EmeRobustness::INVALID),
-      persistent_license_support(EME_SESSION_TYPE_INVALID),
-      persistent_release_message_support(EME_SESSION_TYPE_INVALID),
-      persistent_state_support(EME_FEATURE_INVALID),
-      distinctive_identifier_support(EME_FEATURE_INVALID),
+      persistent_license_support(EmeSessionTypeSupport::INVALID),
+      persistent_release_message_support(EmeSessionTypeSupport::INVALID),
+      persistent_state_support(EmeFeatureSupport::INVALID),
+      distinctive_identifier_support(EmeFeatureSupport::INVALID),
       use_aes_decryptor(false) {
 }
 
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc
index 7bbbde7..f8999257 100644
--- a/media/base/key_systems.cc
+++ b/media/base/key_systems.cc
@@ -108,10 +108,11 @@
 
   info.max_audio_robustness = EmeRobustness::EMPTY;
   info.max_video_robustness = EmeRobustness::EMPTY;
-  info.persistent_license_support = EME_SESSION_TYPE_NOT_SUPPORTED;
-  info.persistent_release_message_support = EME_SESSION_TYPE_NOT_SUPPORTED;
-  info.persistent_state_support = EME_FEATURE_NOT_SUPPORTED;
-  info.distinctive_identifier_support = EME_FEATURE_NOT_SUPPORTED;
+  info.persistent_license_support = EmeSessionTypeSupport::NOT_SUPPORTED;
+  info.persistent_release_message_support =
+      EmeSessionTypeSupport::NOT_SUPPORTED;
+  info.persistent_state_support = EmeFeatureSupport::NOT_SUPPORTED;
+  info.distinctive_identifier_support = EmeFeatureSupport::NOT_SUPPORTED;
 
   info.use_aes_decryptor = true;
 
@@ -400,31 +401,34 @@
     DCHECK(!info.key_system.empty());
     DCHECK(info.max_audio_robustness != EmeRobustness::INVALID);
     DCHECK(info.max_video_robustness != EmeRobustness::INVALID);
-    DCHECK(info.persistent_license_support != EME_SESSION_TYPE_INVALID);
-    DCHECK(info.persistent_release_message_support != EME_SESSION_TYPE_INVALID);
-    DCHECK(info.persistent_state_support != EME_FEATURE_INVALID);
-    DCHECK(info.distinctive_identifier_support != EME_FEATURE_INVALID);
+    DCHECK(info.persistent_license_support != EmeSessionTypeSupport::INVALID);
+    DCHECK(info.persistent_release_message_support !=
+           EmeSessionTypeSupport::INVALID);
+    DCHECK(info.persistent_state_support != EmeFeatureSupport::INVALID);
+    DCHECK(info.distinctive_identifier_support != EmeFeatureSupport::INVALID);
 
     // Supporting persistent state is a prerequsite for supporting persistent
     // sessions.
-    if (info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED) {
-      DCHECK(info.persistent_license_support == EME_SESSION_TYPE_NOT_SUPPORTED);
+    if (info.persistent_state_support == EmeFeatureSupport::NOT_SUPPORTED) {
+      DCHECK(info.persistent_license_support ==
+             EmeSessionTypeSupport::NOT_SUPPORTED);
       DCHECK(info.persistent_release_message_support ==
-             EME_SESSION_TYPE_NOT_SUPPORTED);
+             EmeSessionTypeSupport::NOT_SUPPORTED);
     }
 
     // persistent-release-message sessions are not currently supported.
     // http://crbug.com/448888
     DCHECK(info.persistent_release_message_support ==
-           EME_SESSION_TYPE_NOT_SUPPORTED);
+           EmeSessionTypeSupport::NOT_SUPPORTED);
 
     // If distinctive identifiers are not supported, then no other features can
     // require them.
-    if (info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED) {
+    if (info.distinctive_identifier_support ==
+        EmeFeatureSupport::NOT_SUPPORTED) {
       DCHECK(info.persistent_license_support !=
-             EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER);
+             EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER);
       DCHECK(info.persistent_release_message_support !=
-             EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER);
+             EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER);
     }
 
     // Distinctive identifiers and persistent state can only be reliably blocked
@@ -438,8 +442,10 @@
       can_block = true;
 #endif
     if (!can_block) {
-      DCHECK(info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED);
-      DCHECK(info.persistent_state_support == EME_FEATURE_ALWAYS_ENABLED);
+      DCHECK(info.distinctive_identifier_support ==
+             EmeFeatureSupport::ALWAYS_ENABLED);
+      DCHECK(info.persistent_state_support ==
+             EmeFeatureSupport::ALWAYS_ENABLED);
     }
 
     DCHECK(!IsSupportedKeySystem(info.key_system))
@@ -776,7 +782,7 @@
       concrete_key_system_map_.find(key_system);
   if (key_system_iter == concrete_key_system_map_.end()) {
     NOTREACHED();
-    return EME_SESSION_TYPE_INVALID;
+    return EmeSessionTypeSupport::INVALID;
   }
   return key_system_iter->second.persistent_license_support;
 }
@@ -789,7 +795,7 @@
       concrete_key_system_map_.find(key_system);
   if (key_system_iter == concrete_key_system_map_.end()) {
     NOTREACHED();
-    return EME_SESSION_TYPE_INVALID;
+    return EmeSessionTypeSupport::INVALID;
   }
   return key_system_iter->second.persistent_release_message_support;
 }
@@ -802,7 +808,7 @@
       concrete_key_system_map_.find(key_system);
   if (key_system_iter == concrete_key_system_map_.end()) {
     NOTREACHED();
-    return EME_FEATURE_INVALID;
+    return EmeFeatureSupport::INVALID;
   }
   return key_system_iter->second.persistent_state_support;
 }
@@ -815,7 +821,7 @@
       concrete_key_system_map_.find(key_system);
   if (key_system_iter == concrete_key_system_map_.end()) {
     NOTREACHED();
-    return EME_FEATURE_INVALID;
+    return EmeFeatureSupport::INVALID;
   }
   return key_system_iter->second.distinctive_identifier_support;
 }
diff --git a/media/base/key_systems_unittest.cc b/media/base/key_systems_unittest.cc
index b80e6a1e..611c2b6 100644
--- a/media/base/key_systems_unittest.cc
+++ b/media/base/key_systems_unittest.cc
@@ -193,10 +193,11 @@
   system.supported_init_data_types = kInitDataTypeMaskWebM;
   system.max_audio_robustness = EmeRobustness::EMPTY;
   system.max_video_robustness = EmeRobustness::EMPTY;
-  system.persistent_license_support = EME_SESSION_TYPE_NOT_SUPPORTED;
-  system.persistent_release_message_support = EME_SESSION_TYPE_NOT_SUPPORTED;
-  system.persistent_state_support = EME_FEATURE_NOT_SUPPORTED;
-  system.distinctive_identifier_support = EME_FEATURE_NOT_SUPPORTED;
+  system.persistent_license_support = EmeSessionTypeSupport::NOT_SUPPORTED;
+  system.persistent_release_message_support =
+      EmeSessionTypeSupport::NOT_SUPPORTED;
+  system.persistent_state_support = EmeFeatureSupport::NOT_SUPPORTED;
+  system.distinctive_identifier_support = EmeFeatureSupport::NOT_SUPPORTED;
   system.use_aes_decryptor = true;
   key_systems->push_back(system);
 }
@@ -210,10 +211,10 @@
   ext.supported_init_data_types = kInitDataTypeMaskWebM;
   ext.max_audio_robustness = EmeRobustness::EMPTY;
   ext.max_video_robustness = EmeRobustness::EMPTY;
-  ext.persistent_license_support = EME_SESSION_TYPE_SUPPORTED;
-  ext.persistent_release_message_support = EME_SESSION_TYPE_NOT_SUPPORTED;
-  ext.persistent_state_support = EME_FEATURE_ALWAYS_ENABLED;
-  ext.distinctive_identifier_support = EME_FEATURE_ALWAYS_ENABLED;
+  ext.persistent_license_support = EmeSessionTypeSupport::SUPPORTED;
+  ext.persistent_release_message_support = EmeSessionTypeSupport::NOT_SUPPORTED;
+  ext.persistent_state_support = EmeFeatureSupport::ALWAYS_ENABLED;
+  ext.distinctive_identifier_support = EmeFeatureSupport::ALWAYS_ENABLED;
   ext.parent_key_system = kExternalParent;
 #if defined(ENABLE_PEPPER_CDMS)
   ext.pepper_type = "application/x-ppapi-external-cdm";
diff --git a/media/base/limits.h b/media/base/limits.h
index 69a5b63..c3cd677 100644
--- a/media/base/limits.h
+++ b/media/base/limits.h
@@ -52,6 +52,9 @@
   kMinKeyIdLength = 1,
   kMaxKeyIdLength = 512,
   kMaxKeyIds = 128,
+  kMaxInitDataLength = 64 * 1024,         // 64 KB
+  kMaxSessionResponseLength = 64 * 1024,  // 64 KB
+  kMaxKeySystemLength = 256,
 };
 
 }  // namespace limits
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 37940e676..26700f6 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -34,7 +34,7 @@
   // Demuxer implementation.
   MOCK_METHOD3(Initialize,
                void(DemuxerHost* host, const PipelineStatusCB& cb, bool));
-  MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
+  MOCK_METHOD1(SetPlaybackRate, void(double playback_rate));
   MOCK_METHOD2(Seek, void(base::TimeDelta time, const PipelineStatusCB& cb));
   MOCK_METHOD0(Stop, void());
   MOCK_METHOD0(OnAudioRendererDisabled, void());
@@ -179,7 +179,7 @@
                     const base::Closure& waiting_for_decryption_key_cb));
   MOCK_METHOD1(Flush, void(const base::Closure& flush_cb));
   MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta timestamp));
-  MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
+  MOCK_METHOD1(SetPlaybackRate, void(double playback_rate));
   MOCK_METHOD1(SetVolume, void(float volume));
   MOCK_METHOD0(GetMediaTime, base::TimeDelta());
   MOCK_METHOD0(HasAudio, bool());
@@ -200,7 +200,7 @@
   // TimeSource implementation.
   MOCK_METHOD0(StartTicking, void());
   MOCK_METHOD0(StopTicking, void());
-  MOCK_METHOD1(SetPlaybackRate, void(float));
+  MOCK_METHOD1(SetPlaybackRate, void(double));
   MOCK_METHOD1(SetMediaTime, void(base::TimeDelta));
   MOCK_METHOD0(CurrentMediaTime, base::TimeDelta());
   MOCK_METHOD1(GetWallClockTime, base::TimeTicks(base::TimeDelta));
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index c39ddcdf..4a39704 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -37,7 +37,7 @@
       running_(false),
       did_loading_progress_(false),
       volume_(1.0f),
-      playback_rate_(0.0f),
+      playback_rate_(0.0),
       status_(PIPELINE_OK),
       state_(kCreated),
       renderer_ended_(false),
@@ -121,13 +121,13 @@
   return running_;
 }
 
-float Pipeline::GetPlaybackRate() const {
+double Pipeline::GetPlaybackRate() const {
   base::AutoLock auto_lock(lock_);
   return playback_rate_;
 }
 
-void Pipeline::SetPlaybackRate(float playback_rate) {
-  if (playback_rate < 0.0f)
+void Pipeline::SetPlaybackRate(double playback_rate) {
+  if (playback_rate < 0.0)
     return;
 
   base::AutoLock auto_lock(lock_);
@@ -552,7 +552,7 @@
   DoStop(base::Bind(&Pipeline::OnStopCompleted, weak_factory_.GetWeakPtr()));
 }
 
-void Pipeline::PlaybackRateChangedTask(float playback_rate) {
+void Pipeline::PlaybackRateChangedTask(double playback_rate) {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   // Playback rate changes are only carried out while playing.
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index f10bc393..b63be00 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -141,17 +141,17 @@
   bool IsRunning() const;
 
   // Gets the current playback rate of the pipeline.  When the pipeline is
-  // started, the playback rate will be 0.0f.  A rate of 1.0f indicates
+  // started, the playback rate will be 0.0.  A rate of 1.0 indicates
   // that the pipeline is rendering the media at the standard rate.  Valid
-  // values for playback rate are >= 0.0f.
-  float GetPlaybackRate() const;
+  // values for playback rate are >= 0.0.
+  double GetPlaybackRate() const;
 
-  // Attempt to adjust the playback rate. Setting a playback rate of 0.0f pauses
-  // all rendering of the media.  A rate of 1.0f indicates a normal playback
-  // rate.  Values for the playback rate must be greater than or equal to 0.0f.
+  // Attempt to adjust the playback rate. Setting a playback rate of 0.0 pauses
+  // all rendering of the media.  A rate of 1.0 indicates a normal playback
+  // rate.  Values for the playback rate must be greater than or equal to 0.0.
   //
   // TODO(scherkus): What about maximum rate?  Does HTML5 specify a max?
-  void SetPlaybackRate(float playback_rate);
+  void SetPlaybackRate(double playback_rate);
 
   // Gets the current volume setting being used by the audio renderer.  When
   // the pipeline is started, this value will be 1.0f.  Valid values range
@@ -242,7 +242,7 @@
   void ErrorChangedTask(PipelineStatus error);
 
   // Carries out notifying filters that the playback rate has changed.
-  void PlaybackRateChangedTask(float playback_rate);
+  void PlaybackRateChangedTask(double playback_rate);
 
   // Carries out notifying filters that the volume has changed.
   void VolumeChangedTask(float volume);
@@ -319,10 +319,10 @@
   // filters.
   float volume_;
 
-  // Current playback rate (>= 0.0f).  This value is set immediately via
+  // Current playback rate (>= 0.0).  This value is set immediately via
   // SetPlaybackRate() and a task is dispatched on the task runner to notify
   // the filters.
-  float playback_rate_;
+  double playback_rate_;
 
   // Current duration as reported by |demuxer_|.
   base::TimeDelta duration_;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 09d9fdd..d4f9fa0 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -209,7 +209,7 @@
 
     if (start_status == PIPELINE_OK) {
       EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_));
-      EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f));
+      EXPECT_CALL(*renderer_, SetPlaybackRate(0.0));
       EXPECT_CALL(*renderer_, SetVolume(1.0f));
       EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_))
           .WillOnce(SetBufferingState(&buffering_state_cb_,
@@ -337,9 +337,9 @@
 
   // Setting should still work.
   EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
-  pipeline_->SetPlaybackRate(-1.0f);
+  pipeline_->SetPlaybackRate(-1.0);
   EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
-  pipeline_->SetPlaybackRate(1.0f);
+  pipeline_->SetPlaybackRate(1.0);
   EXPECT_EQ(1.0f, pipeline_->GetPlaybackRate());
 
   // Setting should still work.
@@ -640,7 +640,7 @@
   SetRendererExpectations();
   StartPipelineAndExpect(PIPELINE_OK);
 
-  float playback_rate = 1.0f;
+  double playback_rate = 1.0;
   EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate));
   pipeline_->SetPlaybackRate(playback_rate);
   message_loop_.RunUntilIdle();
@@ -675,7 +675,7 @@
   EXPECT_TRUE(message_loop->IsIdleForTesting());
 
   // Make calls on pipeline after error has occurred.
-  pipeline->SetPlaybackRate(0.5f);
+  pipeline->SetPlaybackRate(0.5);
   pipeline->SetVolume(0.5f);
 
   // No additional tasks should be queued as a result of these calls.
@@ -877,7 +877,7 @@
     EXPECT_CALL(callbacks_, OnMetadata(_));
 
     // If we get here it's a successful initialization.
-    EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f));
+    EXPECT_CALL(*renderer_, SetPlaybackRate(0.0));
     EXPECT_CALL(*renderer_, SetVolume(1.0f));
     EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta()))
         .WillOnce(SetBufferingState(&buffering_state_cb_,
diff --git a/media/base/renderer.h b/media/base/renderer.h
index 31661c4..75372fba 100644
--- a/media/base/renderer.h
+++ b/media/base/renderer.h
@@ -65,7 +65,7 @@
   virtual void StartPlayingFrom(base::TimeDelta time) = 0;
 
   // Updates the current playback rate. The default playback rate should be 1.
-  virtual void SetPlaybackRate(float playback_rate) = 0;
+  virtual void SetPlaybackRate(double playback_rate) = 0;
 
   // Sets the output volume. The default volume should be 1.
   virtual void SetVolume(float volume) = 0;
diff --git a/media/base/time_delta_interpolator.cc b/media/base/time_delta_interpolator.cc
index 11ba1cd..acff37e 100644
--- a/media/base/time_delta_interpolator.cc
+++ b/media/base/time_delta_interpolator.cc
@@ -16,7 +16,7 @@
     : tick_clock_(tick_clock),
       interpolating_(false),
       upper_bound_(kNoTimestamp()),
-      playback_rate_(1.0f) {
+      playback_rate_(1.0) {
   DCHECK(tick_clock_);
 }
 
@@ -37,7 +37,7 @@
   return lower_bound_;
 }
 
-void TimeDeltaInterpolator::SetPlaybackRate(float playback_rate) {
+void TimeDeltaInterpolator::SetPlaybackRate(double playback_rate) {
   lower_bound_ = GetInterpolatedTime();
   reference_ = tick_clock_->NowTicks();
   playback_rate_ = playback_rate;
diff --git a/media/base/time_delta_interpolator.h b/media/base/time_delta_interpolator.h
index af7535d..7dbda6938 100644
--- a/media/base/time_delta_interpolator.h
+++ b/media/base/time_delta_interpolator.h
@@ -42,7 +42,7 @@
   // Sets a new rate at which to interpolate.
   //
   // |tick_clock| will be queried for a new reference time value.
-  void SetPlaybackRate(float playback_rate);
+  void SetPlaybackRate(double playback_rate);
 
   // Sets the two timestamps to interpolate between at |playback_rate_|.
   // |upper_bound| must be greater or equal to |lower_bound|.
@@ -72,7 +72,7 @@
   // |lower_bound_| and |upper_bound_|.
   base::TimeTicks reference_;
 
-  float playback_rate_;
+  double playback_rate_;
 
   DISALLOW_COPY_AND_ASSIGN(TimeDeltaInterpolator);
 };
diff --git a/media/base/time_delta_interpolator_unittest.cc b/media/base/time_delta_interpolator_unittest.cc
index 04242f12..04ee8f7 100644
--- a/media/base/time_delta_interpolator_unittest.cc
+++ b/media/base/time_delta_interpolator_unittest.cc
@@ -40,7 +40,7 @@
   const base::TimeDelta kZero;
   const base::TimeDelta kTimeToAdvance = base::TimeDelta::FromSeconds(5);
 
-  interpolator_.SetPlaybackRate(2.0f);
+  interpolator_.SetPlaybackRate(2.0);
   EXPECT_EQ(kZero, interpolator_.StartInterpolating());
   AdvanceSystemTime(kTimeToAdvance);
   EXPECT_EQ(2 * kTimeToAdvance, interpolator_.GetInterpolatedTime());
@@ -50,7 +50,7 @@
   const base::TimeDelta kZero;
   const base::TimeDelta kTimeToAdvance = base::TimeDelta::FromSeconds(4);
 
-  interpolator_.SetPlaybackRate(0.5f);
+  interpolator_.SetPlaybackRate(0.5);
   EXPECT_EQ(kZero, interpolator_.StartInterpolating());
   AdvanceSystemTime(kTimeToAdvance);
   EXPECT_EQ(kTimeToAdvance / 2, interpolator_.GetInterpolatedTime());
@@ -68,9 +68,9 @@
   EXPECT_EQ(kZero, interpolator_.StartInterpolating());
 
   AdvanceSystemTime(kPlayDuration1);
-  interpolator_.SetPlaybackRate(0.0f);
+  interpolator_.SetPlaybackRate(0.0);
   AdvanceSystemTime(kPlayDuration2);
-  interpolator_.SetPlaybackRate(1.0f);
+  interpolator_.SetPlaybackRate(1.0);
   AdvanceSystemTime(kPlayDuration3);
 
   EXPECT_EQ(kExpected, interpolator_.GetInterpolatedTime());
@@ -86,14 +86,14 @@
   const base::TimeDelta kExpected =
       kPlayDuration1 / 2 + kPlayDuration2 + 2 * kPlayDuration3;
 
-  interpolator_.SetPlaybackRate(0.5f);
+  interpolator_.SetPlaybackRate(0.5);
   EXPECT_EQ(kZero, interpolator_.StartInterpolating());
   AdvanceSystemTime(kPlayDuration1);
 
-  interpolator_.SetPlaybackRate(1.0f);
+  interpolator_.SetPlaybackRate(1.0);
   AdvanceSystemTime(kPlayDuration2);
 
-  interpolator_.SetPlaybackRate(2.0f);
+  interpolator_.SetPlaybackRate(2.0);
   AdvanceSystemTime(kPlayDuration3);
   EXPECT_EQ(kExpected, interpolator_.GetInterpolatedTime());
 }
diff --git a/media/base/time_source.h b/media/base/time_source.h
index 71fe858..d025de2a 100644
--- a/media/base/time_source.h
+++ b/media/base/time_source.h
@@ -27,7 +27,7 @@
   // Updates the current playback rate. It is expected that values from
   // CurrentMediaTime() will eventually reflect the new playback rate (e.g., the
   // media time will advance at half speed if the rate was set to 0.5f).
-  virtual void SetPlaybackRate(float playback_rate) = 0;
+  virtual void SetPlaybackRate(double playback_rate) = 0;
 
   // Sets the media time to start ticking from. Only valid to call while the
   // time source is not ticking.
diff --git a/media/base/user_input_monitor_win.cc b/media/base/user_input_monitor_win.cc
index d06b82435a..6210236 100644
--- a/media/base/user_input_monitor_win.cc
+++ b/media/base/user_input_monitor_win.cc
@@ -39,10 +39,10 @@
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       const scoped_refptr<UserInputMonitor::MouseListenerList>&
           mouse_listeners);
-  ~UserInputMonitorWinCore();
+  ~UserInputMonitorWinCore() override;
 
   // DestructionObserver overrides.
-  virtual void WillDestroyCurrentMessageLoop() override;
+  void WillDestroyCurrentMessageLoop() override;
 
   size_t GetKeyPressCount() const;
   void StartMonitor(EventBitMask type);
@@ -75,17 +75,17 @@
  public:
   explicit UserInputMonitorWin(
       const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner);
-  virtual ~UserInputMonitorWin();
+  ~UserInputMonitorWin() override;
 
   // Public UserInputMonitor overrides.
-  virtual size_t GetKeyPressCount() const override;
+  size_t GetKeyPressCount() const override;
 
  private:
   // Private UserInputMonitor overrides.
-  virtual void StartKeyboardMonitoring() override;
-  virtual void StopKeyboardMonitoring() override;
-  virtual void StartMouseMonitoring() override;
-  virtual void StopMouseMonitoring() override;
+  void StartKeyboardMonitoring() override;
+  void StopKeyboardMonitoring() override;
+  void StartMouseMonitoring() override;
+  void StopMouseMonitoring() override;
 
   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
   UserInputMonitorWinCore* core_;
diff --git a/media/base/video_capture_types.cc b/media/base/video_capture_types.cc
index 152801745..cc5f840 100644
--- a/media/base/video_capture_types.cc
+++ b/media/base/video_capture_types.cc
@@ -49,6 +49,9 @@
       break;
     case PIXEL_FORMAT_RGB32:
     case PIXEL_FORMAT_ARGB:
+    // GpuMemoryBuffer is an endianness-agnostic 32bpp pixel format until
+    // http://crbug.com/439520 is closed.
+    case PIXEL_FORMAT_GPUMEMORYBUFFER:
       result_frame_size *= 4;
       break;
     case PIXEL_FORMAT_MJPEG:
@@ -95,6 +98,8 @@
     return "YV12";
   case PIXEL_FORMAT_TEXTURE:
     return "TEXTURE";
+  case PIXEL_FORMAT_GPUMEMORYBUFFER:
+    return "GPUMEMORYBUFFER";
   case PIXEL_FORMAT_MAX:
     break;
   }
diff --git a/media/base/video_capture_types.h b/media/base/video_capture_types.h
index 817e942..463873f 100644
--- a/media/base/video_capture_types.h
+++ b/media/base/video_capture_types.h
@@ -29,6 +29,7 @@
   PIXEL_FORMAT_ARGB,
   PIXEL_FORMAT_MJPEG,
   PIXEL_FORMAT_TEXTURE,  // Capture format as a GL texture.
+  PIXEL_FORMAT_GPUMEMORYBUFFER,
   PIXEL_FORMAT_UNKNOWN,  // Color format not set.
   PIXEL_FORMAT_MAX,
 };
diff --git a/media/base/wall_clock_time_source.cc b/media/base/wall_clock_time_source.cc
index e58162e..0369306 100644
--- a/media/base/wall_clock_time_source.cc
+++ b/media/base/wall_clock_time_source.cc
@@ -12,7 +12,7 @@
 WallClockTimeSource::WallClockTimeSource()
     : tick_clock_(new base::DefaultTickClock()),
       ticking_(false),
-      playback_rate_(1.0f) {
+      playback_rate_(1.0) {
 }
 
 WallClockTimeSource::~WallClockTimeSource() {
@@ -35,7 +35,7 @@
   reference_wall_ticks_ = tick_clock_->NowTicks();
 }
 
-void WallClockTimeSource::SetPlaybackRate(float playback_rate) {
+void WallClockTimeSource::SetPlaybackRate(double playback_rate) {
   DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
   base::AutoLock auto_lock(lock_);
   // Estimate current media time using old rate to use as a new base time for
diff --git a/media/base/wall_clock_time_source.h b/media/base/wall_clock_time_source.h
index d3d210ef2..1de6518 100644
--- a/media/base/wall_clock_time_source.h
+++ b/media/base/wall_clock_time_source.h
@@ -25,7 +25,7 @@
   // TimeSource implementation.
   void StartTicking() override;
   void StopTicking() override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
   void SetMediaTime(base::TimeDelta time) override;
   base::TimeDelta CurrentMediaTime() override;
   base::TimeTicks GetWallClockTime(base::TimeDelta time) override;
diff --git a/media/blink/buffered_data_source.cc b/media/blink/buffered_data_source.cc
index ed93848..d5f32b1 100644
--- a/media/blink/buffered_data_source.cc
+++ b/media/blink/buffered_data_source.cc
@@ -189,11 +189,11 @@
   frame_ = NULL;
 }
 
-void BufferedDataSource::MediaPlaybackRateChanged(float playback_rate) {
+void BufferedDataSource::MediaPlaybackRateChanged(double playback_rate) {
   DCHECK(render_task_runner_->BelongsToCurrentThread());
   DCHECK(loader_.get());
 
-  if (playback_rate < 0.0f)
+  if (playback_rate < 0.0)
     return;
 
   playback_rate_ = playback_rate;
diff --git a/media/blink/buffered_data_source.h b/media/blink/buffered_data_source.h
index e149bb06f..32f14816 100644
--- a/media/blink/buffered_data_source.h
+++ b/media/blink/buffered_data_source.h
@@ -100,7 +100,7 @@
 
   // Notifies changes in playback state for controlling media buffering
   // behavior.
-  void MediaPlaybackRateChanged(float playback_rate);
+  void MediaPlaybackRateChanged(double playback_rate);
   void MediaIsPlaying();
   void MediaIsPaused();
   bool media_has_played() const { return media_has_played_; }
@@ -229,7 +229,7 @@
   int bitrate_;
 
   // Current playback rate.
-  float playback_rate_;
+  double playback_rate_;
 
   scoped_refptr<MediaLog> media_log_;
 
diff --git a/media/blink/buffered_data_source_unittest.cc b/media/blink/buffered_data_source_unittest.cc
index eed8674..3776fd6 100644
--- a/media/blink/buffered_data_source_unittest.cc
+++ b/media/blink/buffered_data_source_unittest.cc
@@ -234,9 +234,9 @@
     return loader()->defer_strategy_;
   }
   int data_source_bitrate() { return data_source_->bitrate_; }
-  int data_source_playback_rate() { return data_source_->playback_rate_; }
+  double data_source_playback_rate() { return data_source_->playback_rate_; }
   int loader_bitrate() { return loader()->bitrate_; }
-  int loader_playback_rate() { return loader()->playback_rate_; }
+  double loader_playback_rate() { return loader()->playback_rate_; }
   bool is_local_source() { return data_source_->assume_fully_buffered(); }
   void set_might_be_reused_from_cache_in_future(bool value) {
     loader()->might_be_reused_from_cache_in_future_ = value;
@@ -560,9 +560,9 @@
   EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
 
   EXPECT_EQ(0, data_source_bitrate());
-  EXPECT_EQ(0.0f, data_source_playback_rate());
+  EXPECT_EQ(0.0, data_source_playback_rate());
   EXPECT_EQ(0, loader_bitrate());
-  EXPECT_EQ(0.0f, loader_playback_rate());
+  EXPECT_EQ(0.0, loader_playback_rate());
 
   EXPECT_TRUE(data_source_->loading());
   Stop();
@@ -594,10 +594,10 @@
 TEST_F(BufferedDataSourceTest, MediaPlaybackRateChanged) {
   InitializeWith206Response();
 
-  data_source_->MediaPlaybackRateChanged(2.0f);
+  data_source_->MediaPlaybackRateChanged(2.0);
   message_loop_.RunUntilIdle();
-  EXPECT_EQ(2.0f, data_source_playback_rate());
-  EXPECT_EQ(2.0f, loader_playback_rate());
+  EXPECT_EQ(2.0, data_source_playback_rate());
+  EXPECT_EQ(2.0, loader_playback_rate());
 
   // Read so far ahead to cause the loader to get recreated.
   BufferedResourceLoader* old_loader = loader();
diff --git a/media/blink/buffered_resource_loader.cc b/media/blink/buffered_resource_loader.cc
index b2598ea..51ec8fe 100644
--- a/media/blink/buffered_resource_loader.cc
+++ b/media/blink/buffered_resource_loader.cc
@@ -54,12 +54,12 @@
 // Computes the suggested backward and forward capacity for the buffer
 // if one wants to play at |playback_rate| * the natural playback speed.
 // Use a value of 0 for |bitrate| if it is unknown.
-static void ComputeTargetBufferWindow(float playback_rate, int bitrate,
+static void ComputeTargetBufferWindow(double playback_rate, int bitrate,
                                       int* out_backward_capacity,
                                       int* out_forward_capacity) {
   static const int kDefaultBitrate = 200 * 1024 * 8;  // 200 Kbps.
   static const int kMaxBitrate = 20 * kMegabyte * 8;  // 20 Mbps.
-  static const float kMaxPlaybackRate = 25.0;
+  static const double kMaxPlaybackRate = 25.0;
   static const int kTargetSecondsBufferedAhead = 10;
   static const int kTargetSecondsBufferedBehind = 2;
 
@@ -71,12 +71,12 @@
   // Only scale the buffer window for playback rates greater than 1.0 in
   // magnitude and clamp to prevent overflow.
   bool backward_playback = false;
-  if (playback_rate < 0.0f) {
+  if (playback_rate < 0.0) {
     backward_playback = true;
-    playback_rate *= -1.0f;
+    playback_rate *= -1.0;
   }
 
-  playback_rate = std::max(playback_rate, 1.0f);
+  playback_rate = std::max(playback_rate, 1.0);
   playback_rate = std::min(playback_rate, kMaxPlaybackRate);
 
   int bytes_per_second = (bitrate / 8.0) * playback_rate;
@@ -101,7 +101,7 @@
     int64 last_byte_position,
     DeferStrategy strategy,
     int bitrate,
-    float playback_rate,
+    double playback_rate,
     MediaLog* media_log)
     : buffer_(kMinBufferCapacity, kMinBufferCapacity),
       loader_failed_(false),
@@ -571,7 +571,7 @@
   UpdateDeferBehavior();
 }
 
-void BufferedResourceLoader::SetPlaybackRate(float playback_rate) {
+void BufferedResourceLoader::SetPlaybackRate(double playback_rate) {
   playback_rate_ = playback_rate;
 
   // This is a pause so don't bother updating the buffer window as we'll likely
diff --git a/media/blink/buffered_resource_loader.h b/media/blink/buffered_resource_loader.h
index 2b9cf579..cb02720 100644
--- a/media/blink/buffered_resource_loader.h
+++ b/media/blink/buffered_resource_loader.h
@@ -85,7 +85,7 @@
       int64 last_byte_position,
       DeferStrategy strategy,
       int bitrate,
-      float playback_rate,
+      double playback_rate,
       MediaLog* media_log);
   virtual ~BufferedResourceLoader();
 
@@ -179,7 +179,7 @@
 
   // Sets the playback rate to the given value and updates buffer window
   // accordingly.
-  void SetPlaybackRate(float playback_rate);
+  void SetPlaybackRate(double playback_rate);
 
   // Sets the bitrate to the given value and updates buffer window
   // accordingly.
@@ -314,7 +314,7 @@
   int bitrate_;
 
   // Playback rate of the media.
-  float playback_rate_;
+  double playback_rate_;
 
   scoped_refptr<MediaLog> media_log_;
 
diff --git a/media/blink/buffered_resource_loader_unittest.cc b/media/blink/buffered_resource_loader_unittest.cc
index f046d60..1fdd6d8 100644
--- a/media/blink/buffered_resource_loader_unittest.cc
+++ b/media/blink/buffered_resource_loader_unittest.cc
@@ -1068,7 +1068,7 @@
 TEST_F(BufferedResourceLoaderTest, BufferWindow_PlaybackRate_BelowLowerBound) {
   Initialize(kHttpUrl, -1, -1);
   Start();
-  loader_->SetPlaybackRate(0.1f);
+  loader_->SetPlaybackRate(0.1);
   CheckBufferWindowBounds();
   StopWhenLoad();
 }
diff --git a/media/blink/key_system_config_selector.cc b/media/blink/key_system_config_selector.cc
index 769f973..67a13e2 100644
--- a/media/blink/key_system_config_selector.cc
+++ b/media/blink/key_system_config_selector.cc
@@ -20,33 +20,21 @@
 
 namespace media {
 
+using EmeFeatureRequirement =
+    blink::WebMediaKeySystemConfiguration::Requirement;
+
 namespace {
 
-static EmeFeatureRequirement ConvertRequirement(
-    blink::WebMediaKeySystemConfiguration::Requirement requirement) {
-  switch (requirement) {
-    case blink::WebMediaKeySystemConfiguration::Requirement::Required:
-      return EME_FEATURE_REQUIRED;
-    case blink::WebMediaKeySystemConfiguration::Requirement::Optional:
-      return EME_FEATURE_OPTIONAL;
-    case blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed:
-      return EME_FEATURE_NOT_ALLOWED;
-  }
-
-  NOTREACHED();
-  return EME_FEATURE_NOT_ALLOWED;
-}
-
 static EmeConfigRule GetSessionTypeConfigRule(EmeSessionTypeSupport support) {
   switch (support) {
-    case EME_SESSION_TYPE_INVALID:
+    case EmeSessionTypeSupport::INVALID:
       NOTREACHED();
       return EmeConfigRule::NOT_SUPPORTED;
-    case EME_SESSION_TYPE_NOT_SUPPORTED:
+    case EmeSessionTypeSupport::NOT_SUPPORTED:
       return EmeConfigRule::NOT_SUPPORTED;
-    case EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER:
+    case EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER:
       return EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED;
-    case EME_SESSION_TYPE_SUPPORTED:
+    case EmeSessionTypeSupport::SUPPORTED:
       return EmeConfigRule::PERSISTENCE_REQUIRED;
   }
   NOTREACHED();
@@ -56,7 +44,7 @@
 static EmeConfigRule GetDistinctiveIdentifierConfigRule(
     EmeFeatureSupport support,
     EmeFeatureRequirement requirement) {
-  if (support == EME_FEATURE_INVALID) {
+  if (support == EmeFeatureSupport::INVALID) {
     NOTREACHED();
     return EmeConfigRule::NOT_SUPPORTED;
   }
@@ -70,24 +58,24 @@
   //    NOT_SUPPORTED  I_NOT_ALLOWED  I_NOT_ALLOWED  NOT_SUPPORTED
   //      REQUESTABLE  I_NOT_ALLOWED  SUPPORTED      I_REQUIRED
   //   ALWAYS_ENABLED  NOT_SUPPORTED  I_REQUIRED     I_REQUIRED
-  DCHECK(support == EME_FEATURE_NOT_SUPPORTED ||
-         support == EME_FEATURE_REQUESTABLE ||
-         support == EME_FEATURE_ALWAYS_ENABLED);
-  DCHECK(requirement == EME_FEATURE_NOT_ALLOWED ||
-         requirement == EME_FEATURE_OPTIONAL ||
-         requirement == EME_FEATURE_REQUIRED);
-  if ((support == EME_FEATURE_NOT_SUPPORTED &&
-       requirement == EME_FEATURE_REQUIRED) ||
-      (support == EME_FEATURE_ALWAYS_ENABLED &&
-       requirement == EME_FEATURE_NOT_ALLOWED)) {
+  DCHECK(support == EmeFeatureSupport::NOT_SUPPORTED ||
+         support == EmeFeatureSupport::REQUESTABLE ||
+         support == EmeFeatureSupport::ALWAYS_ENABLED);
+  DCHECK(requirement == EmeFeatureRequirement::NotAllowed ||
+         requirement == EmeFeatureRequirement::Optional ||
+         requirement == EmeFeatureRequirement::Required);
+  if ((support == EmeFeatureSupport::NOT_SUPPORTED &&
+       requirement == EmeFeatureRequirement::Required) ||
+      (support == EmeFeatureSupport::ALWAYS_ENABLED &&
+       requirement == EmeFeatureRequirement::NotAllowed)) {
     return EmeConfigRule::NOT_SUPPORTED;
   }
-  if (support == EME_FEATURE_REQUESTABLE &&
-      requirement == EME_FEATURE_OPTIONAL) {
+  if (support == EmeFeatureSupport::REQUESTABLE &&
+      requirement == EmeFeatureRequirement::Optional) {
     return EmeConfigRule::SUPPORTED;
   }
-  if (support == EME_FEATURE_NOT_SUPPORTED ||
-      requirement == EME_FEATURE_NOT_ALLOWED) {
+  if (support == EmeFeatureSupport::NOT_SUPPORTED ||
+      requirement == EmeFeatureRequirement::NotAllowed) {
     return EmeConfigRule::IDENTIFIER_NOT_ALLOWED;
   }
   return EmeConfigRule::IDENTIFIER_REQUIRED;
@@ -96,7 +84,7 @@
 static EmeConfigRule GetPersistentStateConfigRule(
     EmeFeatureSupport support,
     EmeFeatureRequirement requirement) {
-  if (support == EME_FEATURE_INVALID) {
+  if (support == EmeFeatureSupport::INVALID) {
     NOTREACHED();
     return EmeConfigRule::NOT_SUPPORTED;
   }
@@ -113,24 +101,24 @@
   //    NOT_SUPPORTED  P_NOT_ALLOWED  P_NOT_ALLOWED  NOT_SUPPORTED
   //      REQUESTABLE  P_NOT_ALLOWED  SUPPORTED      P_REQUIRED
   //   ALWAYS_ENABLED  NOT_SUPPORTED  P_REQUIRED     P_REQUIRED
-  DCHECK(support == EME_FEATURE_NOT_SUPPORTED ||
-         support == EME_FEATURE_REQUESTABLE ||
-         support == EME_FEATURE_ALWAYS_ENABLED);
-  DCHECK(requirement == EME_FEATURE_NOT_ALLOWED ||
-         requirement == EME_FEATURE_OPTIONAL ||
-         requirement == EME_FEATURE_REQUIRED);
-  if ((support == EME_FEATURE_NOT_SUPPORTED &&
-       requirement == EME_FEATURE_REQUIRED) ||
-      (support == EME_FEATURE_ALWAYS_ENABLED &&
-       requirement == EME_FEATURE_NOT_ALLOWED)) {
+  DCHECK(support == EmeFeatureSupport::NOT_SUPPORTED ||
+         support == EmeFeatureSupport::REQUESTABLE ||
+         support == EmeFeatureSupport::ALWAYS_ENABLED);
+  DCHECK(requirement == EmeFeatureRequirement::NotAllowed ||
+         requirement == EmeFeatureRequirement::Optional ||
+         requirement == EmeFeatureRequirement::Required);
+  if ((support == EmeFeatureSupport::NOT_SUPPORTED &&
+       requirement == EmeFeatureRequirement::Required) ||
+      (support == EmeFeatureSupport::ALWAYS_ENABLED &&
+       requirement == EmeFeatureRequirement::NotAllowed)) {
     return EmeConfigRule::NOT_SUPPORTED;
   }
-  if (support == EME_FEATURE_REQUESTABLE &&
-      requirement == EME_FEATURE_OPTIONAL) {
+  if (support == EmeFeatureSupport::REQUESTABLE &&
+      requirement == EmeFeatureRequirement::Optional) {
     return EmeConfigRule::SUPPORTED;
   }
-  if (support == EME_FEATURE_NOT_SUPPORTED ||
-      requirement == EME_FEATURE_NOT_ALLOWED) {
+  if (support == EmeFeatureSupport::NOT_SUPPORTED ||
+      requirement == EmeFeatureRequirement::NotAllowed) {
     return EmeConfigRule::PERSISTENCE_NOT_ALLOWED;
   }
   return EmeConfigRule::PERSISTENCE_REQUIRED;
@@ -426,7 +414,7 @@
   // permission has already been denied. This would happen anyway at step 11.
   EmeConfigRule di_rule = GetDistinctiveIdentifierConfigRule(
       key_systems_->GetDistinctiveIdentifierSupport(key_system),
-      ConvertRequirement(candidate.distinctiveIdentifier));
+      candidate.distinctiveIdentifier);
   if (!config_state->IsRuleSupported(di_rule)) {
     DVLOG(2) << "Rejecting requested configuration because "
              << "the distinctiveIdentifier requirement was not supported.";
@@ -448,7 +436,7 @@
   //        combination with accumulated configuration, return null.
   EmeConfigRule ps_rule = GetPersistentStateConfigRule(
       key_systems_->GetPersistentStateSupport(key_system),
-      ConvertRequirement(candidate.persistentState));
+      candidate.persistentState);
   if (!config_state->IsRuleSupported(ps_rule)) {
     DVLOG(2) << "Rejecting requested configuration because "
              << "the persistentState requirement was not supported.";
@@ -565,10 +553,10 @@
       blink::WebMediaKeySystemConfiguration::Requirement::Optional) {
     EmeConfigRule not_allowed_rule = GetDistinctiveIdentifierConfigRule(
         key_systems_->GetDistinctiveIdentifierSupport(key_system),
-        EME_FEATURE_NOT_ALLOWED);
+        EmeFeatureRequirement::NotAllowed);
     EmeConfigRule required_rule = GetDistinctiveIdentifierConfigRule(
         key_systems_->GetDistinctiveIdentifierSupport(key_system),
-        EME_FEATURE_REQUIRED);
+        EmeFeatureRequirement::Required);
     bool not_allowed_supported =
         config_state->IsRuleSupported(not_allowed_rule);
     bool required_supported = config_state->IsRuleSupported(required_rule);
@@ -605,10 +593,10 @@
       blink::WebMediaKeySystemConfiguration::Requirement::Optional) {
     EmeConfigRule not_allowed_rule = GetPersistentStateConfigRule(
         key_systems_->GetPersistentStateSupport(key_system),
-        EME_FEATURE_NOT_ALLOWED);
+        EmeFeatureRequirement::NotAllowed);
     EmeConfigRule required_rule = GetPersistentStateConfigRule(
         key_systems_->GetPersistentStateSupport(key_system),
-        EME_FEATURE_REQUIRED);
+        EmeFeatureRequirement::Required);
     // |distinctiveIdentifier| should not be affected after it is decided.
     DCHECK(not_allowed_rule == EmeConfigRule::NOT_SUPPORTED ||
            not_allowed_rule == EmeConfigRule::PERSISTENCE_NOT_ALLOWED);
diff --git a/media/blink/key_system_config_selector_unittest.cc b/media/blink/key_system_config_selector_unittest.cc
index fc6d99a..762db78 100644
--- a/media/blink/key_system_config_selector_unittest.cc
+++ b/media/blink/key_system_config_selector_unittest.cc
@@ -124,15 +124,16 @@
   InitDataTypeMask init_data_types = kInitDataTypeMaskNone;
 
   // INVALID so that they must be set in any test that needs them.
-  EmeSessionTypeSupport persistent_license = EME_SESSION_TYPE_INVALID;
-  EmeSessionTypeSupport persistent_release_message = EME_SESSION_TYPE_INVALID;
+  EmeSessionTypeSupport persistent_license = EmeSessionTypeSupport::INVALID;
+  EmeSessionTypeSupport persistent_release_message =
+      EmeSessionTypeSupport::INVALID;
 
   // Every test implicitly requires these, so they must be set. They are set to
   // values that are likely to cause tests to fail if they are accidentally
   // depended on. Test cases explicitly depending on them should set them, as
   // the default values may be changed.
-  EmeFeatureSupport persistent_state = EME_FEATURE_NOT_SUPPORTED;
-  EmeFeatureSupport distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  EmeFeatureSupport persistent_state = EmeFeatureSupport::NOT_SUPPORTED;
+  EmeFeatureSupport distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 };
 
 class FakeMediaPermission : public MediaPermission {
@@ -327,7 +328,7 @@
 // --- distinctiveIdentifier ---
 
 TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_Default) {
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   blink::WebMediaKeySystemConfiguration config;
   config.distinctiveIdentifier =
@@ -341,7 +342,7 @@
 
 TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_Forced) {
   media_permission_->is_granted = true;
-  key_systems_->distinctive_identifier = EME_FEATURE_ALWAYS_ENABLED;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::ALWAYS_ENABLED;
 
   blink::WebMediaKeySystemConfiguration config;
   config.distinctiveIdentifier =
@@ -354,7 +355,7 @@
 }
 
 TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_Blocked) {
-  key_systems_->distinctive_identifier = EME_FEATURE_NOT_SUPPORTED;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::NOT_SUPPORTED;
 
   blink::WebMediaKeySystemConfiguration config;
   config.distinctiveIdentifier =
@@ -366,7 +367,7 @@
 
 TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_RequestsPermission) {
   media_permission_->is_granted = true;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   blink::WebMediaKeySystemConfiguration config;
   config.distinctiveIdentifier =
@@ -380,7 +381,7 @@
 
 TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_RespectsPermission) {
   media_permission_->is_granted = false;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   blink::WebMediaKeySystemConfiguration config;
   config.distinctiveIdentifier =
@@ -393,7 +394,7 @@
 // --- persistentState ---
 
 TEST_F(KeySystemConfigSelectorTest, PersistentState_Default) {
-  key_systems_->persistent_state = EME_FEATURE_REQUESTABLE;
+  key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE;
 
   blink::WebMediaKeySystemConfiguration config;
   config.persistentState =
@@ -406,7 +407,7 @@
 }
 
 TEST_F(KeySystemConfigSelectorTest, PersistentState_Forced) {
-  key_systems_->persistent_state = EME_FEATURE_ALWAYS_ENABLED;
+  key_systems_->persistent_state = EmeFeatureSupport::ALWAYS_ENABLED;
 
   blink::WebMediaKeySystemConfiguration config;
   config.persistentState =
@@ -419,7 +420,7 @@
 }
 
 TEST_F(KeySystemConfigSelectorTest, PersistentState_Blocked) {
-  key_systems_->persistent_state = EME_FEATURE_ALWAYS_ENABLED;
+  key_systems_->persistent_state = EmeFeatureSupport::ALWAYS_ENABLED;
 
   blink::WebMediaKeySystemConfiguration config;
   config.persistentState =
@@ -442,8 +443,8 @@
 
 TEST_F(KeySystemConfigSelectorTest, SessionTypes_SubsetSupported) {
   // Allow persistent state, as it would be required to be successful.
-  key_systems_->persistent_state = EME_FEATURE_REQUESTABLE;
-  key_systems_->persistent_license = EME_SESSION_TYPE_NOT_SUPPORTED;
+  key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE;
+  key_systems_->persistent_license = EmeSessionTypeSupport::NOT_SUPPORTED;
 
   std::vector<blink::WebEncryptedMediaSessionType> session_types;
   session_types.push_back(blink::WebEncryptedMediaSessionType::Temporary);
@@ -460,8 +461,8 @@
 
 TEST_F(KeySystemConfigSelectorTest, SessionTypes_AllSupported) {
   // Allow persistent state, and expect it to be required.
-  key_systems_->persistent_state = EME_FEATURE_REQUESTABLE;
-  key_systems_->persistent_license = EME_SESSION_TYPE_SUPPORTED;
+  key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE;
+  key_systems_->persistent_license = EmeSessionTypeSupport::SUPPORTED;
 
   std::vector<blink::WebEncryptedMediaSessionType> session_types;
   session_types.push_back(blink::WebEncryptedMediaSessionType::Temporary);
@@ -487,9 +488,10 @@
 
 TEST_F(KeySystemConfigSelectorTest, SessionTypes_PermissionCanBeRequired) {
   media_permission_->is_granted = true;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
-  key_systems_->persistent_state = EME_FEATURE_REQUESTABLE;
-  key_systems_->persistent_license = EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
+  key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE;
+  key_systems_->persistent_license =
+      EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER;
 
   std::vector<blink::WebEncryptedMediaSessionType> session_types;
   session_types.push_back(
@@ -636,7 +638,7 @@
 TEST_F(KeySystemConfigSelectorTest,
        VideoCapabilities_Robustness_PermissionCanBeRequired) {
   media_permission_->is_granted = true;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities(1);
   video_capabilities[0].contentType = "a";
@@ -656,7 +658,7 @@
 TEST_F(KeySystemConfigSelectorTest,
        VideoCapabilities_Robustness_PermissionCanBeRecommended) {
   media_permission_->is_granted = false;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities(1);
   video_capabilities[0].contentType = "a";
@@ -725,7 +727,7 @@
 TEST_F(KeySystemConfigSelectorTest,
        Configurations_FirstRequiresPermission_Allowed) {
   media_permission_->is_granted = true;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   blink::WebMediaKeySystemConfiguration config1;
   config1.label = "a";
@@ -744,7 +746,7 @@
 TEST_F(KeySystemConfigSelectorTest,
        Configurations_FirstRequiresPermission_Rejected) {
   media_permission_->is_granted = false;
-  key_systems_->distinctive_identifier = EME_FEATURE_REQUESTABLE;
+  key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE;
 
   blink::WebMediaKeySystemConfiguration config1;
   config1.label = "a";
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.cc b/media/blink/webcontentdecryptionmodulesession_impl.cc
index 643aa948..94afa0e 100644
--- a/media/blink/webcontentdecryptionmodulesession_impl.cc
+++ b/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -13,11 +13,14 @@
 #include "media/base/cdm_key_information.h"
 #include "media/base/cdm_promise.h"
 #include "media/base/key_systems.h"
+#include "media/base/limits.h"
 #include "media/base/media_keys.h"
 #include "media/blink/cdm_result_promise.h"
 #include "media/blink/cdm_session_adapter.h"
 #include "media/blink/new_session_cdm_result_promise.h"
 #include "media/blink/webmediaplayer_util.h"
+#include "media/cdm/cenc_utils.h"
+#include "media/cdm/json_web_key.h"
 #include "third_party/WebKit/public/platform/WebData.h"
 #include "third_party/WebKit/public/platform/WebEncryptedMediaKeyInformation.h"
 #include "third_party/WebKit/public/platform/WebString.h"
@@ -91,6 +94,60 @@
   return MediaKeys::TEMPORARY_SESSION;
 }
 
+static bool SanitizeInitData(EmeInitDataType init_data_type,
+                             const unsigned char* init_data,
+                             size_t init_data_length,
+                             std::vector<uint8>* sanitized_init_data,
+                             std::string* error_message) {
+  if (init_data_length > limits::kMaxInitDataLength) {
+    error_message->assign("Initialization data too long.");
+    return false;
+  }
+
+  switch (init_data_type) {
+    case EmeInitDataType::WEBM:
+      sanitized_init_data->assign(init_data, init_data + init_data_length);
+      return true;
+
+    case EmeInitDataType::CENC:
+      if (!ValidatePsshInput(init_data, init_data_length)) {
+        error_message->assign("Initialization data for CENC is incorrect.");
+        return false;
+      }
+
+      sanitized_init_data->assign(init_data, init_data + init_data_length);
+      return true;
+
+    case EmeInitDataType::KEYIDS: {
+      // Extract the keys and then rebuild the message. This ensures that any
+      // extra data in the provided JSON is dropped.
+      std::string init_data_string(init_data, init_data + init_data_length);
+      KeyIdList key_ids;
+      if (!ExtractKeyIdsFromKeyIdsInitData(init_data_string, &key_ids,
+                                           error_message))
+        return false;
+
+      for (const auto& key_id : key_ids) {
+        if (key_id.size() < limits::kMinKeyIdLength ||
+            key_id.size() > limits::kMaxKeyIdLength) {
+          error_message->assign("Incorrect key size.");
+          return false;
+        }
+      }
+
+      CreateKeyIdsInitData(key_ids, sanitized_init_data);
+      return true;
+    }
+
+    case EmeInitDataType::UNKNOWN:
+      break;
+  }
+
+  NOTREACHED();
+  error_message->assign("Initialization data type is not supported.");
+  return false;
+}
+
 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
     const scoped_refptr<CdmSessionAdapter>& adapter)
     : adapter_(adapter), is_closed_(false), weak_ptr_factory_(this) {
@@ -118,7 +175,7 @@
     blink::WebContentDecryptionModuleResult result) {
   DCHECK(session_id_.empty());
 
-  // Step 5 from https://w3c.github.io/encrypted-media/#generateRequest.
+  // From https://w3c.github.io/encrypted-media/#generateRequest.
   // 5. If the Key System implementation represented by this object's cdm
   //    implementation value does not support initDataType as an Initialization
   //    Data Type, return a promise rejected with a new DOMException whose name
@@ -134,9 +191,42 @@
     return;
   }
 
+  // 9.1 If the init data is not valid for initDataType, reject promise with a
+  //     new DOMException whose name is InvalidAccessError.
+  // 9.2 Let sanitized init data be a validated and sanitized version of init
+  //     data. The user agent must thoroughly validate the Initialization Data
+  //     before passing it to the CDM. This includes verifying that the length
+  //     and values of fields are reasonable, verifying that values are within
+  //     reasonable limits, and stripping irrelevant, unsupported, or unknown
+  //     data or fields. It is recommended that user agents pre-parse, sanitize,
+  //     and/or generate a fully sanitized version of the Initialization Data.
+  //     If the Initialization Data format specified by initDataType support
+  //     multiple entries, the user agent should remove entries that are not
+  //     needed by the CDM.
+  // 9.3 If the previous step failed, reject promise with a new DOMException
+  //     whose name is InvalidAccessError.
+  std::vector<uint8> sanitized_init_data;
+  std::string message;
+  if (!SanitizeInitData(eme_init_data_type, init_data, init_data_length,
+                        &sanitized_init_data, &message)) {
+    result.completeWithError(
+        blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0,
+        blink::WebString::fromUTF8(message));
+    return;
+  }
+
+  // 9.4 Let session id be the empty string.
+  //     (Done in constructor.)
+
+  // 9.5 Let message be null.
+  //     (Done by CDM.)
+
+  // 9.6 Let cdm be the CDM instance represented by this object's cdm
+  //     instance value.
+  // 9.7 Use the cdm to execute the following steps:
   adapter_->InitializeNewSession(
-      eme_init_data_type, init_data,
-      base::saturated_cast<int>(init_data_length),
+      eme_init_data_type, vector_as_array(&sanitized_init_data),
+      base::saturated_cast<int>(sanitized_init_data.size()),
       convertSessionType(session_type),
       scoped_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise(
           result, adapter_->GetKeySystemUMAPrefix() + kGenerateRequestUMAName,
@@ -145,16 +235,6 @@
               base::Unretained(this)))));
 }
 
-// TODO(jrummell): Remove this. http://crbug.com/418239.
-void WebContentDecryptionModuleSessionImpl::initializeNewSession(
-    const blink::WebString& init_data_type,
-    const uint8* init_data,
-    size_t init_data_length,
-    const blink::WebString& session_type,
-    blink::WebContentDecryptionModuleResult result) {
-  NOTREACHED();
-}
-
 void WebContentDecryptionModuleSessionImpl::load(
     const blink::WebString& session_id,
     blink::WebContentDecryptionModuleResult result) {
@@ -207,8 +287,8 @@
     MediaKeys::MessageType message_type,
     const std::vector<uint8>& message) {
   DCHECK(client_) << "Client not set before message event";
-  client_->message(convertMessageType(message_type),
-                   message.empty() ? NULL : &message[0], message.size());
+  client_->message(convertMessageType(message_type), vector_as_array(&message),
+                   message.size());
 }
 
 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.h b/media/blink/webcontentdecryptionmodulesession_impl.h
index 881c07e13..2f00ff5 100644
--- a/media/blink/webcontentdecryptionmodulesession_impl.h
+++ b/media/blink/webcontentdecryptionmodulesession_impl.h
@@ -38,12 +38,6 @@
       size_t initDataLength,
       blink::WebEncryptedMediaSessionType session_type,
       blink::WebContentDecryptionModuleResult result);
-  virtual void initializeNewSession(
-      const blink::WebString& init_data_type,
-      const uint8* init_data,
-      size_t init_data_length,
-      const blink::WebString& session_type,
-      blink::WebContentDecryptionModuleResult result);
   virtual void load(const blink::WebString& session_id,
                     blink::WebContentDecryptionModuleResult result);
   virtual void update(const uint8* response,
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 8fa7a7f5..ac67b21 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -122,7 +122,7 @@
       opaque_(false),
       paused_(true),
       seeking_(false),
-      playback_rate_(0.0f),
+      playback_rate_(0.0),
       ended_(false),
       pending_seek_(false),
       pending_seek_seconds_(0.0f),
@@ -269,7 +269,7 @@
 
   const bool was_already_paused = paused_ || playback_rate_ == 0;
   paused_ = true;
-  pipeline_.SetPlaybackRate(0.0f);
+  pipeline_.SetPlaybackRate(0.0);
   if (data_source_)
     data_source_->MediaIsPaused();
   UpdatePausedTime();
diff --git a/media/cdm/cenc_utils.cc b/media/cdm/cenc_utils.cc
index 2eeafd7..a59c19c 100644
--- a/media/cdm/cenc_utils.cc
+++ b/media/cdm/cenc_utils.cc
@@ -70,6 +70,52 @@
   return true;
 }
 
+// Checks that |reader| contains a valid 'ppsh' box header. |reader| is updated
+// to point to the content immediately following the box header. Returns true
+// if the header looks valid and |reader| contains enough data for the size of
+// header. |size| is updated as the computed size of the box header. Otherwise
+// false is returned.
+static bool ValidBoxHeader(BitReader* reader, uint32* size) {
+  // Enough data for a miniumum size 'pssh' box?
+  uint32 available_bytes = reader->bits_available() / 8;
+  RCHECK(available_bytes >= kMinimumBoxSizeInBytes);
+
+  *size = ReadBits(reader, 32);
+
+  // Must be a 'pssh' box or else fail.
+  RCHECK(ReadBits(reader, 8) == 'p');
+  RCHECK(ReadBits(reader, 8) == 's');
+  RCHECK(ReadBits(reader, 8) == 's');
+  RCHECK(ReadBits(reader, 8) == 'h');
+
+  if (*size == 1) {
+    // If largesize > 2**32 it is too big.
+    RCHECK(ReadBits(reader, 32) == 0);
+    *size = ReadBits(reader, 32);
+  } else if (*size == 0) {
+    *size = available_bytes;
+  }
+
+  // Check that the buffer contains at least size bytes.
+  return available_bytes >= *size;
+}
+
+bool ValidatePsshInput(const uint8* input, size_t input_length) {
+  size_t offset = 0;
+  while (offset < input_length) {
+    // Create a BitReader over the remaining part of the buffer.
+    BitReader reader(input + offset, input_length - offset);
+    uint32 size;
+    RCHECK(ValidBoxHeader(&reader, &size));
+
+    // Update offset to point at the next 'pssh' box (may not be one).
+    offset += size;
+  }
+
+  // Only valid if this contains 0 or more 'pssh' boxes.
+  return offset == input_length;
+}
+
 bool GetKeyIdsForCommonSystemId(const uint8* input,
                                 int input_length,
                                 std::vector<std::vector<uint8>>* key_ids) {
@@ -77,29 +123,10 @@
   std::vector<std::vector<uint8>> result;
 
   while (offset < input_length) {
+    // Create a BitReader over the remaining part of the buffer.
     BitReader reader(input + offset, input_length - offset);
-
-    // Enough data for a miniumum size 'pssh' box?
-    RCHECK(reader.bits_available() >= kMinimumBoxSizeInBytes * 8);
-
-    uint32 size = ReadBits(&reader, 32);
-
-    // Must be a 'pssh' box or else fail.
-    RCHECK(ReadBits(&reader, 8) == 'p');
-    RCHECK(ReadBits(&reader, 8) == 's');
-    RCHECK(ReadBits(&reader, 8) == 's');
-    RCHECK(ReadBits(&reader, 8) == 'h');
-
-    if (size == 1) {
-      // If largesize > 2**32 it is too big.
-      RCHECK(ReadBits(&reader, 32) == 0);
-      size = ReadBits(&reader, 32);
-    } else if (size == 0) {
-      size = input_length - offset;
-    }
-
-    // Check that the buffer contains at least size bytes.
-    RCHECK(static_cast<uint32>(input_length - offset) >= size);
+    uint32 size;
+    RCHECK(ValidBoxHeader(&reader, &size));
 
     // Update offset to point at the next 'pssh' box (may not be one).
     offset += size;
diff --git a/media/cdm/cenc_utils.h b/media/cdm/cenc_utils.h
index c659742..6fd9952 100644
--- a/media/cdm/cenc_utils.h
+++ b/media/cdm/cenc_utils.h
@@ -12,6 +12,10 @@
 
 namespace media {
 
+// Validate that |input| is a set of concatenated 'pssh' boxes and the sizes
+// match. Returns true if |input| looks valid, false otherwise.
+MEDIA_EXPORT bool ValidatePsshInput(const uint8* input, size_t input_length);
+
 // Gets the Key Ids from a 'pssh' box for the Common SystemID among one or
 // more concatenated 'pssh' boxes. If |input| looks valid, then true is
 // returned and |key_ids| is updated to contain the values found. Otherwise
diff --git a/media/cdm/cenc_utils_unittest.cc b/media/cdm/cenc_utils_unittest.cc
index ae75817..fd481da4 100644
--- a/media/cdm/cenc_utils_unittest.cc
+++ b/media/cdm/cenc_utils_unittest.cc
@@ -168,6 +168,7 @@
 
 TEST_F(CencUtilsTest, EmptyPSSH) {
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(nullptr, 0));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(nullptr, 0, &key_ids));
   EXPECT_EQ(0u, key_ids.size());
 }
@@ -175,6 +176,7 @@
 TEST_F(CencUtilsTest, PSSHVersion0) {
   std::vector<uint8> box = MakePSSHBox(0);
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box[0], box.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box[0], box.size(), &key_ids));
   EXPECT_EQ(0u, key_ids.size());
 }
@@ -182,6 +184,7 @@
 TEST_F(CencUtilsTest, PSSHVersion1WithNoKeys) {
   std::vector<uint8> box = MakePSSHBox(1);
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box[0], box.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box[0], box.size(), &key_ids));
   EXPECT_EQ(0u, key_ids.size());
 }
@@ -189,6 +192,7 @@
 TEST_F(CencUtilsTest, PSSHVersion1WithOneKey) {
   std::vector<uint8> box = MakePSSHBox(1, Key1());
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box[0], box.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box[0], box.size(), &key_ids));
   EXPECT_EQ(1u, key_ids.size());
   EXPECT_EQ(key_ids[0], Key1());
@@ -197,6 +201,7 @@
 TEST_F(CencUtilsTest, PSSHVersion1WithTwoKeys) {
   std::vector<uint8> box = MakePSSHBox(1, Key1(), Key2());
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box[0], box.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box[0], box.size(), &key_ids));
   EXPECT_EQ(2u, key_ids.size());
   EXPECT_EQ(key_ids[0], Key1());
@@ -212,6 +217,7 @@
     box0.push_back(value);
 
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box0[0], box0.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box0[0], box0.size(), &key_ids));
   EXPECT_EQ(1u, key_ids.size());
   EXPECT_EQ(key_ids[0], Key1());
@@ -226,6 +232,7 @@
     box1.push_back(value);
 
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box1[0], box1.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box1[0], box1.size(), &key_ids));
   EXPECT_EQ(1u, key_ids.size());
   EXPECT_EQ(key_ids[0], Key1());
@@ -244,6 +251,7 @@
     box.push_back(value);
 
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(&box[0], box.size()));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(&box[0], box.size(), &key_ids));
   EXPECT_EQ(4u, key_ids.size());
   EXPECT_EQ(key_ids[0], Key1());
@@ -257,8 +265,10 @@
   std::vector<std::vector<uint8>> key_ids;
   for (uint32 i = 1; i < box.size(); ++i) {
     // Modify size of data passed to be less than real size.
+    EXPECT_FALSE(ValidatePsshInput(&box[0], i));
     EXPECT_FALSE(GetKeyIdsForCommonSystemId(&box[0], i, &key_ids));
     // Modify starting point.
+    EXPECT_FALSE(ValidatePsshInput(&box[i], box.size() - i));
     EXPECT_FALSE(GetKeyIdsForCommonSystemId(&box[i], box.size() - i, &key_ids));
   }
 }
@@ -304,6 +314,7 @@
   };
 
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(data, arraysize(data)));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(data, arraysize(data), &key_ids));
   EXPECT_EQ(2u, key_ids.size());
 }
@@ -325,6 +336,7 @@
   };
 
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_TRUE(ValidatePsshInput(data, arraysize(data)));
   EXPECT_TRUE(GetKeyIdsForCommonSystemId(data, arraysize(data), &key_ids));
   EXPECT_EQ(2u, key_ids.size());
 }
@@ -347,6 +359,7 @@
   };
 
   std::vector<std::vector<uint8>> key_ids;
+  EXPECT_FALSE(ValidatePsshInput(data, arraysize(data)));
   EXPECT_FALSE(GetKeyIdsForCommonSystemId(data, arraysize(data), &key_ids));
 }
 
diff --git a/media/cdm/json_web_key.cc b/media/cdm/json_web_key.cc
index 43533f0..f60c6f5 100644
--- a/media/cdm/json_web_key.cc
+++ b/media/cdm/json_web_key.cc
@@ -329,6 +329,25 @@
   license->swap(result);
 }
 
+void CreateKeyIdsInitData(const KeyIdList& key_ids,
+                          std::vector<uint8>* init_data) {
+  // Create the init_data.
+  scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
+  scoped_ptr<base::ListValue> list(new base::ListValue());
+  for (const auto& key_id : key_ids)
+    list->AppendString(EncodeBase64Url(&key_id[0], key_id.size()));
+  dictionary->Set(kKeyIdsTag, list.release());
+
+  // Serialize the dictionary as a string.
+  std::string json;
+  JSONStringValueSerializer serializer(&json);
+  serializer.Serialize(*dictionary);
+
+  // Convert the serialized data into std::vector and return it.
+  std::vector<uint8> result(json.begin(), json.end());
+  init_data->swap(result);
+}
+
 bool ExtractFirstKeyIdFromLicenseRequest(const std::vector<uint8>& license,
                                          std::vector<uint8>* first_key) {
   const std::string license_as_str(
diff --git a/media/cdm/json_web_key.h b/media/cdm/json_web_key.h
index 7be4473..c77a814c 100644
--- a/media/cdm/json_web_key.h
+++ b/media/cdm/json_web_key.h
@@ -81,6 +81,11 @@
                                        MediaKeys::SessionType session_type,
                                        std::vector<uint8>* license);
 
+// Creates a keyIDs init_data message for the |key_ids| specified.
+// |key_ids_init_data| is updated to contain the resulting JSON string.
+MEDIA_EXPORT void CreateKeyIdsInitData(const KeyIdList& key_ids,
+                                       std::vector<uint8>* key_ids_init_data);
+
 // Extract the first key from the license request message. Returns true if
 // |license| is a valid license request and contains at least one key,
 // otherwise false and |first_key| is not touched.
diff --git a/media/cdm/json_web_key_unittest.cc b/media/cdm/json_web_key_unittest.cc
index ecd9d2a..82b3bb0 100644
--- a/media/cdm/json_web_key_unittest.cc
+++ b/media/cdm/json_web_key_unittest.cc
@@ -576,5 +576,34 @@
             "'kids'[1] is not valid base64url encoded. Value: AQI/");
 }
 
+TEST_F(JSONWebKeyTest, CreateInitData) {
+  const uint8 data1[] = { 0x01, 0x02 };
+  const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
+  const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
+
+  KeyIdList key_ids;
+  std::string error_message;
+
+  key_ids.push_back(std::vector<uint8>(data1, data1 + arraysize(data1)));
+  std::vector<uint8> init_data1;
+  CreateKeyIdsInitData(key_ids, &init_data1);
+  std::string result1(init_data1.begin(), init_data1.end());
+  EXPECT_EQ(result1, "{\"kids\":[\"AQI\"]}");
+
+  key_ids.push_back(std::vector<uint8>(data2, data2 + arraysize(data2)));
+  std::vector<uint8> init_data2;
+  CreateKeyIdsInitData(key_ids, &init_data2);
+  std::string result2(init_data2.begin(), init_data2.end());
+  EXPECT_EQ(result2, "{\"kids\":[\"AQI\",\"AQIDBA\"]}");
+
+  key_ids.push_back(std::vector<uint8>(data3, data3 + arraysize(data3)));
+  std::vector<uint8> init_data3;
+  CreateKeyIdsInitData(key_ids, &init_data3);
+  std::string result3(init_data3.begin(), init_data3.end());
+  EXPECT_EQ(result3,
+            "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}");
+}
+
 }  // namespace media
 
diff --git a/media/filters/audio_clock_unittest.cc b/media/filters/audio_clock_unittest.cc
index 7b4d85fd..3fe437e 100644
--- a/media/filters/audio_clock_unittest.cc
+++ b/media/filters/audio_clock_unittest.cc
@@ -19,7 +19,7 @@
   void WroteAudio(int frames_written,
                   int frames_requested,
                   int delay_frames,
-                  float playback_rate) {
+                  double playback_rate) {
     clock_.WroteAudio(
         frames_written, frames_requested, delay_frames, playback_rate);
   }
diff --git a/media/filters/audio_renderer_algorithm.cc b/media/filters/audio_renderer_algorithm.cc
index 16e903c..0d59d398 100644
--- a/media/filters/audio_renderer_algorithm.cc
+++ b/media/filters/audio_renderer_algorithm.cc
@@ -49,8 +49,8 @@
 // Max/min supported playback rates for fast/slow audio. Audio outside of these
 // ranges are muted.
 // Audio at these speeds would sound better under a frequency domain algorithm.
-static const float kMinPlaybackRate = 0.5f;
-static const float kMaxPlaybackRate = 4.0f;
+static const double kMinPlaybackRate = 0.5;
+static const double kMaxPlaybackRate = 4.0;
 
 // Overlap-and-add window size in milliseconds.
 static const int kOlaWindowSizeMs = 20;
@@ -144,7 +144,7 @@
 int AudioRendererAlgorithm::FillBuffer(AudioBus* dest,
                                        int dest_offset,
                                        int requested_frames,
-                                       float playback_rate) {
+                                       double playback_rate) {
   if (playback_rate == 0)
     return 0;
 
@@ -237,7 +237,7 @@
       search_block_index_ + search_block_size <= frames;
 }
 
-bool AudioRendererAlgorithm::RunOneWsolaIteration(float playback_rate) {
+bool AudioRendererAlgorithm::RunOneWsolaIteration(double playback_rate) {
   if (!CanPerformWsola())
     return false;
 
@@ -263,7 +263,7 @@
   return true;
 }
 
-void AudioRendererAlgorithm::UpdateOutputTime(float playback_rate,
+void AudioRendererAlgorithm::UpdateOutputTime(double playback_rate,
                                               double time_change) {
   output_time_ += time_change;
   // Center of the search region, in frames.
@@ -272,7 +272,7 @@
   search_block_index_ = search_block_center_index - search_block_center_offset_;
 }
 
-void AudioRendererAlgorithm::RemoveOldInputFrames(float playback_rate) {
+void AudioRendererAlgorithm::RemoveOldInputFrames(double playback_rate) {
   const int earliest_used_index = std::min(target_block_index_,
                                            search_block_index_);
   if (earliest_used_index <= 0)
diff --git a/media/filters/audio_renderer_algorithm.h b/media/filters/audio_renderer_algorithm.h
index 25ac811..2005bfe 100644
--- a/media/filters/audio_renderer_algorithm.h
+++ b/media/filters/audio_renderer_algorithm.h
@@ -51,7 +51,7 @@
   int FillBuffer(AudioBus* dest,
                  int dest_offset,
                  int requested_frames,
-                 float playback_rate);
+                 double playback_rate);
 
   // Clears |audio_buffer_|.
   void FlushBuffers();
@@ -101,15 +101,15 @@
   // Run one iteration of WSOLA, if there are sufficient frames. This will
   // overlap-and-add one block to |wsola_output_|, hence, |num_complete_frames_|
   // is incremented by |ola_hop_size_|.
-  bool RunOneWsolaIteration(float playback_rate);
+  bool RunOneWsolaIteration(double playback_rate);
 
   // Seek |audio_buffer_| forward to remove frames from input that are not used
   // any more. State of the WSOLA will be updated accordingly.
-  void RemoveOldInputFrames(float playback_rate);
+  void RemoveOldInputFrames(double playback_rate);
 
   // Update |output_time_| by |time_change|. In turn |search_block_index_| is
   // updated.
-  void UpdateOutputTime(float playback_rate, double time_change);
+  void UpdateOutputTime(double playback_rate, double time_change);
 
   // Is |target_block_| fully within |search_block_|? If so, we don't need to
   // perform the search.
diff --git a/media/filters/audio_renderer_algorithm_unittest.cc b/media/filters/audio_renderer_algorithm_unittest.cc
index 47ce30e..003cd512 100644
--- a/media/filters/audio_renderer_algorithm_unittest.cc
+++ b/media/filters/audio_renderer_algorithm_unittest.cc
@@ -239,7 +239,7 @@
     EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0);
   }
 
-  void WsolaTest(float playback_rate) {
+  void WsolaTest(double playback_rate) {
     const int kSampleRateHz = 48000;
     const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
     const int kBytesPerSample = 2;
@@ -640,11 +640,11 @@
 }
 
 TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) {
-  WsolaTest(0.6f);
+  WsolaTest(0.6);
 }
 
 TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) {
-  WsolaTest(1.6f);
+  WsolaTest(1.6);
 }
 
 TEST_F(AudioRendererAlgorithmTest, FillBufferOffset) {
diff --git a/media/media_nacl.gyp b/media/media_nacl.gyp
index 39c832e..9697a8a 100644
--- a/media/media_nacl.gyp
+++ b/media/media_nacl.gyp
@@ -27,7 +27,6 @@
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl',
             '../base/base_nacl.gyp:base_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
           ],
           'defines': [
             'MEDIA_IMPLEMENTATION',
@@ -51,9 +50,6 @@
             'build_newlib': 0,
             'build_pnacl_newlib': 1,
           },
-          'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
-          ],
           'sources': [
             'base/media.cc',
             'base/media.h',
diff --git a/media/media_options.gni b/media/media_options.gni
index 9ac7c5e..746b541 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -45,10 +45,6 @@
   # default since it's not available on the normal Web Platform and costs money.
   enable_mpeg2ts_stream_parser = false
 
-  # Enables browser side Content Decryption Modules. Required for embedders
-  # (e.g. Android and ChromeCast) that use a browser side CDM.
-  enable_browser_cdms = is_android
-
   # Experiment to enable mojo based media renderer: http://crbug.com/431776
   enable_media_mojo_renderer = false
 
diff --git a/media/midi/midi_manager_win.h b/media/midi/midi_manager_win.h
index 9cb8fb0b..73c1fe5 100644
--- a/media/midi/midi_manager_win.h
+++ b/media/midi/midi_manager_win.h
@@ -42,7 +42,7 @@
 class MidiManagerWin final : public MidiManager, public MidiServiceWinDelegate {
  public:
   MidiManagerWin() {}
-  virtual ~MidiManagerWin() { midi_service_.reset(); }
+  ~MidiManagerWin() override { midi_service_.reset(); }
 
   // MidiManager overrides:
   void StartInitialization() final;
diff --git a/media/mojo/interfaces/media_renderer.mojom b/media/mojo/interfaces/media_renderer.mojom
index 9165a33..616e677 100644
--- a/media/mojo/interfaces/media_renderer.mojom
+++ b/media/mojo/interfaces/media_renderer.mojom
@@ -25,7 +25,7 @@
   StartPlayingFrom(int64 time_usec);
 
   // Updates the current playback rate. The default playback rate should be 1.
-  SetPlaybackRate(float playback_rate);
+  SetPlaybackRate(double playback_rate);
 
   // Sets the output volume. The default volume should be 1.
   SetVolume(float volume);
diff --git a/media/mojo/services/mojo_renderer_impl.cc b/media/mojo/services/mojo_renderer_impl.cc
index d1b41a6..73e677d 100644
--- a/media/mojo/services/mojo_renderer_impl.cc
+++ b/media/mojo/services/mojo_renderer_impl.cc
@@ -103,7 +103,7 @@
   remote_media_renderer_->StartPlayingFrom(time.InMicroseconds());
 }
 
-void MojoRendererImpl::SetPlaybackRate(float playback_rate) {
+void MojoRendererImpl::SetPlaybackRate(double playback_rate) {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   remote_media_renderer_->SetPlaybackRate(playback_rate);
diff --git a/media/mojo/services/mojo_renderer_impl.h b/media/mojo/services/mojo_renderer_impl.h
index cea3284..7b955a2c 100644
--- a/media/mojo/services/mojo_renderer_impl.h
+++ b/media/mojo/services/mojo_renderer_impl.h
@@ -44,7 +44,7 @@
               const CdmAttachedCB& cdm_attached_cb) override;
   void Flush(const base::Closure& flush_cb) override;
   void StartPlayingFrom(base::TimeDelta time) override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
   void SetVolume(float volume) override;
   base::TimeDelta GetMediaTime() override;
   bool HasAudio() override;
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc
index 0601c2c4..ba81a212 100644
--- a/media/mojo/services/mojo_renderer_service.cc
+++ b/media/mojo/services/mojo_renderer_service.cc
@@ -93,7 +93,7 @@
   SchedulePeriodicMediaTimeUpdates();
 }
 
-void MojoRendererService::SetPlaybackRate(float playback_rate) {
+void MojoRendererService::SetPlaybackRate(double playback_rate) {
   DVLOG(2) << __FUNCTION__ << ": " << playback_rate;
   DCHECK_EQ(state_, STATE_PLAYING);
   renderer_->SetPlaybackRate(playback_rate);
diff --git a/media/mojo/services/mojo_renderer_service.h b/media/mojo/services/mojo_renderer_service.h
index 6003515..1b81168 100644
--- a/media/mojo/services/mojo_renderer_service.h
+++ b/media/mojo/services/mojo_renderer_service.h
@@ -44,7 +44,7 @@
                   const mojo::Closure& callback) override;
   void Flush(const mojo::Closure& callback) override;
   void StartPlayingFrom(int64_t time_delta_usec) override;
-  void SetPlaybackRate(float playback_rate) override;
+  void SetPlaybackRate(double playback_rate) override;
   void SetVolume(float volume) override;
 
  private:
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc
index 6f839db..dbc1b8e 100644
--- a/media/renderers/audio_renderer_impl.cc
+++ b/media/renderers/audio_renderer_impl.cc
@@ -52,7 +52,7 @@
       audio_buffer_stream_(
           new AudioBufferStream(task_runner, decoders.Pass(), media_log)),
       hardware_config_(hardware_config),
-      playback_rate_(0),
+      playback_rate_(0.0),
       state_(kUninitialized),
       buffering_state_(BUFFERING_HAVE_NOTHING),
       rendering_(false),
@@ -100,7 +100,7 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK_EQ(state_, kPlaying);
   DCHECK(!sink_playing_);
-  DCHECK_NE(playback_rate_, 0);
+  DCHECK_NE(playback_rate_, 0.0);
   lock_.AssertAcquired();
 
   sink_playing_ = true;
@@ -535,7 +535,7 @@
       !algorithm_->IsQueueFull();
 }
 
-void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
+void AudioRendererImpl::SetPlaybackRate(double playback_rate) {
   DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK_GE(playback_rate, 0);
@@ -546,7 +546,7 @@
   // We have two cases here:
   // Play: current_playback_rate == 0 && playback_rate != 0
   // Pause: current_playback_rate != 0 && playback_rate == 0
-  float current_playback_rate = playback_rate_;
+  double current_playback_rate = playback_rate_;
   playback_rate_ = playback_rate;
 
   if (!rendering_)
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h
index 366b492..bd11f40 100644
--- a/media/renderers/audio_renderer_impl.h
+++ b/media/renderers/audio_renderer_impl.h
@@ -68,7 +68,7 @@
   // TimeSource implementation.
   void StartTicking() override;
   void StopTicking() override;
-  void SetPlaybackRate(float rate) override;
+  void SetPlaybackRate(double rate) override;
   void SetMediaTime(base::TimeDelta time) override;
   base::TimeDelta CurrentMediaTime() override;
   base::TimeTicks GetWallClockTime(base::TimeDelta time) override;
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc
index 98782c93..1fe5bdd 100644
--- a/media/renderers/audio_renderer_impl_unittest.cc
+++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -212,7 +212,7 @@
 
   void StartTicking() {
     renderer_->StartTicking();
-    renderer_->SetPlaybackRate(1.0f);
+    renderer_->SetPlaybackRate(1.0);
   }
 
   void StopTicking() { renderer_->StopTicking(); }
@@ -721,18 +721,18 @@
 
   // Rendering hasn't started. Sink should always be paused.
   EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
-  renderer_->SetPlaybackRate(0.0f);
+  renderer_->SetPlaybackRate(0.0);
   EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
-  renderer_->SetPlaybackRate(1.0f);
+  renderer_->SetPlaybackRate(1.0);
   EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
 
   // Rendering has started with non-zero rate. Rate changes will affect sink
   // state.
   renderer_->StartTicking();
   EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
-  renderer_->SetPlaybackRate(0.0f);
+  renderer_->SetPlaybackRate(0.0);
   EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
-  renderer_->SetPlaybackRate(1.0f);
+  renderer_->SetPlaybackRate(1.0);
   EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
 
   // Rendering has stopped. Sink should be paused.
@@ -741,10 +741,10 @@
 
   // Start rendering with zero playback rate. Sink should be paused until
   // non-zero rate is set.
-  renderer_->SetPlaybackRate(0.0f);
+  renderer_->SetPlaybackRate(0.0);
   renderer_->StartTicking();
   EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
-  renderer_->SetPlaybackRate(1.0f);
+  renderer_->SetPlaybackRate(1.0);
   EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
 }
 
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
index 62caf9d8..30eeb4f 100644
--- a/media/renderers/renderer_impl.cc
+++ b/media/renderers/renderer_impl.cc
@@ -35,7 +35,7 @@
       video_renderer_(video_renderer.Pass()),
       time_source_(NULL),
       time_ticking_(false),
-      playback_rate_(0),
+      playback_rate_(0.0),
       audio_buffering_state_(BUFFERING_HAVE_NOTHING),
       video_buffering_state_(BUFFERING_HAVE_NOTHING),
       audio_ended_(false),
@@ -166,7 +166,7 @@
     video_renderer_->StartPlayingFrom(time);
 }
 
-void RendererImpl::SetPlaybackRate(float playback_rate) {
+void RendererImpl::SetPlaybackRate(double playback_rate) {
   DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -176,7 +176,7 @@
 
   time_source_->SetPlaybackRate(playback_rate);
 
-  const float old_rate = playback_rate_;
+  const double old_rate = playback_rate_;
   playback_rate_ = playback_rate;
   if (!time_ticking_ || !video_renderer_)
     return;
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h
index 3f90271c..79118488 100644
--- a/media/renderers/renderer_impl.h
+++ b/media/renderers/renderer_impl.h
@@ -55,7 +55,7 @@
               const CdmAttachedCB& cdm_attached_cb) final;
   void Flush(const base::Closure& flush_cb) final;
   void StartPlayingFrom(base::TimeDelta time) final;
-  void SetPlaybackRate(float playback_rate) final;
+  void SetPlaybackRate(double playback_rate) final;
   void SetVolume(float volume) final;
   base::TimeDelta GetMediaTime() final;
   bool HasAudio() final;
@@ -152,7 +152,7 @@
   TimeSource* time_source_;
   scoped_ptr<WallClockTimeSource> wall_clock_time_source_;
   bool time_ticking_;
-  float playback_rate_;
+  double playback_rate_;
 
   // The time to start playback from after starting/seeking has completed.
   base::TimeDelta start_time_;
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc
index 9fcefe4..df4c8cc 100644
--- a/media/renderers/renderer_impl_unittest.cc
+++ b/media/renderers/renderer_impl_unittest.cc
@@ -217,7 +217,7 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void SetPlaybackRate(float playback_rate) {
+  void SetPlaybackRate(double playback_rate) {
     EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
     renderer_impl_->SetPlaybackRate(playback_rate);
     base::RunLoop().RunUntilIdle();
@@ -227,7 +227,7 @@
     return renderer_impl_->GetMediaTime().InMilliseconds();
   }
 
-  bool IsMediaTimeAdvancing(float playback_rate) {
+  bool IsMediaTimeAdvancing(double playback_rate) {
     int64 start_time_ms = GetMediaTimeMs();
     const int64 time_to_advance_ms = 100;
 
@@ -242,7 +242,7 @@
   }
 
   bool IsMediaTimeAdvancing() {
-    return IsMediaTimeAdvancing(1.0f);
+    return IsMediaTimeAdvancing(1.0);
   }
 
   // Fixture members.
@@ -377,8 +377,8 @@
 
 TEST_F(RendererImplTest, SetPlaybackRate) {
   InitializeWithAudioAndVideo();
-  SetPlaybackRate(1.0f);
-  SetPlaybackRate(2.0f);
+  SetPlaybackRate(1.0);
+  SetPlaybackRate(2.0);
 }
 
 TEST_F(RendererImplTest, SetVolume) {
diff --git a/media/video/capture/fake_video_capture_device.cc b/media/video/capture/fake_video_capture_device.cc
index 4f3a8bb..a2cd37d 100644
--- a/media/video/capture/fake_video_capture_device.cc
+++ b/media/video/capture/fake_video_capture_device.cc
@@ -101,26 +101,25 @@
   else
     capture_format_.frame_size.SetSize(320, 240);
 
-  switch (device_type_) {
-    case USING_OWN_BUFFERS:
-      fake_frame_.reset(new uint8[VideoFrame::AllocationSize(
-          VideoFrame::I420, capture_format_.frame_size)]);
-      BeepAndScheduleNextCapture(
-          base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
-                     weak_factory_.GetWeakPtr()));
-      break;
-    case USING_CLIENT_BUFFERS:
-      BeepAndScheduleNextCapture(
-          base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers,
-                     weak_factory_.GetWeakPtr()));
-      break;
-    case USING_GPU_MEMORY_BUFFERS:
-      BeepAndScheduleNextCapture(
-          base::Bind(&FakeVideoCaptureDevice::CaptureUsingGpuMemoryBuffers,
-                     weak_factory_.GetWeakPtr()));
-      break;
-    default:
-      client_->OnError("Unknown Fake Video Capture Device type.");
+  if (device_type_ == USING_OWN_BUFFERS ||
+      device_type_ == USING_OWN_BUFFERS_TRIPLANAR) {
+    fake_frame_.reset(new uint8[VideoFrame::AllocationSize(
+        VideoFrame::I420, capture_format_.frame_size)]);
+    BeepAndScheduleNextCapture(
+        base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
+                   weak_factory_.GetWeakPtr()));
+  } else if (device_type_ == USING_CLIENT_BUFFERS_I420 ||
+             device_type_ == USING_CLIENT_BUFFERS_GPU) {
+    DVLOG(1) << "starting with " << (device_type_ == USING_CLIENT_BUFFERS_I420
+                                         ? "Client buffers"
+                                         : "GpuMemoryBuffers");
+    BeepAndScheduleNextCapture(base::Bind(
+        &FakeVideoCaptureDevice::CaptureUsingClientBuffers,
+        weak_factory_.GetWeakPtr(), (device_type_ == USING_CLIENT_BUFFERS_I420
+                                         ? PIXEL_FORMAT_I420
+                                         : PIXEL_FORMAT_GPUMEMORYBUFFER)));
+  } else {
+    client_->OnError("Unknown Fake Video Capture Device type.");
   }
 }
 
@@ -131,8 +130,7 @@
 
 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  const size_t frame_size =
-      VideoFrame::AllocationSize(VideoFrame::I420, capture_format_.frame_size);
+  const size_t frame_size = capture_format_.ImageAllocationSize();
   memset(fake_frame_.get(), 0, frame_size);
 
   DrawPacman(false  /* use_argb */,
@@ -142,62 +140,60 @@
              capture_format_.frame_size);
 
   // Give the captured frame to the client.
-  client_->OnIncomingCapturedData(fake_frame_.get(),
-                                  frame_size,
-                                  capture_format_,
-                                  0,
-                                  base::TimeTicks::Now());
+  if (device_type_ == USING_OWN_BUFFERS) {
+    client_->OnIncomingCapturedData(fake_frame_.get(),
+                                    frame_size,
+                                    capture_format_,
+                                    0  /* rotation */,
+                                    base::TimeTicks::Now());
+  } else if (device_type_ == USING_OWN_BUFFERS_TRIPLANAR) {
+    client_->OnIncomingCapturedYuvData(
+        fake_frame_.get(),
+        fake_frame_.get() + capture_format_.frame_size.GetArea(),
+        fake_frame_.get() + capture_format_.frame_size.GetArea() * 5 / 4,
+        capture_format_.frame_size.width(),
+        capture_format_.frame_size.width() / 2,
+        capture_format_.frame_size.width() / 2,
+        capture_format_,
+        0  /* rotation */,
+        base::TimeTicks::Now());
+  }
   BeepAndScheduleNextCapture(
       base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
                  weak_factory_.GetWeakPtr()));
 }
 
-void FakeVideoCaptureDevice::CaptureUsingClientBuffers() {
+void FakeVideoCaptureDevice::CaptureUsingClientBuffers(
+    VideoPixelFormat pixel_format) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  const scoped_refptr<VideoCaptureDevice::Client::Buffer> capture_buffer =
-      client_->ReserveOutputBuffer(capture_format_.pixel_format,
-                                   capture_format_.frame_size);
+  scoped_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer(
+      client_->ReserveOutputBuffer(pixel_format, capture_format_.frame_size));
   DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer";
-  if (!capture_buffer)
-    return;
 
-  uint8_t* const data_ptr = static_cast<uint8_t*>(capture_buffer->data());
-  memset(data_ptr, 0, capture_buffer->size());
-  DCHECK(data_ptr) << "Buffer has NO backing memory";
+  if (capture_buffer.get()) {
+    uint8_t* const data_ptr = static_cast<uint8_t*>(capture_buffer->data());
+    DCHECK(data_ptr) << "Buffer has NO backing memory";
+    memset(data_ptr, 0, capture_buffer->size());
 
-  DrawPacman(false  /* use_argb */,
-             data_ptr,
-             frame_count_,
-             kFakeCapturePeriodMs,
-             capture_format_.frame_size);
+    DrawPacman(
+        (pixel_format == media::PIXEL_FORMAT_GPUMEMORYBUFFER), /* use_argb */
+        data_ptr,
+        frame_count_,
+        kFakeCapturePeriodMs,
+        capture_format_.frame_size);
 
-  scoped_refptr<VideoFrame> video_frame =
-      VideoFrame::WrapExternalPackedMemory(
-          VideoFrame::I420,
-          capture_format_.frame_size,
-          gfx::Rect(capture_format_.frame_size),
-          capture_format_.frame_size,
-          static_cast<uint8*>(capture_buffer->data()),
-          capture_buffer->size(),
-          base::SharedMemory::NULLHandle(),
-          0,
-          base::TimeDelta(),
-          base::Closure());
+    // Give the captured frame to the client.
+    const VideoCaptureFormat format(capture_format_.frame_size,
+                                    capture_format_.frame_rate,
+                                    pixel_format);
+    client_->OnIncomingCapturedBuffer(capture_buffer.Pass(), format,
+                                      base::TimeTicks::Now());
+  }
 
-  // Give the captured frame to the client.
-  client_->OnIncomingCapturedVideoFrame(capture_buffer,
-                                        video_frame,
-                                        base::TimeTicks::Now());
   BeepAndScheduleNextCapture(
       base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers,
-                 weak_factory_.GetWeakPtr()));
-}
-
-void FakeVideoCaptureDevice::CaptureUsingGpuMemoryBuffers() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  NOTIMPLEMENTED();
+                 weak_factory_.GetWeakPtr(), pixel_format));
 }
 
 void FakeVideoCaptureDevice::BeepAndScheduleNextCapture(
diff --git a/media/video/capture/fake_video_capture_device.h b/media/video/capture/fake_video_capture_device.h
index e785ce6..f4a19f9 100644
--- a/media/video/capture/fake_video_capture_device.h
+++ b/media/video/capture/fake_video_capture_device.h
@@ -23,8 +23,9 @@
  public:
   enum FakeVideoCaptureDeviceType {
     USING_OWN_BUFFERS,
-    USING_CLIENT_BUFFERS,
-    USING_GPU_MEMORY_BUFFERS,
+    USING_OWN_BUFFERS_TRIPLANAR,
+    USING_CLIENT_BUFFERS_I420,
+    USING_CLIENT_BUFFERS_GPU,
   };
 
   static int FakeCapturePeriodMs() { return kFakeCapturePeriodMs; }
@@ -41,8 +42,7 @@
   static const int kFakeCapturePeriodMs = 50;
 
   void CaptureUsingOwnBuffers();
-  void CaptureUsingClientBuffers();
-  void CaptureUsingGpuMemoryBuffers();
+  void CaptureUsingClientBuffers(VideoPixelFormat pixel_format);
   void BeepAndScheduleNextCapture(const base::Closure& next_capture);
 
   // |thread_checker_| is used to check that all methods are called in the
diff --git a/media/video/capture/fake_video_capture_device_factory.cc b/media/video/capture/fake_video_capture_device_factory.cc
index aea1909..76de761 100644
--- a/media/video/capture/fake_video_capture_device_factory.cc
+++ b/media/video/capture/fake_video_capture_device_factory.cc
@@ -26,10 +26,12 @@
   FakeVideoCaptureDevice::FakeVideoCaptureDeviceType fake_vcd_type;
   if (option.empty())
     fake_vcd_type = FakeVideoCaptureDevice::USING_OWN_BUFFERS;
+  else if (base:: strcasecmp(option.c_str(), "triplanar") == 0)
+    fake_vcd_type = FakeVideoCaptureDevice::USING_OWN_BUFFERS_TRIPLANAR;
   else if (base:: strcasecmp(option.c_str(), "gpu") == 0)
-    fake_vcd_type = FakeVideoCaptureDevice::USING_GPU_MEMORY_BUFFERS;
+    fake_vcd_type = FakeVideoCaptureDevice::USING_CLIENT_BUFFERS_GPU;
   else
-    fake_vcd_type = FakeVideoCaptureDevice::USING_CLIENT_BUFFERS;
+    fake_vcd_type = FakeVideoCaptureDevice::USING_CLIENT_BUFFERS_I420;
 
   for (int n = 0; n < number_of_devices_; ++n) {
     std::string possible_id = base::StringPrintf("/dev/video%d", n);
@@ -73,9 +75,8 @@
                                        gfx::Size(1920, 1080)};
   supported_formats->clear();
   for (const auto& size : supported_sizes) {
-    supported_formats->push_back(VideoCaptureFormat(size,
-                                                    frame_rate,
-                                                    media::PIXEL_FORMAT_I420));
+    supported_formats->push_back(
+        VideoCaptureFormat(size, frame_rate, media::PIXEL_FORMAT_I420));
   }
 }
 
diff --git a/media/video/capture/fake_video_capture_device_unittest.cc b/media/video/capture/fake_video_capture_device_unittest.cc
index e413c5ed4..e340ae43 100644
--- a/media/video/capture/fake_video_capture_device_unittest.cc
+++ b/media/video/capture/fake_video_capture_device_unittest.cc
@@ -24,25 +24,23 @@
 static const FakeVideoCaptureDevice::FakeVideoCaptureDeviceType
 kCaptureTypes[] = {
   FakeVideoCaptureDevice::USING_OWN_BUFFERS,
-  FakeVideoCaptureDevice::USING_CLIENT_BUFFERS,
-  // TODO(mcasas): Add FakeVideoCaptureDevice::USING_GPU_MEMORY_BUFFERS when
-  // implemented.
+  FakeVideoCaptureDevice::USING_OWN_BUFFERS_TRIPLANAR,
+  FakeVideoCaptureDevice::USING_CLIENT_BUFFERS_I420,
+  FakeVideoCaptureDevice::USING_CLIENT_BUFFERS_GPU,
 };
 
 // This class is a Client::Buffer that allocates and frees the requested |size|.
 class MockBuffer : public VideoCaptureDevice::Client::Buffer {
  public:
   MockBuffer(int buffer_id, size_t size)
-      : id_(buffer_id),
-        size_(size),
-        data_(new uint8[size_]) {}
+      : id_(buffer_id), size_(size), data_(new uint8[size_]) {}
+  ~MockBuffer() override { delete[] data_; }
   int id() const override { return id_; }
-  void* data() const override { return static_cast<void*>(data_); }
   size_t size() const override { return size_; }
+  void* data() override { return data_; }
+  ClientBuffer AsClientBuffer() override { return nullptr; }
 
  private:
-  ~MockBuffer() override { delete[] data_; }
-
   const int id_;
   const size_t size_;
   uint8* const data_;
@@ -50,22 +48,12 @@
 
 class MockClient : public VideoCaptureDevice::Client {
  public:
-  MOCK_METHOD9(OnIncomingCapturedYuvData,
-               void (const uint8* y_data,
-                     const uint8* u_data,
-                     const uint8* v_data,
-                     size_t y_stride,
-                     size_t u_stride,
-                     size_t v_stride,
-                     const VideoCaptureFormat& frame_format,
-                     int clockwise_rotation,
-                     const base::TimeTicks& timestamp));
   MOCK_METHOD1(OnError, void(const std::string& reason));
 
   explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
       : frame_cb_(frame_cb) {}
 
-  // Client virtual method for capturing using Device Buffers.
+  // Client virtual methods for capturing using Device Buffers.
   void OnIncomingCapturedData(const uint8* data,
                               int length,
                               const VideoCaptureFormat& format,
@@ -73,16 +61,35 @@
                               const base::TimeTicks& timestamp) {
     frame_cb_.Run(format);
   }
+  void OnIncomingCapturedYuvData(const uint8* y_data,
+                                 const uint8* u_data,
+                                 const uint8* v_data,
+                                 size_t y_stride,
+                                 size_t u_stride,
+                                 size_t v_stride,
+                                 const VideoCaptureFormat& frame_format,
+                                 int clockwise_rotation,
+                                 const base::TimeTicks& timestamp) {
+    frame_cb_.Run(frame_format);
+  }
 
   // Virtual methods for capturing using Client's Buffers.
-  scoped_refptr<Buffer> ReserveOutputBuffer(media::VideoPixelFormat format,
-                                            const gfx::Size& dimensions) {
-    EXPECT_EQ(format, PIXEL_FORMAT_I420);
+  scoped_ptr<Buffer> ReserveOutputBuffer(media::VideoPixelFormat format,
+                                         const gfx::Size& dimensions) {
+    EXPECT_TRUE(format == PIXEL_FORMAT_I420 ||
+                format == PIXEL_FORMAT_GPUMEMORYBUFFER);
     EXPECT_GT(dimensions.GetArea(), 0);
-    return make_scoped_refptr(new MockBuffer(0, dimensions.GetArea() * 3 / 2));
+    const VideoCaptureFormat frame_format(dimensions, 0.0, format);
+    return make_scoped_ptr(
+        new MockBuffer(0, frame_format.ImageAllocationSize()));
+  }
+  void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer,
+                                const VideoCaptureFormat& frame_format,
+                                const base::TimeTicks& timestamp) {
+    frame_cb_.Run(frame_format);
   }
   void OnIncomingCapturedVideoFrame(
-      const scoped_refptr<Buffer>& buffer,
+      scoped_ptr<Buffer> buffer,
       const scoped_refptr<media::VideoFrame>& frame,
       const base::TimeTicks& timestamp) {
     VideoCaptureFormat format(frame->natural_size(), 30.0, PIXEL_FORMAT_I420);
@@ -125,8 +132,6 @@
   }
 
   void SetUp() override {
-    EXPECT_CALL(*client_, OnIncomingCapturedYuvData(_,_,_,_,_,_,_,_,_))
-               .Times(0);
     EXPECT_CALL(*client_, OnError(_)).Times(0);
   }
 
diff --git a/media/video/capture/video_capture_device.cc b/media/video/capture/video_capture_device.cc
index 1eb205a..44442c4 100644
--- a/media/video/capture/video_capture_device.cc
+++ b/media/video/capture/video_capture_device.cc
@@ -128,6 +128,8 @@
 }
 #endif
 
+VideoCaptureDevice::Client::Buffer::~Buffer() {}
+
 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 e5e42f8..d3dfe72 100644
--- a/media/video/capture/video_capture_device.h
+++ b/media/video/capture/video_capture_device.h
@@ -23,6 +23,7 @@
 #include "media/base/media_export.h"
 #include "media/base/video_capture_types.h"
 #include "media/base/video_frame.h"
+#include "ui/gfx/gpu_memory_buffer.h"
 
 namespace media {
 
@@ -195,15 +196,13 @@
    class MEDIA_EXPORT Client {
    public:
     // Memory buffer returned by Client::ReserveOutputBuffer().
-    class Buffer : public base::RefCountedThreadSafe<Buffer> {
+    class MEDIA_EXPORT Buffer {
      public:
+      virtual ~Buffer() = 0;
       virtual int id() const = 0;
-      virtual void* data() const = 0;
       virtual size_t size() const = 0;
-
-     protected:
-      friend class base::RefCountedThreadSafe<Buffer>;
-      virtual ~Buffer() {}
+      virtual void* data() = 0;
+      virtual ClientBuffer AsClientBuffer() = 0;
     };
 
     virtual ~Client() {}
@@ -241,20 +240,25 @@
     // backing, but functions as a reservation for external input for the
     // purposes of buffer throttling.
     //
-    // The output buffer stays reserved for use until the Buffer object is
-    // destroyed.
-    virtual scoped_refptr<Buffer> ReserveOutputBuffer(
+    // The output buffer stays reserved and mapped for use until the Buffer
+    // object is destroyed or returned.
+    virtual scoped_ptr<Buffer> ReserveOutputBuffer(
         media::VideoPixelFormat format,
         const gfx::Size& dimensions) = 0;
 
-    // Captured a new video frame, held in |frame|.
+    // Captured new video data, held in |frame| or |buffer|, respectively for
+    // OnIncomingCapturedVideoFrame() and  OnIncomingCapturedBuffer().
     //
-    // As the frame is backed by a reservation returned by
+    // In both cases, as the frame is backed by a reservation returned by
     // ReserveOutputBuffer(), delivery is guaranteed and will require no
     // additional copies in the browser process.
+    virtual void OnIncomingCapturedBuffer(
+        scoped_ptr<Buffer> buffer,
+        const VideoCaptureFormat& frame_format,
+        const base::TimeTicks& timestamp) = 0;
     virtual void OnIncomingCapturedVideoFrame(
-        const scoped_refptr<Buffer>& buffer,
-        const scoped_refptr<media::VideoFrame>& frame,
+        scoped_ptr<Buffer> buffer,
+        const scoped_refptr<VideoFrame>& frame,
         const base::TimeTicks& timestamp) = 0;
 
     // An error has occurred that cannot be handled and VideoCaptureDevice must
diff --git a/media/video/capture/video_capture_device_unittest.cc b/media/video/capture/video_capture_device_unittest.cc
index a01fbab9..961957f1 100644
--- a/media/video/capture/video_capture_device_unittest.cc
+++ b/media/video/capture/video_capture_device_unittest.cc
@@ -64,23 +64,19 @@
 
 class MockClient : public VideoCaptureDevice::Client {
  public:
-  MOCK_METHOD2(ReserveOutputBuffer,
-               scoped_refptr<Buffer>(media::VideoPixelFormat format,
-                 const gfx::Size& dimensions));
   MOCK_METHOD9(OnIncomingCapturedYuvData,
-               void (const uint8* y_data,
-                     const uint8* u_data,
-                     const uint8* v_data,
-                     size_t y_stride,
-                     size_t u_stride,
-                     size_t v_stride,
-                     const VideoCaptureFormat& frame_format,
-                     int clockwise_rotation,
-                     const base::TimeTicks& timestamp));
-  MOCK_METHOD3(OnIncomingCapturedVideoFrame,
-               void(const scoped_refptr<Buffer>& buffer,
-                    const scoped_refptr<VideoFrame>& frame,
+               void(const uint8* y_data,
+                    const uint8* u_data,
+                    const uint8* v_data,
+                    size_t y_stride,
+                    size_t u_stride,
+                    size_t v_stride,
+                    const VideoCaptureFormat& frame_format,
+                    int clockwise_rotation,
                     const base::TimeTicks& timestamp));
+  MOCK_METHOD0(DoReserveOutputBuffer, void(void));
+  MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
+  MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
   MOCK_METHOD1(OnError, void(const std::string& reason));
 
   explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
@@ -96,6 +92,23 @@
     main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format));
   }
 
+  // Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
+  scoped_ptr<Buffer> ReserveOutputBuffer(VideoPixelFormat format,
+                                         const gfx::Size& dimensions) override {
+    DoReserveOutputBuffer();
+    return scoped_ptr<Buffer>();
+  }
+  void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer,
+                                const VideoCaptureFormat& frame_format,
+                                const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedBuffer();
+  }
+  void OnIncomingCapturedVideoFrame(scoped_ptr<Buffer> buffer,
+                                    const scoped_refptr<VideoFrame>& frame,
+                                    const base::TimeTicks& timestamp) override {
+    DoOnIncomingCapturedVideoFrame();
+  }
+
  private:
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
   base::Callback<void(const VideoCaptureFormat&)> frame_cb_;
@@ -139,8 +152,9 @@
 #endif
     EXPECT_CALL(*client_, OnIncomingCapturedYuvData(_,_,_,_,_,_,_,_,_))
                .Times(0);
-    EXPECT_CALL(*client_, ReserveOutputBuffer(_,_)).Times(0);
-    EXPECT_CALL(*client_, OnIncomingCapturedVideoFrame(_,_,_)).Times(0);
+    EXPECT_CALL(*client_, DoReserveOutputBuffer()).Times(0);
+    EXPECT_CALL(*client_, DoOnIncomingCapturedBuffer()).Times(0);
+    EXPECT_CALL(*client_, DoOnIncomingCapturedVideoFrame()).Times(0);
   }
 
   void ResetWithNewClient() {
diff --git a/media/video/capture/win/filter_base_win.cc b/media/video/capture/win/filter_base_win.cc
index 96709d5..1c3e24e 100644
--- a/media/video/capture/win/filter_base_win.cc
+++ b/media/video/capture/win/filter_base_win.cc
@@ -22,7 +22,7 @@
   }
 
   // IUnknown implementation.
-  STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) {
+  STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) override {
     if (iid == IID_IEnumPins || iid == IID_IUnknown) {
       AddRef();
       *object_ptr = static_cast<IEnumPins*>(this);
@@ -31,18 +31,18 @@
     return E_NOINTERFACE;
   }
 
-  STDMETHOD_(ULONG, AddRef)() {
+  STDMETHOD_(ULONG, AddRef)() override {
     base::RefCounted<PinEnumerator>::AddRef();
     return 1;
   }
 
-  STDMETHOD_(ULONG, Release)() {
+  STDMETHOD_(ULONG, Release)() override {
     base::RefCounted<PinEnumerator>::Release();
     return 1;
   }
 
   // Implement IEnumPins.
-  STDMETHOD(Next)(ULONG count, IPin** pins, ULONG* fetched) {
+  STDMETHOD(Next)(ULONG count, IPin** pins, ULONG* fetched) override {
     ULONG pins_fetched = 0;
     while (pins_fetched < count && filter_->NoOfPins() > index_) {
       IPin* pin = filter_->GetPin(index_++);
@@ -56,7 +56,7 @@
     return pins_fetched == count ? S_OK : S_FALSE;
   }
 
-  STDMETHOD(Skip)(ULONG count) {
+  STDMETHOD(Skip)(ULONG count) override {
     if (filter_->NoOfPins()- index_ > count) {
       index_ += count;
       return S_OK;
@@ -65,12 +65,12 @@
     return S_FALSE;
   }
 
-  STDMETHOD(Reset)() {
+  STDMETHOD(Reset)() override {
     index_ = 0;
     return S_OK;
   }
 
-  STDMETHOD(Clone)(IEnumPins** clone) {
+  STDMETHOD(Clone)(IEnumPins** clone) override {
     PinEnumerator* pin_enum = new PinEnumerator(filter_.get());
     pin_enum->AddRef();
     pin_enum->index_ = index_;
diff --git a/media/video/capture/win/filter_base_win.h b/media/video/capture/win/filter_base_win.h
index 9d5aa76f..e490f421 100644
--- a/media/video/capture/win/filter_base_win.h
+++ b/media/video/capture/win/filter_base_win.h
@@ -30,36 +30,36 @@
   virtual IPin* GetPin(int index) = 0;
 
   // Inherited from IUnknown.
-  STDMETHOD(QueryInterface)(REFIID id, void** object_ptr);
-  STDMETHOD_(ULONG, AddRef)();
-  STDMETHOD_(ULONG, Release)();
+  STDMETHOD(QueryInterface)(REFIID id, void** object_ptr) override;
+  STDMETHOD_(ULONG, AddRef)() override;
+  STDMETHOD_(ULONG, Release)() override;
 
   // Inherited from IBaseFilter.
-  STDMETHOD(EnumPins)(IEnumPins** enum_pins);
+  STDMETHOD(EnumPins)(IEnumPins** enum_pins) override;
 
-  STDMETHOD(FindPin)(LPCWSTR id, IPin** pin);
+  STDMETHOD(FindPin)(LPCWSTR id, IPin** pin) override;
 
-  STDMETHOD(QueryFilterInfo)(FILTER_INFO* info);
+  STDMETHOD(QueryFilterInfo)(FILTER_INFO* info) override;
 
-  STDMETHOD(JoinFilterGraph)(IFilterGraph* graph, LPCWSTR name);
+  STDMETHOD(JoinFilterGraph)(IFilterGraph* graph, LPCWSTR name) override;
 
-  STDMETHOD(QueryVendorInfo)(LPWSTR* vendor_info);
+  STDMETHOD(QueryVendorInfo)(LPWSTR* vendor_info) override;
 
   // Inherited from IMediaFilter.
-  STDMETHOD(Stop)();
+  STDMETHOD(Stop)() override;
 
-  STDMETHOD(Pause)();
+  STDMETHOD(Pause)() override;
 
-  STDMETHOD(Run)(REFERENCE_TIME start);
+  STDMETHOD(Run)(REFERENCE_TIME start) override;
 
-  STDMETHOD(GetState)(DWORD msec_timeout, FILTER_STATE* state);
+  STDMETHOD(GetState)(DWORD msec_timeout, FILTER_STATE* state) override;
 
-  STDMETHOD(SetSyncSource)(IReferenceClock* clock);
+  STDMETHOD(SetSyncSource)(IReferenceClock* clock) override;
 
-  STDMETHOD(GetSyncSource)(IReferenceClock** clock);
+  STDMETHOD(GetSyncSource)(IReferenceClock** clock) override;
 
   // Inherited from IPersistent.
-  STDMETHOD(GetClassID)(CLSID* class_id) = 0;
+  STDMETHOD(GetClassID)(CLSID* class_id) override = 0;
 
  private:
   FILTER_STATE state_;
diff --git a/media/video/capture/win/pin_base_win.cc b/media/video/capture/win/pin_base_win.cc
index 92453c18..d2efa8b 100644
--- a/media/video/capture/win/pin_base_win.cc
+++ b/media/video/capture/win/pin_base_win.cc
@@ -22,7 +22,7 @@
   }
 
   // Implement from IUnknown.
-  STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) {
+  STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) override {
     if (iid == IID_IEnumMediaTypes || iid == IID_IUnknown) {
       AddRef();
       *object_ptr = static_cast<IEnumMediaTypes*>(this);
@@ -31,18 +31,18 @@
     return E_NOINTERFACE;
   }
 
-  STDMETHOD_(ULONG, AddRef)() {
+  STDMETHOD_(ULONG, AddRef)() override {
     base::RefCounted<TypeEnumerator>::AddRef();
     return 1;
   }
 
-  STDMETHOD_(ULONG, Release)() {
+  STDMETHOD_(ULONG, Release)() override {
     base::RefCounted<TypeEnumerator>::Release();
     return 1;
   }
 
   // Implement IEnumMediaTypes.
-  STDMETHOD(Next)(ULONG count, AM_MEDIA_TYPE** types, ULONG* fetched) {
+  STDMETHOD(Next)(ULONG count, AM_MEDIA_TYPE** types, ULONG* fetched) override {
     ULONG types_fetched = 0;
 
     while (types_fetched < count) {
@@ -81,17 +81,17 @@
     return types_fetched == count ? S_OK : S_FALSE;
   }
 
-  STDMETHOD(Skip)(ULONG count) {
+  STDMETHOD(Skip)(ULONG count) override {
     index_ += count;
     return S_OK;
   }
 
-  STDMETHOD(Reset)() {
+  STDMETHOD(Reset)() override {
     index_ = 0;
     return S_OK;
   }
 
-  STDMETHOD(Clone)(IEnumMediaTypes** clone) {
+  STDMETHOD(Clone)(IEnumMediaTypes** clone) override {
     TypeEnumerator* type_enum = new TypeEnumerator(pin_.get());
     type_enum->AddRef();
     type_enum->index_ = index_;
diff --git a/media/video/capture/win/pin_base_win.h b/media/video/capture/win/pin_base_win.h
index 33f403f..7ad5436 100644
--- a/media/video/capture/win/pin_base_win.h
+++ b/media/video/capture/win/pin_base_win.h
@@ -40,59 +40,61 @@
 
   // Called when new media is received. Note that this is not on the same
   // thread as where the pin is created.
-  STDMETHOD(Receive)(IMediaSample* sample) = 0;
+  STDMETHOD(Receive)(IMediaSample* sample) override = 0;
 
-  STDMETHOD(Connect)(IPin* receive_pin, const AM_MEDIA_TYPE* media_type);
+  STDMETHOD(Connect)(IPin* receive_pin,
+                     const AM_MEDIA_TYPE* media_type) override;
 
   STDMETHOD(ReceiveConnection)(IPin* connector,
-                               const AM_MEDIA_TYPE* media_type);
+                               const AM_MEDIA_TYPE* media_type) override;
 
-  STDMETHOD(Disconnect)();
+  STDMETHOD(Disconnect)() override;
 
-  STDMETHOD(ConnectedTo)(IPin** pin);
+  STDMETHOD(ConnectedTo)(IPin** pin) override;
 
-  STDMETHOD(ConnectionMediaType)(AM_MEDIA_TYPE* media_type);
+  STDMETHOD(ConnectionMediaType)(AM_MEDIA_TYPE* media_type) override;
 
-  STDMETHOD(QueryPinInfo)(PIN_INFO* info);
+  STDMETHOD(QueryPinInfo)(PIN_INFO* info) override;
 
-  STDMETHOD(QueryDirection)(PIN_DIRECTION* pin_dir);
+  STDMETHOD(QueryDirection)(PIN_DIRECTION* pin_dir) override;
 
-  STDMETHOD(QueryId)(LPWSTR* id);
+  STDMETHOD(QueryId)(LPWSTR* id) override;
 
-  STDMETHOD(QueryAccept)(const AM_MEDIA_TYPE* media_type);
+  STDMETHOD(QueryAccept)(const AM_MEDIA_TYPE* media_type) override;
 
-  STDMETHOD(EnumMediaTypes)(IEnumMediaTypes** types);
+  STDMETHOD(EnumMediaTypes)(IEnumMediaTypes** types) override;
 
-  STDMETHOD(QueryInternalConnections)(IPin** pins, ULONG* no_pins);
+  STDMETHOD(QueryInternalConnections)(IPin** pins, ULONG* no_pins) override;
 
-  STDMETHOD(EndOfStream)();
+  STDMETHOD(EndOfStream)() override;
 
-  STDMETHOD(BeginFlush)();
+  STDMETHOD(BeginFlush)() override;
 
-  STDMETHOD(EndFlush)();
+  STDMETHOD(EndFlush)() override;
 
   STDMETHOD(NewSegment)(REFERENCE_TIME start,
                         REFERENCE_TIME stop,
-                        double dRate);
+                        double dRate) override;
 
   // Inherited from IMemInputPin.
-  STDMETHOD(GetAllocator)(IMemAllocator** allocator);
+  STDMETHOD(GetAllocator)(IMemAllocator** allocator) override;
 
-  STDMETHOD(NotifyAllocator)(IMemAllocator* allocator, BOOL read_only);
+  STDMETHOD(NotifyAllocator)(IMemAllocator* allocator, BOOL read_only) override;
 
-  STDMETHOD(GetAllocatorRequirements)(ALLOCATOR_PROPERTIES* properties);
+  STDMETHOD(GetAllocatorRequirements)(
+      ALLOCATOR_PROPERTIES* properties) override;
 
   STDMETHOD(ReceiveMultiple)(IMediaSample** samples,
                              long sample_count,
-                             long* processed);
-  STDMETHOD(ReceiveCanBlock)();
+                             long* processed) override;
+  STDMETHOD(ReceiveCanBlock)() override;
 
   // Inherited from IUnknown.
-  STDMETHOD(QueryInterface)(REFIID id, void** object_ptr);
+  STDMETHOD(QueryInterface)(REFIID id, void** object_ptr) override;
 
-  STDMETHOD_(ULONG, AddRef)();
+  STDMETHOD_(ULONG, AddRef)() override;
 
-  STDMETHOD_(ULONG, Release)();
+  STDMETHOD_(ULONG, Release)() override;
 
  private:
   AM_MEDIA_TYPE current_media_type_;
diff --git a/media/video/capture/win/sink_filter_win.h b/media/video/capture/win/sink_filter_win.h
index 831fd48..f9ff0c9 100644
--- a/media/video/capture/win/sink_filter_win.h
+++ b/media/video/capture/win/sink_filter_win.h
@@ -35,7 +35,7 @@
     SinkFilter : public FilterBase {
  public:
   explicit SinkFilter(SinkFilterObserver* observer);
-  virtual ~SinkFilter();
+  ~SinkFilter() override;
 
   void SetRequestedMediaFormat(VideoPixelFormat pixel_format,
                                float frame_rate,
@@ -45,10 +45,10 @@
   const VideoCaptureFormat& ResultingFormat();
 
   // Implement FilterBase.
-  virtual size_t NoOfPins();
-  virtual IPin* GetPin(int index);
+  size_t NoOfPins() override;
+  IPin* GetPin(int index) override;
 
-  STDMETHOD(GetClassID)(CLSID* clsid);
+  STDMETHOD(GetClassID)(CLSID* clsid) override;
 
  private:
   scoped_refptr<SinkInputPin> input_pin_;
diff --git a/media/video/capture/win/sink_input_pin_win.h b/media/video/capture/win/sink_input_pin_win.h
index ffe5245..1ee23a9 100644
--- a/media/video/capture/win/sink_input_pin_win.h
+++ b/media/video/capture/win/sink_input_pin_win.h
@@ -22,7 +22,7 @@
 class SinkInputPin : public PinBase {
  public:
   SinkInputPin(IBaseFilter* filter, SinkFilterObserver* observer);
-  virtual ~SinkInputPin();
+  ~SinkInputPin() override;
 
   void SetRequestedMediaFormat(VideoPixelFormat pixel_format,
                                float frame_rate,
@@ -32,10 +32,10 @@
   const VideoCaptureFormat& ResultingFormat();
 
   // Implement PinBase.
-  virtual bool IsMediaTypeValid(const AM_MEDIA_TYPE* media_type);
-  virtual bool GetValidMediaType(int index, AM_MEDIA_TYPE* media_type);
+  bool IsMediaTypeValid(const AM_MEDIA_TYPE* media_type) override;
+  bool GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) override;
 
-  STDMETHOD(Receive)(IMediaSample* media_sample);
+  STDMETHOD(Receive)(IMediaSample* media_sample) override;
 
  private:
   VideoPixelFormat requested_pixel_format_;
diff --git a/media/video/capture/win/video_capture_device_factory_win.h b/media/video/capture/win/video_capture_device_factory_win.h
index 849e1ad4..f76fe63 100644
--- a/media/video/capture/win/video_capture_device_factory_win.h
+++ b/media/video/capture/win/video_capture_device_factory_win.h
@@ -19,12 +19,12 @@
   static bool PlatformSupportsMediaFoundation();
 
   VideoCaptureDeviceFactoryWin();
-  virtual ~VideoCaptureDeviceFactoryWin() {}
+  ~VideoCaptureDeviceFactoryWin() override {}
 
-  virtual scoped_ptr<VideoCaptureDevice> Create(
+  scoped_ptr<VideoCaptureDevice> Create(
       const VideoCaptureDevice::Name& device_name) override;
-  virtual void GetDeviceNames(VideoCaptureDevice::Names* device_names) override;
-  virtual void GetDeviceSupportedFormats(
+  void GetDeviceNames(VideoCaptureDevice::Names* device_names) override;
+  void GetDeviceSupportedFormats(
       const VideoCaptureDevice::Name& device,
       VideoCaptureFormats* supported_formats) override;
 
diff --git a/media/video/capture/win/video_capture_device_mf_win.cc b/media/video/capture/win/video_capture_device_mf_win.cc
index 3d3fb160..95ade71 100644
--- a/media/video/capture/win/video_capture_device_mf_win.cc
+++ b/media/video/capture/win/video_capture_device_mf_win.cc
@@ -91,7 +91,7 @@
     wait_event_ = event;
   }
 
-  STDMETHOD(QueryInterface)(REFIID riid, void** object) {
+  STDMETHOD(QueryInterface)(REFIID riid, void** object) override {
     if (riid != IID_IUnknown && riid != IID_IMFSourceReaderCallback)
       return E_NOINTERFACE;
     *object = static_cast<IMFSourceReaderCallback*>(this);
@@ -99,18 +99,21 @@
     return S_OK;
   }
 
-  STDMETHOD_(ULONG, AddRef)() {
+  STDMETHOD_(ULONG, AddRef)() override {
     base::RefCountedThreadSafe<MFReaderCallback>::AddRef();
     return 1U;
   }
 
-  STDMETHOD_(ULONG, Release)() {
+  STDMETHOD_(ULONG, Release)() override {
     base::RefCountedThreadSafe<MFReaderCallback>::Release();
     return 1U;
   }
 
-  STDMETHOD(OnReadSample)(HRESULT status, DWORD stream_index,
-      DWORD stream_flags, LONGLONG time_stamp, IMFSample* sample) {
+  STDMETHOD(OnReadSample)(HRESULT status,
+                          DWORD stream_index,
+                          DWORD stream_flags,
+                          LONGLONG time_stamp,
+                          IMFSample* sample) override {
     base::TimeTicks stamp(base::TimeTicks::Now());
     if (!sample) {
       observer_->OnIncomingCapturedData(NULL, 0, 0, stamp);
@@ -134,7 +137,7 @@
     return S_OK;
   }
 
-  STDMETHOD(OnFlush)(DWORD stream_index) {
+  STDMETHOD(OnFlush)(DWORD stream_index) override {
     if (wait_event_) {
       wait_event_->Signal();
       wait_event_ = NULL;
@@ -142,7 +145,7 @@
     return S_OK;
   }
 
-  STDMETHOD(OnEvent)(DWORD stream_index, IMFMediaEvent* event) {
+  STDMETHOD(OnEvent)(DWORD stream_index, IMFMediaEvent* event) override {
     NOTIMPLEMENTED();
     return S_OK;
   }
diff --git a/media/video/capture/win/video_capture_device_mf_win.h b/media/video/capture/win/video_capture_device_mf_win.h
index fc11d19..eeb7edf 100644
--- a/media/video/capture/win/video_capture_device_mf_win.h
+++ b/media/video/capture/win/video_capture_device_mf_win.h
@@ -36,16 +36,15 @@
   static bool FormatFromGuid(const GUID& guid, VideoPixelFormat* format);
 
   explicit VideoCaptureDeviceMFWin(const Name& device_name);
-  virtual ~VideoCaptureDeviceMFWin();
+  ~VideoCaptureDeviceMFWin() override;
 
   // Opens the device driver for this device.
   bool Init(const base::win::ScopedComPtr<IMFMediaSource>& source);
 
   // VideoCaptureDevice implementation.
-  virtual void AllocateAndStart(const VideoCaptureParams& params,
-                                scoped_ptr<VideoCaptureDevice::Client> client)
-      override;
-  virtual void StopAndDeAllocate() override;
+  void AllocateAndStart(const VideoCaptureParams& params,
+                        scoped_ptr<VideoCaptureDevice::Client> client) override;
+  void StopAndDeAllocate() override;
 
   // Captured new video data.
   void OnIncomingCapturedData(const uint8* data,
diff --git a/media/video/capture/win/video_capture_device_win.h b/media/video/capture/win/video_capture_device_win.h
index f758c2c..9315754f 100644
--- a/media/video/capture/win/video_capture_device_win.h
+++ b/media/video/capture/win/video_capture_device_win.h
@@ -64,15 +64,14 @@
       const GUID& sub_type);
 
   explicit VideoCaptureDeviceWin(const Name& device_name);
-  virtual ~VideoCaptureDeviceWin();
+  ~VideoCaptureDeviceWin() override;
   // Opens the device driver for this device.
   bool Init();
 
   // VideoCaptureDevice implementation.
-  virtual void AllocateAndStart(
-      const VideoCaptureParams& params,
-      scoped_ptr<VideoCaptureDevice::Client> client) override;
-  virtual void StopAndDeAllocate() override;
+  void AllocateAndStart(const VideoCaptureParams& params,
+                        scoped_ptr<VideoCaptureDevice::Client> client) override;
+  void StopAndDeAllocate() override;
 
  private:
   enum InternalState {
@@ -83,7 +82,7 @@
   };
 
   // Implements SinkFilterObserver.
-  virtual void FrameReceived(const uint8* buffer, int length);
+  void FrameReceived(const uint8* buffer, int length) override;
 
   bool CreateCapabilityMap();
   void SetAntiFlickerInCaptureFilter();
diff --git a/mojo/application/application_test_main_chromium.cc b/mojo/application/application_test_main_chromium.cc
index 3d6c4b2..6b21abe 100644
--- a/mojo/application/application_test_main_chromium.cc
+++ b/mojo/application/application_test_main_chromium.cc
@@ -13,8 +13,7 @@
   // An AtExitManager instance is needed to construct message loops.
   base::AtExitManager at_exit;
 
-  // Initialize test timeouts, which requires CommandLine::ForCurrentProcess().
-  // TODO(msw): Plumb relevant command line args before initializing timeouts.
+  // Initialize the current process Commandline and test timeouts.
   mojo::ApplicationRunnerChromium::InitBaseCommandLine();
   TestTimeouts::Initialize();
 
diff --git a/mojo/converters/surfaces/surfaces_type_converters.cc b/mojo/converters/surfaces/surfaces_type_converters.cc
index 3874e6a7..f922ebf9 100644
--- a/mojo/converters/surfaces/surfaces_type_converters.cc
+++ b/mojo/converters/surfaces/surfaces_type_converters.cc
@@ -363,7 +363,7 @@
 PassPtr TypeConverter<PassPtr, cc::RenderPass>::Convert(
     const cc::RenderPass& input) {
   PassPtr pass = Pass::New();
-  pass->id = input.id.index;
+  pass->id = RenderPassId::From(input.id);
   pass->output_rect = Rect::From(input.output_rect);
   pass->damage_rect = Rect::From(input.damage_rect);
   pass->transform_to_root_target =
@@ -402,7 +402,7 @@
     const PassPtr& input) {
   scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create(
       input->shared_quad_states.size(), input->quads.size());
-  pass->SetAll(cc::RenderPassId(1, input->id),
+  pass->SetAll(input->id.To<cc::RenderPassId>(),
                input->output_rect.To<gfx::Rect>(),
                input->damage_rect.To<gfx::Rect>(),
                input->transform_to_root_target.To<gfx::Transform>(),
diff --git a/mojo/converters/surfaces/surfaces_utils.cc b/mojo/converters/surfaces/surfaces_utils.cc
index 7853863a..b433722a 100644
--- a/mojo/converters/surfaces/surfaces_utils.cc
+++ b/mojo/converters/surfaces/surfaces_utils.cc
@@ -27,7 +27,10 @@
 
 PassPtr CreateDefaultPass(int id, const gfx::Rect& rect) {
   PassPtr pass = Pass::New();
-  pass->id = id;
+  RenderPassId render_pass_id;
+  render_pass_id.layer_id = 1;
+  render_pass_id.index = id;
+  pass->id = render_pass_id.Clone();
   pass->output_rect = Rect::From(rect);
   pass->damage_rect = Rect::From(rect);
   pass->transform_to_root_target = Transform::From(gfx::Transform());
diff --git a/mojo/converters/surfaces/tests/surface_unittest.cc b/mojo/converters/surfaces/tests/surface_unittest.cc
index 10e1b41..465bee3 100644
--- a/mojo/converters/surfaces/tests/surface_unittest.cc
+++ b/mojo/converters/surfaces/tests/surface_unittest.cc
@@ -287,7 +287,7 @@
 
   PassPtr mojo_pass = Pass::From(*pass);
   ASSERT_FALSE(mojo_pass.is_null());
-  EXPECT_EQ(6, mojo_pass->id);
+  EXPECT_EQ(6, mojo_pass->id->index);
   EXPECT_EQ(Rect::From(output_rect), mojo_pass->output_rect);
   EXPECT_EQ(Rect::From(damage_rect), mojo_pass->damage_rect);
   EXPECT_EQ(Transform::From(transform_to_root_target),
diff --git a/mojo/mojo_nacl_untrusted.gyp b/mojo/mojo_nacl_untrusted.gyp
index eeca34221..4054b32 100644
--- a/mojo/mojo_nacl_untrusted.gyp
+++ b/mojo/mojo_nacl_untrusted.gyp
@@ -24,7 +24,6 @@
             '<(monacl_codegen_dir)/libmojo.cc',
           ],
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
             'mojo_nacl.gyp:monacl_codegen',
             '../third_party/mojo/mojo_public.gyp:mojo_system_placeholder',
           ],
@@ -44,7 +43,6 @@
             '<(monacl_codegen_dir)/mojo_irt.h',
           ],
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
             'mojo_nacl.gyp:monacl_codegen',
           ],
           'direct_dependent_settings': {
@@ -71,7 +69,6 @@
             ],
           },
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
             '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:nacl_lib',
             '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:imc_syscalls_lib',
             '<(DEPTH)/native_client/src/untrusted/pthread/pthread.gyp:pthread_lib',
diff --git a/mojo/services/BUILD.gn b/mojo/services/BUILD.gn
index 304ef92..455e190 100644
--- a/mojo/services/BUILD.gn
+++ b/mojo/services/BUILD.gn
@@ -20,12 +20,12 @@
   if (!is_component_build) {
     deps += [
       "//components/clipboard",
+      "//components/html_viewer",
       "//components/kiosk_wm:window_manager",
       "//components/native_viewport",
       "//components/surfaces",
       "//components/view_manager",
       "//components/window_manager:lib",
-      "//mojo/services/html_viewer",
       "//mojo/services/network",
       "//mojo/services/tracing",
     ]
@@ -33,11 +33,11 @@
     # TODO(GYP): Make this work.
     if (is_mac) {
       deps -= [
+        "//components/html_viewer",
         "//components/kiosk_wm:window_manager",
         "//components/native_viewport",
         "//components/view_manager",
         "//components/window_manager:lib",
-        "//mojo/services/html_viewer",
       ]
     }
   }
@@ -50,17 +50,17 @@
   ]
   if (!is_component_build) {
     deps += [
+      "//components/html_viewer:tests",
       "//components/view_manager:view_manager_service_unittests",
       "//components/window_manager:window_manager_unittests",
-      "//mojo/services/html_viewer:tests",
     ]
 
     # TODO(GYP): Make this work.
     if (is_mac) {
       deps -= [
+        "//components/html_viewer:tests",
         "//components/view_manager:view_manager_service_unittests",
         "//components/window_manager:window_manager_unittests",
-        "//mojo/services/html_viewer:tests",
       ]
     }
   }
@@ -74,18 +74,18 @@
   if (!is_component_build) {
     deps += [
       "//components/clipboard:apptests",
+      "//components/html_viewer:apptests",
       "//components/view_manager:apptests",
       "//components/window_manager:apptests",
-      "//mojo/services/html_viewer:apptests",
       "//mojo/services/network:apptests",
     ]
 
     # TODO(GYP): Make this work.
     if (is_mac) {
       deps -= [
+        "//components/html_viewer:apptests",
         "//components/view_manager:apptests",
         "//components/window_manager:apptests",
-        "//mojo/services/html_viewer:apptests",
       ]
     }
   }
diff --git a/mojo/services/network/public/interfaces/url_loader.mojom b/mojo/services/network/public/interfaces/url_loader.mojom
index 10f0af3..77db3ad 100644
--- a/mojo/services/network/public/interfaces/url_loader.mojom
+++ b/mojo/services/network/public/interfaces/url_loader.mojom
@@ -34,6 +34,9 @@
   // servers to also not satisfy the request from their cache.  This has the
   // effect of forcing a full end-to-end fetch.
   bool bypass_cache = false;
+
+  // The referrer request header.
+  string? referrer;
 };
 
 struct URLResponse {
@@ -67,6 +70,7 @@
   // follow this redirect.
   string? redirect_method;
   string? redirect_url;
+  string? redirect_referrer;
 };
 
 struct URLLoaderStatus {
diff --git a/mojo/services/network/url_loader_impl.cc b/mojo/services/network/url_loader_impl.cc
index 964f9c2..467cc3fa 100644
--- a/mojo/services/network/url_loader_impl.cc
+++ b/mojo/services/network/url_loader_impl.cc
@@ -129,6 +129,10 @@
   url_request_ = context_->url_request_context()->CreateRequest(
       GURL(request->url), net::DEFAULT_PRIORITY, this);
   url_request_->set_method(request->method);
+  url_request_->SetReferrer(request->referrer);
+  // TODO(jam): need to specify this policy.
+  url_request_->set_referrer_policy(
+      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE);
   if (request->headers) {
     net::HttpRequestHeaders headers;
     for (size_t i = 0; i < request->headers.size(); ++i)
@@ -207,6 +211,7 @@
   URLResponsePtr response = MakeURLResponse(url_request);
   response->redirect_method = redirect_info.new_method;
   response->redirect_url = String::From(redirect_info.new_url);
+  response->redirect_referrer = redirect_info.new_referrer;
 
   SendResponse(response.Pass());
 
diff --git a/mojo/shell/BUILD.gn b/mojo/shell/BUILD.gn
index 512c455..3c06107 100644
--- a/mojo/shell/BUILD.gn
+++ b/mojo/shell/BUILD.gn
@@ -18,24 +18,17 @@
   deps = [
     ":mojo_shell",
     ":tests",
+    "//mojo/shell/application_manager:tests",
   ]
 
   if (is_android) {
     deps += [
       ":mojo_shell_apk",
-      ":mojo_shell_tests_apk",
+      ":tests_apk",
     ]
   }
 }
 
-group("tests") {
-  testonly = true
-  deps = [
-    ":mojo_shell_tests",
-    "//mojo/shell/application_manager:mojo_application_manager_unittests",
-  ]
-}
-
 if (is_android) {
   import("//build/config/android/config.gni")
   import("//build/config/android/rules.gni")
@@ -45,7 +38,6 @@
   sources = []
 
   deps = [
-    ":init",
     ":lib",
     "//base",
     "//build/config/sanitizers:deps",
@@ -79,17 +71,6 @@
   }
 }
 
-source_set("init") {
-  sources = [
-    "init.cc",
-    "init.h",
-  ]
-
-  deps = [
-    "//base",
-  ]
-}
-
 source_set("in_process_native_runner") {
   sources = [
     "in_process_native_runner.cc",
@@ -116,6 +97,8 @@
     "context.h",
     "filename_util.cc",
     "filename_util.h",
+    "init.cc",
+    "init.h",
     "out_of_process_native_runner.cc",
     "out_of_process_native_runner.h",
     "task_runners.cc",
@@ -126,7 +109,6 @@
 
   deps = [
     ":child_process_bindings",
-    ":init",
     ":in_process_native_runner",
     ":native_application_support",
     "//base",
@@ -350,8 +332,9 @@
   ]
 }
 
-# GYP version: mojo/mojo.gyp:mojo_shell_tests
-test("mojo_shell_tests") {
+test("tests") {
+  output_name = "mojo_shell_unittests"
+
   sources = [
     "child_process_host_unittest.cc",
     "data_pipe_peek_unittest.cc",
@@ -400,22 +383,6 @@
   }
 }
 
-# GYP version: mojo/mojo.gyp:mojo_shell_test_support
-source_set("test_support") {
-  sources = [
-    "shell_test_helper.cc",
-    "shell_test_helper.h",
-  ]
-
-  deps = [
-    ":init",
-    ":lib",
-    "//base",
-    "//third_party/mojo/src/mojo/edk/system",
-    "//mojo/shell/application_manager",
-  ]
-}
-
 mojo_native_application("apptests") {
   output_name = "shell_apptests"
 
diff --git a/mojo/shell/application_manager/BUILD.gn b/mojo/shell/application_manager/BUILD.gn
index f220b43..9122e7e9 100644
--- a/mojo/shell/application_manager/BUILD.gn
+++ b/mojo/shell/application_manager/BUILD.gn
@@ -47,7 +47,9 @@
   ]
 }
 
-test("mojo_application_manager_unittests") {
+test("tests") {
+  output_name = "mojo_application_manager_unittests"
+
   sources = [
     "application_manager_unittest.cc",
     "query_util_unittest.cc",
diff --git a/mojo/shell/application_manager/application_manager_unittest.cc b/mojo/shell/application_manager/application_manager_unittest.cc
index cc420a7..f801e36 100644
--- a/mojo/shell/application_manager/application_manager_unittest.cc
+++ b/mojo/shell/application_manager/application_manager_unittest.cc
@@ -487,6 +487,33 @@
   EXPECT_EQ(0U, app_args.size());
 }
 
+// Confirm that url mappings are respected.
+TEST_F(ApplicationManagerTest, URLMapping) {
+  ApplicationManager am(&test_delegate_);
+  GURL test_url("test:test");
+  GURL test_url2("test:test2");
+  test_delegate_.AddMapping(test_url, test_url2);
+  TestApplicationLoader* loader = new TestApplicationLoader;
+  loader->set_context(&context_);
+  am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url2);
+  {
+    // Connext to the mapped url
+    TestServicePtr test_service;
+    am.ConnectToService(test_url, &test_service);
+    TestClient test_client(test_service.Pass());
+    test_client.Test("test");
+    loop_.Run();
+  }
+  {
+    // Connext to the target url
+    TestServicePtr test_service;
+    am.ConnectToService(test_url2, &test_service);
+    TestClient test_client(test_service.Pass());
+    test_client.Test("test");
+    loop_.Run();
+  }
+}
+
 TEST_F(ApplicationManagerTest, ClientError) {
   test_client_->Test("test");
   EXPECT_TRUE(HasFactoryForTestURL());
diff --git a/mojo/shell/context.cc b/mojo/shell/context.cc
index fc56476f..0cc27d1 100644
--- a/mojo/shell/context.cc
+++ b/mojo/shell/context.cc
@@ -84,6 +84,23 @@
     resolver->AddOriginMapping(GURL(origin_mapping.origin),
                                GURL(origin_mapping.base_url));
 
+  if (command_line.HasSwitch(switches::kURLMappings)) {
+    const std::string mappings =
+        command_line.GetSwitchValueASCII(switches::kURLMappings);
+
+    base::StringPairs pairs;
+    if (!base::SplitStringIntoKeyValuePairs(mappings, '=', ',', &pairs))
+      return false;
+    using StringPair = std::pair<std::string, std::string>;
+    for (const StringPair& pair : pairs) {
+      const GURL from(pair.first);
+      const GURL to = context->ResolveCommandLineURL(pair.second);
+      if (!from.is_valid() || !to.is_valid())
+        return false;
+      resolver->AddURLMapping(from, to);
+    }
+  }
+
   return true;
 }
 
diff --git a/mojo/shell/shell_test_helper.cc b/mojo/shell/shell_test_helper.cc
deleted file mode 100644
index 0a467303..0000000
--- a/mojo/shell/shell_test_helper.cc
+++ /dev/null
@@ -1,46 +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/shell_test_helper.h"
-
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "mojo/shell/filename_util.h"
-#include "mojo/shell/init.h"
-#include "mojo/shell/url_resolver.h"
-
-namespace mojo {
-namespace shell {
-
-ShellTestHelper::ShellTestHelper() {
-  base::CommandLine::Init(0, nullptr);
-  InitializeLogging();
-}
-
-ShellTestHelper::~ShellTestHelper() {
-}
-
-void ShellTestHelper::Init() {
-  context_.Init();
-  test_api_.reset(
-      new ApplicationManager::TestAPI(context_.application_manager()));
-  base::FilePath service_dir;
-  CHECK(PathService::Get(base::DIR_MODULE, &service_dir));
-  context_.url_resolver()->SetMojoBaseURL(FilePathToFileURL(service_dir));
-}
-
-void ShellTestHelper::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader,
-                                      const GURL& url) {
-  context_.application_manager()->SetLoaderForURL(loader.Pass(), url);
-}
-
-void ShellTestHelper::AddURLMapping(const GURL& url, const GURL& resolved_url) {
-  context_.url_resolver()->AddURLMapping(url, resolved_url);
-}
-
-}  // namespace shell
-}  // namespace mojo
diff --git a/mojo/shell/shell_test_helper.h b/mojo/shell/shell_test_helper.h
deleted file mode 100644
index 185d367..0000000
--- a/mojo/shell/shell_test_helper.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 SHELL_SHELL_TEST_HELPER_H_
-#define SHELL_SHELL_TEST_HELPER_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/run_loop.h"
-#include "mojo/shell/application_manager/application_loader.h"
-#include "mojo/shell/context.h"
-
-class GURL;
-
-namespace mojo {
-namespace shell {
-
-// ShellTestHelper is useful for tests to establish a connection to the
-// ApplicationManager. Invoke Init() to establish the connection. Once done,
-// application_manager() returns the ApplicationManager.
-class ShellTestHelper {
- public:
-  ShellTestHelper();
-  ~ShellTestHelper();
-
-  void Init();
-
-  ApplicationManager* application_manager() {
-    return context_.application_manager();
-  }
-
-  // Sets a ApplicationLoader for the specified URL. |loader| is ultimately used
-  // on
-  // the thread this class spawns.
-  void SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, const GURL& url);
-
-  // Adds a mapping that is used when resolving mojo urls. See URLResolver
-  // for details.
-  void AddURLMapping(const GURL& url, const GURL& resolved_url);
-
- private:
-  Context context_;
-  base::MessageLoop shell_loop_;
-  scoped_ptr<ApplicationManager::TestAPI> test_api_;
-  DISALLOW_COPY_AND_ASSIGN(ShellTestHelper);
-};
-
-}  // namespace shell
-}  // namespace mojo
-
-#endif  // SHELL_SHELL_TEST_HELPER_H_
diff --git a/mojo/shell/switches.cc b/mojo/shell/switches.cc
index 28e7d058..1fff40d5 100644
--- a/mojo/shell/switches.cc
+++ b/mojo/shell/switches.cc
@@ -55,4 +55,10 @@
 // seconds or when the shell exits.
 const char kTraceStartup[] = "trace-startup";
 
+// Specifies a set of mappings to apply when resolving urls. The value is a set
+// of ',' separated mappings, where each mapping consists of a pair of urls
+// giving the to/from url to map. For example, 'a=b,c=d' contains two mappings,
+// the first maps 'a' to 'b' and the second 'c' to 'd'.
+const char kURLMappings[] = "url-mappings";
+
 }  // namespace switches
diff --git a/mojo/shell/switches.h b/mojo/shell/switches.h
index ff2eb6c..31cac8f6 100644
--- a/mojo/shell/switches.h
+++ b/mojo/shell/switches.h
@@ -23,6 +23,7 @@
 extern const char kOrigin[];
 extern const char kPredictableAppFilenames[];
 extern const char kTraceStartup[];
+extern const char kURLMappings[];
 
 }  // namespace switches
 
diff --git a/mojo/tools/apptest_runner.py b/mojo/tools/apptest_runner.py
index 9ef7b7aa..ddc0830 100755
--- a/mojo/tools/apptest_runner.py
+++ b/mojo/tools/apptest_runner.py
@@ -1,81 +1,91 @@
 #!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
+# 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.
 
 """A test runner for gtest application tests."""
 
 import argparse
-import ast
 import logging
-import os
 import sys
 
-_logging = logging.getLogger()
+from mopy import dart_apptest
+from mopy import gtest
+# TODO(msw): Mojo's script pulls in android.py via mojo/devtools/common/pylib.
+from mopy.android import AndroidShell
+from mopy.config import Config
+from mopy.gn import ConfigForGNArgs, ParseGNConfig
+from mopy.log import InitLogging
+from mopy.paths import Paths
 
-import gtest
+
+_logger = logging.getLogger()
 
 
 def main():
-  logging.basicConfig()
-  # Uncomment to debug:
-  #_logging.setLevel(logging.DEBUG)
+  parser = argparse.ArgumentParser(description="A test runner for application "
+                                               "tests.")
 
-  parser = argparse.ArgumentParser(description='A test runner for gtest '
-                                   'application tests.')
-
-  parser.add_argument('apptest_list_file', type=file,
-                      help='A file listing apptests to run.')
-  parser.add_argument('build_dir', type=str,
-                      help='The build output directory.')
+  parser.add_argument("--verbose", help="be verbose (multiple times for more)",
+                      default=0, dest="verbose_count", action="count")
+  parser.add_argument("test_list_file", type=file,
+                      help="a file listing apptests to run")
+  parser.add_argument("build_dir", type=str,
+                      help="the build output directory")
   args = parser.parse_args()
 
-  apptest_list = ast.literal_eval(args.apptest_list_file.read())
-  _logging.debug("Test list: %s" % apptest_list)
+  InitLogging(args.verbose_count)
+  config = ConfigForGNArgs(ParseGNConfig(args.build_dir))
+
+  _logger.debug("Test list file: %s", args.test_list_file)
+  execution_globals = {"config": config}
+  exec args.test_list_file in execution_globals
+  test_list = execution_globals["tests"]
+  _logger.debug("Test list: %s" % test_list)
+
+  extra_args = []
+  if config.target_os == Config.OS_ANDROID:
+    paths = Paths(config)
+    shell = AndroidShell(paths.target_mojo_shell_path, paths.build_dir,
+                         paths.adb_path)
+    extra_args.extend(shell.PrepareShellRun(fixed_port=False))
+  else:
+    shell = None
 
   gtest.set_color()
-  mojo_shell_path = os.path.join(args.build_dir, "mojo_shell")
 
   exit_code = 0
-  for apptest_dict in apptest_list:
-    if apptest_dict.get("disabled"):
-      continue
+  for test_dict in test_list:
+    test = test_dict["test"]
+    test_name = test_dict.get("name", test)
+    test_type = test_dict.get("type", "gtest")
+    test_args = test_dict.get("test-args", [])
+    shell_args = test_dict.get("shell-args", []) + extra_args
 
-    apptest = apptest_dict["test"]
-    apptest_args = apptest_dict.get("test-args", [])
-    shell_args = apptest_dict.get("shell-args", [])
-
-    print "Running " + apptest + "...",
+    _logger.info("Will start: %s" % test_name)
+    print "Running %s...." % test_name,
     sys.stdout.flush()
 
-    # List the apptest fixtures so they can be run independently for isolation.
-    # TODO(msw): Run some apptests without fixture isolation?
-    fixtures = gtest.get_fixtures(mojo_shell_path, apptest)
+    if test_type == "dart":
+      apptest_result = dart_apptest.run_test(config, shell, test_dict,
+                                             shell_args, {test: test_args})
+    elif test_type == "gtest":
+      apptest_result = gtest.run_fixtures(config, shell, test_dict,
+                                          test, False,
+                                          test_args, shell_args)
+    elif test_type == "gtest_isolated":
+      apptest_result = gtest.run_fixtures(config, shell, test_dict,
+                                          test, True, test_args, shell_args)
+    else:
+      apptest_result = "Invalid test type in %r" % test_dict
 
-    if not fixtures:
-      print "Failed with no tests found."
+    if apptest_result != "Succeeded":
       exit_code = 1
-      continue
-
-    apptest_result = "Succeeded"
-    for fixture in fixtures:
-      args_for_apptest = " ".join(["--gtest_filter=" + fixture] + apptest_args)
-
-      success = RunApptestInShell(mojo_shell_path, apptest,
-                                  shell_args + [args_for_apptest])
-
-      if not success:
-        apptest_result = "Failed test(s) in %r" % apptest_dict
-        exit_code = 1
-
     print apptest_result
+    _logger.info("Completed: %s" % test_name)
 
   return exit_code
 
 
-def RunApptestInShell(mojo_shell_path, apptest, shell_args):
-  return gtest.run_test([mojo_shell_path, apptest] + shell_args)
-
-
 if __name__ == '__main__':
   sys.exit(main())
diff --git a/mojo/tools/data/apptests b/mojo/tools/data/apptests
index 400f70c..7f336c6 100644
--- a/mojo/tools/data/apptests
+++ b/mojo/tools/data/apptests
@@ -1,10 +1,51 @@
 # This file contains a list of Mojo gtest unit tests.
-# This must be a valid python dictionary.
-[
+#
+# This must be valid Python. It may use the |config| global that will be a
+# mopy.config.Config object, and must set a |tests| global that will contain the
+# list of tests to run.
+#
+# The entries in |tests| are dictionaries of the following form:
+#   {
+#     # Required URL for apptest.
+#     "test": "mojo:test_app_url",
+#     # Optional display name (otherwise the entry for "test" above is used).
+#     "name": "mojo:test_app_url (more details)",
+#     # Optional test type. Valid values:
+#     #   * "gtest" (default)
+#     #   * "gtest_isolated": like "gtest", but run with fixture isolation,
+#     #      i.e., each test in a fresh mojo_shell)
+#     #   * "dart".
+#     "type": "gtest",
+#     # Optional arguments for the apptest.
+#     "test-args": ["--an_arg", "another_arg"],
+#     # Optional arguments for the shell.
+#     "shell-args": ["--some-flag-for-the-shell", "--another-flag"],
+#   }
+#
+# TODO(vtl|msw): Add a way of specifying data dependencies.
+
+tests = [
   {
-    "test": "mojo:network_service_apptests",
+    "test": "mojo:clipboard_apptests",
   },
   {
     "test": "mojo:html_viewer_apptests",
+    "shell-args": ["--is-headless"],
   },
+  {
+    "test": "mojo:network_service_apptests",
+  },
+  # TODO(msw|jam): Fix and enable the shell_apptests: http://crbug.com/479316
+  #{
+  #  "test": "mojo:shell_apptests",
+  #},
+  {
+    "test": "mojo:view_manager_apptests",
+    "type": "gtest_isolated",
+    "shell-args": ["--url-mappings=mojo:window_manager=mojo:test_window_manager"]
+  },
+  # TODO(msw): Fix and enable window_manager_apptests: http://crbug.com/480040
+  #{
+  #  "test": "mojo:window_manager_apptests",
+  #},
 ]
diff --git a/mojo/tools/gtest.py b/mojo/tools/gtest.py
deleted file mode 100644
index d84c8e5e..0000000
--- a/mojo/tools/gtest.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import re
-import subprocess
-import sys
-
-_logging = logging.getLogger()
-
-def _print_process_error(command_line, error):
-  """Properly format an exception raised from a failed command execution."""
-
-  if command_line:
-    print 'Failed command: %r' % command_line
-  else:
-    print 'Failed command:'
-  print 72 * '-'
-
-  if hasattr(error, 'returncode'):
-    print '  with exit code %d' % error.returncode
-    print 72 * '-'
-
-  if hasattr(error, 'output'):
-    print error.output
-  else:
-    print error
-  print 72 * '-'
-
-def set_color():
-  """Run gtests with color if we're on a TTY (and we're not being told
-  explicitly what to do)."""
-  if sys.stdout.isatty() and 'GTEST_COLOR' not in os.environ:
-    _logging.debug("Setting GTEST_COLOR=yes")
-    os.environ['GTEST_COLOR'] = 'yes'
-
-
-def _try_command_line(command_line):
-  """Returns the output of a command line or an empty string on error."""
-  _logging.debug("Running command line: %s" % command_line)
-  try:
-    return subprocess.check_output(command_line, stderr=subprocess.STDOUT)
-  except Exception as e:
-    _print_process_error(command_line, e)
-  return None
-
-
-def run_test(command_line):
-  """Runs a command line and checks the output for signs of gtest failure."""
-  output = _try_command_line(command_line)
-  # Fail on output with gtest's "[  FAILED  ]" or a lack of "[  PASSED  ]".
-  # The latter condition ensures failure on broken command lines or output.
-  # Check output instead of exit codes because mojo_shell always exits with 0.
-  if (output is None or
-      (output.find("[  FAILED  ]") != -1 or output.find("[  PASSED  ]") == -1)):
-    print "Failed test:"
-    _print_process_error(command_line, output)
-    return False
-  _logging.debug("Succeeded with output:\n%s" % output)
-  return True
-
-
-def get_fixtures(mojo_shell, apptest):
-  """Returns the "Test.Fixture" list from an apptest using mojo_shell.
-
-  Tests are listed by running the given apptest in mojo_shell and passing
-  --gtest_list_tests. The output is parsed and reformatted into a list like
-  [TestSuite.TestFixture, ... ]
-  An empty list is returned on failure, with errors logged.
-  """
-  command = [mojo_shell, "--gtest_list_tests", apptest]
-  try:
-    list_output = subprocess.check_output(command, stderr=subprocess.STDOUT)
-    _logging.debug("Tests listed:\n%s" % list_output)
-    return _gtest_list_tests(list_output)
-  except Exception as e:
-    print "Failed to get test fixtures:"
-    _print_process_error(command, e)
-  return []
-
-
-def _gtest_list_tests(gtest_list_tests_output):
-  """Returns a list of strings formatted as TestSuite.TestFixture from the
-  output of running --gtest_list_tests on a GTEST application."""
-
-  # Remove log lines.
-  gtest_list_tests_output = (
-      re.sub("^\[.*\n", "", gtest_list_tests_output, flags=re.MULTILINE))
-
-  if not re.match("^(\w*\.\r?\n(  \w*\r?\n)+)+", gtest_list_tests_output):
-    raise Exception("Unrecognized --gtest_list_tests output:\n%s" %
-                    gtest_list_tests_output)
-
-  output_lines = gtest_list_tests_output.split('\n')
-
-  test_list = []
-  for line in output_lines:
-    if not line:
-      continue
-    if line[0] != ' ':
-      suite = line.strip()
-      continue
-    test_list.append(suite + line.strip())
-
-  return test_list
diff --git a/mojo/tools/mopy/android.py b/mojo/tools/mopy/android.py
index 6584b9f..374ebb08 100644
--- a/mojo/tools/mopy/android.py
+++ b/mojo/tools/mopy/android.py
@@ -3,8 +3,13 @@
 # found in the LICENSE file.
 
 import atexit
+import datetime
+import email.utils
+import hashlib
+import itertools
 import json
 import logging
+import math
 import os
 import os.path
 import random
@@ -17,9 +22,6 @@
 import SimpleHTTPServer
 import SocketServer
 
-from mopy.config import Config
-from mopy.paths import Paths
-
 
 # Tags used by the mojo shell application logs.
 LOGCAT_TAGS = [
@@ -31,11 +33,30 @@
     'chromium',
 ]
 
-ADB_PATH = os.path.join(Paths().src_root, 'third_party', 'android_tools', 'sdk',
-                        'platform-tools', 'adb')
-
 MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell'
 
+MAPPING_PREFIX = '--map-origin='
+
+DEFAULT_BASE_PORT = 31337
+
+ZERO = datetime.timedelta(0)
+
+class UTC_TZINFO(datetime.tzinfo):
+  """UTC time zone representation."""
+
+  def utcoffset(self, _):
+    return ZERO
+
+  def tzname(self, _):
+    return "UTC"
+
+  def dst(self, _):
+     return ZERO
+
+UTC = UTC_TZINFO()
+
+_logger = logging.getLogger()
+
 
 class _SilentTCPServer(SocketServer.TCPServer):
   """
@@ -58,6 +79,69 @@
     |base_path| directory over http.
     """
 
+    def __init__(self, *args, **kwargs):
+      self.etag = None
+      SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
+
+    def get_etag(self):
+      if self.etag:
+        return self.etag
+
+      path = self.translate_path(self.path)
+      if not os.path.isfile(path):
+        return None
+
+      sha256 = hashlib.sha256()
+      BLOCKSIZE = 65536
+      with open(path, 'rb') as hashed:
+        buf = hashed.read(BLOCKSIZE)
+        while len(buf) > 0:
+          sha256.update(buf)
+          buf = hashed.read(BLOCKSIZE)
+      self.etag = '"%s"' % sha256.hexdigest()
+      return self.etag
+
+    def send_head(self):
+      # Always close the connection after each request, as the keep alive
+      # support from SimpleHTTPServer doesn't like when the client requests to
+      # close the connection before downloading the full response content.
+      # pylint: disable=W0201
+      self.close_connection = 1
+
+      path = self.translate_path(self.path)
+      if os.path.isfile(path):
+        # Handle If-None-Match
+        etag = self.get_etag()
+        if ('If-None-Match' in self.headers and
+            etag == self.headers['If-None-Match']):
+          self.send_response(304)
+          return None
+
+        # Handle If-Modified-Since
+        if ('If-None-Match' not in self.headers and
+            'If-Modified-Since' in self.headers):
+          last_modified = datetime.datetime.fromtimestamp(
+              math.floor(os.stat(path).st_mtime), tz=UTC)
+          ims = datetime.datetime(
+              *email.utils.parsedate(self.headers['If-Modified-Since'])[:6],
+              tzinfo=UTC)
+          if last_modified <= ims:
+            self.send_response(304)
+            return None
+
+      return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
+
+    def end_headers(self):
+      path = self.translate_path(self.path)
+
+      if os.path.isfile(path):
+        etag = self.get_etag()
+        if etag:
+          self.send_header('ETag', etag)
+          self.send_header('Cache-Control', 'must-revalidate')
+
+      return SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)
+
     def translate_path(self, path):
       path_from_current = (
           SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self, path))
@@ -69,9 +153,26 @@
       """
       pass
 
+  RequestHandler.protocol_version = 'HTTP/1.1'
   return RequestHandler
 
 
+def _IsMapOrigin(arg):
+  """Returns whether arg is a --map-origin argument."""
+  return arg.startswith(MAPPING_PREFIX)
+
+
+def _Split(l, pred):
+  positive = []
+  negative = []
+  for v in l:
+    if pred(v):
+      positive.append(v)
+    else:
+      negative.append(v)
+  return (positive, negative)
+
+
 def _ExitIfNeeded(process):
   """
   Exits |process| if it is still alive.
@@ -80,186 +181,228 @@
     process.kill()
 
 
-def _ReadFifo(fifo_path, pipe, on_fifo_closed, max_attempts=5):
+class AndroidShell(object):
+  """ Allows to set up and run a given mojo shell binary on an Android device.
+
+  Args:
+    shell_apk_path: path to the shell Android binary
+    local_dir: directory where locally build Mojo apps will be served, optional
+    adb_path: path to adb, optional if adb is in PATH
+    target_device: device to run on, if multiple devices are connected
   """
-  Reads |fifo_path| on the device and write the contents to |pipe|. Calls
-  |on_fifo_closed| when the fifo is closed. This method will try to find the
-  path up to |max_attempts|, waiting 1 second between each attempt. If it cannot
-  find |fifo_path|, a exception will be raised.
-  """
-  def Run():
-    def _WaitForFifo():
-      command = [ADB_PATH, 'shell', 'test -e "%s"; echo $?' % fifo_path]
-      for _ in xrange(max_attempts):
-        if subprocess.check_output(command)[0] == '0':
-          return
-        time.sleep(1)
+  def __init__(
+      self, shell_apk_path, local_dir=None, adb_path="adb", target_device=None):
+    self.shell_apk_path = shell_apk_path
+    self.adb_path = adb_path
+    self.local_dir = local_dir
+    self.target_device = target_device
+
+  def _CreateADBCommand(self, args):
+    adb_command = [self.adb_path]
+    if self.target_device:
+      adb_command.extend(['-s', self.target_device])
+    adb_command.extend(args)
+    return adb_command
+
+  def _ReadFifo(self, fifo_path, pipe, on_fifo_closed, max_attempts=5):
+    """
+    Reads |fifo_path| on the device and write the contents to |pipe|. Calls
+    |on_fifo_closed| when the fifo is closed. This method will try to find the
+    path up to |max_attempts|, waiting 1 second between each attempt. If it
+    cannot find |fifo_path|, a exception will be raised.
+    """
+    fifo_command = self._CreateADBCommand(
+        ['shell', 'test -e "%s"; echo $?' % fifo_path])
+
+    def Run():
+      def _WaitForFifo():
+        for _ in xrange(max_attempts):
+          if subprocess.check_output(fifo_command)[0] == '0':
+            return
+          time.sleep(1)
+        if on_fifo_closed:
+          on_fifo_closed()
+        raise Exception("Unable to find fifo.")
+      _WaitForFifo()
+      stdout_cat = subprocess.Popen(self._CreateADBCommand([
+                                     'shell',
+                                     'cat',
+                                     fifo_path]),
+                                    stdout=pipe)
+      atexit.register(_ExitIfNeeded, stdout_cat)
+      stdout_cat.wait()
       if on_fifo_closed:
         on_fifo_closed()
-      raise Exception("Unable to find fifo.")
-    _WaitForFifo()
-    stdout_cat = subprocess.Popen([ADB_PATH,
-                                   'shell',
-                                   'cat',
-                                   fifo_path],
-                                  stdout=pipe)
-    atexit.register(_ExitIfNeeded, stdout_cat)
-    stdout_cat.wait()
-    if on_fifo_closed:
-      on_fifo_closed()
 
-  thread = threading.Thread(target=Run, name="StdoutRedirector")
-  thread.start()
+    thread = threading.Thread(target=Run, name="StdoutRedirector")
+    thread.start()
 
+  def _MapPort(self, device_port, host_port):
+    """
+    Maps the device port to the host port. If |device_port| is 0, a random
+    available port is chosen. Returns the device port.
+    """
+    def _FindAvailablePortOnDevice():
+      opened = subprocess.check_output(
+          self._CreateADBCommand(['shell', 'netstat']))
+      opened = [int(x.strip().split()[3].split(':')[1])
+                for x in opened if x.startswith(' tcp')]
+      while True:
+        port = random.randint(4096, 16384)
+        if port not in opened:
+          return port
+    if device_port == 0:
+      device_port = _FindAvailablePortOnDevice()
+    subprocess.Popen(self._CreateADBCommand([
+                      "reverse",
+                      "tcp:%d" % device_port,
+                      "tcp:%d" % host_port])).wait()
 
-def _MapPort(device_port, host_port):
-  """
-  Maps the device port to the host port. If |device_port| is 0, a random
-  available port is chosen. Returns the device port.
-  """
-  def _FindAvailablePortOnDevice():
-    opened = subprocess.check_output([ADB_PATH, 'shell', 'netstat'])
-    opened = [int(x.strip().split()[3].split(':')[1])
-              for x in opened if x.startswith(' tcp')]
-    while True:
-      port = random.randint(4096, 16384)
-      if port not in opened:
-        return port
-  if device_port == 0:
-    device_port = _FindAvailablePortOnDevice()
-  subprocess.Popen([ADB_PATH,
-                    "reverse",
-                    "tcp:%d" % device_port,
-                    "tcp:%d" % host_port]).wait()
-  def _UnmapPort():
-    subprocess.Popen([ADB_PATH, "reverse", "--remove",  "tcp:%d" % device_port])
-  atexit.register(_UnmapPort)
-  return device_port
+    unmap_command = self._CreateADBCommand(["reverse", "--remove",
+                     "tcp:%d" % device_port])
 
+    def _UnmapPort():
+      subprocess.Popen(unmap_command)
+    atexit.register(_UnmapPort)
+    return device_port
 
-def StartHttpServerForDirectory(path):
-  """Starts an http server serving files from |path|. Returns the local url."""
-  print 'starting http for', path
-  httpd = _SilentTCPServer(('127.0.0.1', 0), _GetHandlerClassForPath(path))
-  atexit.register(httpd.shutdown)
+  def _StartHttpServerForDirectory(self, path, port=0):
+    """Starts an http server serving files from |path|. Returns the local
+    url."""
+    assert path
+    print 'starting http for', path
+    httpd = _SilentTCPServer(('127.0.0.1', 0), _GetHandlerClassForPath(path))
+    atexit.register(httpd.shutdown)
 
-  http_thread = threading.Thread(target=httpd.serve_forever)
-  http_thread.daemon = True
-  http_thread.start()
+    http_thread = threading.Thread(target=httpd.serve_forever)
+    http_thread.daemon = True
+    http_thread.start()
 
-  print 'local port=', httpd.server_address[1]
-  return 'http://127.0.0.1:%d/' % _MapPort(0, httpd.server_address[1])
+    print 'local port=%d' % httpd.server_address[1]
+    return 'http://127.0.0.1:%d/' % self._MapPort(port, httpd.server_address[1])
 
+  def _StartHttpServerForOriginMapping(self, mapping, port):
+    """If |mapping| points at a local file starts an http server to serve files
+    from the directory and returns the new mapping.
 
-def PrepareShellRun(config, origin=None):
-  """ Prepares for StartShell: runs adb as root and installs the apk.  If no
-  --origin is specified, local http server will be set up to serve files from
-  the build directory along with port forwarding.
+    This is intended to be called for every --map-origin value."""
+    parts = mapping.split('=')
+    if len(parts) != 2:
+      return mapping
+    dest = parts[1]
+    # If the destination is a url, don't map it.
+    if urlparse.urlparse(dest)[0]:
+      return mapping
+    # Assume the destination is a local file. Start a local server that
+    # redirects to it.
+    localUrl = self._StartHttpServerForDirectory(dest, port)
+    print 'started server at %s for %s' % (dest, localUrl)
+    return parts[0] + '=' + localUrl
 
-  Returns arguments that should be appended to shell argument list."""
-  build_dir = Paths(config).build_dir
+  def _StartHttpServerForOriginMappings(self, map_parameters, fixed_port):
+    """Calls _StartHttpServerForOriginMapping for every --map-origin
+    argument."""
+    if not map_parameters:
+      return []
 
-  subprocess.check_call([ADB_PATH, 'root'])
-  apk_path = os.path.join(build_dir, 'apks', 'MojoShell.apk')
-  subprocess.check_call(
-      [ADB_PATH, 'install', '-r', apk_path, '-i', MOJO_SHELL_PACKAGE_NAME])
-  atexit.register(StopShell)
+    original_values = list(itertools.chain(
+        *map(lambda x: x[len(MAPPING_PREFIX):].split(','), map_parameters)))
+    sorted(original_values)
+    result = []
+    for i, value in enumerate(original_values):
+      result.append(self._StartHttpServerForOriginMapping(
+          value, DEFAULT_BASE_PORT + 1 + i if fixed_port else 0))
+    return [MAPPING_PREFIX + ','.join(result)]
 
-  extra_shell_args = []
-  origin_url = origin if origin else StartHttpServerForDirectory(build_dir)
-  extra_shell_args.append("--origin=" + origin_url)
+  def PrepareShellRun(self, origin=None, fixed_port=True):
+    """ Prepares for StartShell: runs adb as root and installs the apk.  If no
+    --origin is specified, local http server will be set up to serve files from
+    the build directory along with port forwarding.
 
-  return extra_shell_args
+    Returns arguments that should be appended to shell argument list."""
+    if 'cannot run as root' in subprocess.check_output(
+        self._CreateADBCommand(['root'])):
+      raise Exception("Unable to run adb as root.")
+    subprocess.check_call(
+        self._CreateADBCommand(['install', '-r', self.shell_apk_path, '-i',
+         MOJO_SHELL_PACKAGE_NAME]))
+    atexit.register(self.StopShell)
 
+    extra_shell_args = []
+    origin_url = origin if origin else self._StartHttpServerForDirectory(
+        self.local_dir, DEFAULT_BASE_PORT if fixed_port else 0)
+    extra_shell_args.append("--origin=" + origin_url)
 
-def _StartHttpServerForOriginMapping(mapping):
-  """If |mapping| points at a local file starts an http server to serve files
-  from the directory and returns the new mapping.
+    return extra_shell_args
 
-  This is intended to be called for every --map-origin value."""
-  parts = mapping.split('=')
-  if len(parts) != 2:
-    return mapping
-  dest = parts[1]
-  # If the destination is a url, don't map it.
-  if urlparse.urlparse(dest)[0]:
-    return mapping
-  # Assume the destination is a local file. Start a local server that redirects
-  # to it.
-  localUrl = StartHttpServerForDirectory(dest)
-  print 'started server at %s for %s' % (dest, localUrl)
-  return parts[0] + '=' + localUrl
+  def StartShell(self,
+                 arguments,
+                 stdout=None,
+                 on_application_stop=None,
+                 fixed_port=True):
+    """
+    Starts the mojo shell, passing it the given arguments.
 
+    The |arguments| list must contain the "--origin=" arg from PrepareShellRun.
+    If |stdout| is not None, it should be a valid argument for subprocess.Popen.
+    """
+    STDOUT_PIPE = "/data/data/%s/stdout.fifo" % MOJO_SHELL_PACKAGE_NAME
 
-def _StartHttpServerForOriginMappings(arg):
-  """Calls _StartHttpServerForOriginMapping for every --map-origin argument."""
-  mapping_prefix = '--map-origin='
-  if not arg.startswith(mapping_prefix):
-    return arg
-  return mapping_prefix + ','.join([_StartHttpServerForOriginMapping(value)
-      for value in arg[len(mapping_prefix):].split(',')])
+    cmd = self._CreateADBCommand([
+           'shell',
+           'am',
+           'start',
+           '-S',
+           '-a', 'android.intent.action.VIEW',
+           '-n', '%s/.MojoShellActivity' % MOJO_SHELL_PACKAGE_NAME])
 
+    parameters = []
+    if stdout or on_application_stop:
+      subprocess.check_call(self._CreateADBCommand(
+          ['shell', 'rm', STDOUT_PIPE]))
+      parameters.append('--fifo-path=%s' % STDOUT_PIPE)
+      self._ReadFifo(STDOUT_PIPE, stdout, on_application_stop)
+    # The origin has to be specified whether it's local or external.
+    assert any("--origin=" in arg for arg in arguments)
 
-def StartShell(arguments, stdout=None, on_application_stop=None):
-  """
-  Starts the mojo shell, passing it the given arguments.
+    # Extract map-origin arguments.
+    map_parameters, other_parameters = _Split(arguments, _IsMapOrigin)
+    parameters += other_parameters
+    parameters += self._StartHttpServerForOriginMappings(map_parameters,
+                                                         fixed_port)
 
-  The |arguments| list must contain the "--origin=" arg from PrepareShellRun.
-  If |stdout| is not None, it should be a valid argument for subprocess.Popen.
-  """
-  STDOUT_PIPE = "/data/data/%s/stdout.fifo" % MOJO_SHELL_PACKAGE_NAME
+    if parameters:
+      encodedParameters = json.dumps(parameters)
+      cmd += ['--es', 'encodedParameters', encodedParameters]
 
-  cmd = [ADB_PATH,
-         'shell',
-         'am',
-         'start',
-         '-W',
-         '-S',
-         '-a', 'android.intent.action.VIEW',
-         '-n', '%s/.MojoShellActivity' % MOJO_SHELL_PACKAGE_NAME]
+    with open(os.devnull, 'w') as devnull:
+      subprocess.Popen(cmd, stdout=devnull).wait()
 
-  parameters = []
-  if stdout or on_application_stop:
-    subprocess.check_call([ADB_PATH, 'shell', 'rm', STDOUT_PIPE])
-    parameters.append('--fifo-path=%s' % STDOUT_PIPE)
-    _ReadFifo(STDOUT_PIPE, stdout, on_application_stop)
-  # The origin has to be specified whether it's local or external.
-  assert any("--origin=" in arg for arg in arguments)
-  parameters += [_StartHttpServerForOriginMappings(arg) for arg in arguments]
+  def StopShell(self):
+    """
+    Stops the mojo shell.
+    """
+    subprocess.check_call(self._CreateADBCommand(['shell',
+                                                  'am',
+                                                  'force-stop',
+                                                  MOJO_SHELL_PACKAGE_NAME]))
 
-  if parameters:
-    encodedParameters = json.dumps(parameters)
-    cmd += [ '--es', 'encodedParameters', encodedParameters]
+  def CleanLogs(self):
+    """
+    Cleans the logs on the device.
+    """
+    subprocess.check_call(self._CreateADBCommand(['logcat', '-c']))
 
-  with open(os.devnull, 'w') as devnull:
-    subprocess.Popen(cmd, stdout=devnull).wait()
+  def ShowLogs(self):
+    """
+    Displays the log for the mojo shell.
 
-
-def StopShell():
-  """
-  Stops the mojo shell.
-  """
-  subprocess.check_call(
-      [ADB_PATH, 'shell', 'am', 'force-stop', MOJO_SHELL_PACKAGE_NAME])
-
-
-def CleanLogs():
-  """
-  Cleans the logs on the device.
-  """
-  subprocess.check_call([ADB_PATH, 'logcat', '-c'])
-
-
-def ShowLogs():
-  """
-  Displays the log for the mojo shell.
-
-  Returns the process responsible for reading the logs.
-  """
-  logcat = subprocess.Popen([ADB_PATH,
-                             'logcat',
-                             '-s',
-                             ' '.join(LOGCAT_TAGS)],
-                            stdout=sys.stdout)
-  atexit.register(_ExitIfNeeded, logcat)
-  return logcat
+    Returns the process responsible for reading the logs.
+    """
+    logcat = subprocess.Popen(self._CreateADBCommand([
+                               'logcat',
+                               '-s',
+                               ' '.join(LOGCAT_TAGS)]),
+                              stdout=sys.stdout)
+    atexit.register(_ExitIfNeeded, logcat)
+    return logcat
diff --git a/mojo/tools/mopy/config.py b/mojo/tools/mopy/config.py
index 7c8cadd..796a328 100644
--- a/mojo/tools/mopy/config.py
+++ b/mojo/tools/mopy/config.py
@@ -6,8 +6,6 @@
 "defines" the schema and provides some wrappers."""
 
 
-import json
-import os.path
 import platform
 import sys
 
diff --git a/mojo/tools/mopy/dart_apptest.py b/mojo/tools/mopy/dart_apptest.py
new file mode 100644
index 0000000..5e12b174
--- /dev/null
+++ b/mojo/tools/mopy/dart_apptest.py
@@ -0,0 +1,38 @@
+# 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 logging
+
+_logging = logging.getLogger()
+
+from mopy import test_util
+from mopy.print_process_error import print_process_error
+
+
+# TODO(erg): Support android, launched services and fixture isolation.
+def run_test(config, shell, apptest_dict, shell_args, apps_and_args=None):
+  """Runs a command line and checks the output for signs of gtest failure.
+
+  Args:
+    config: The mopy.config.Config object for the build.
+    shell_args: The arguments for mojo_shell.
+    apps_and_args: A Dict keyed by application URL associated to the
+        application's specific arguments.
+  """
+  apps_and_args = apps_and_args or {}
+  output = test_util.try_run_test(config, shell, shell_args, apps_and_args)
+  # Fail on output with dart unittests' "FAIL:"/"ERROR:" or a lack of "PASS:".
+  # The latter condition ensures failure on broken command lines or output.
+  # Check output instead of exit codes because mojo_shell always exits with 0.
+  if (not output or
+      '\nFAIL: ' in output or
+      '\nERROR: ' in output or
+      '\nPASS: ' not in output):
+    print "Failed test:"
+    print_process_error(
+        test_util.build_command_line(config, shell_args, apps_and_args),
+        output)
+    return "Failed test(s) in %r" % apptest_dict
+  _logging.debug("Succeeded with output:\n%s" % output)
+  return "Succeeded"
diff --git a/mojo/tools/mopy/gn.py b/mojo/tools/mopy/gn.py
index 69ddff4f..024e00f 100644
--- a/mojo/tools/mopy/gn.py
+++ b/mojo/tools/mopy/gn.py
@@ -132,4 +132,10 @@
         key = result.group(1)
         value = result.group(2)
         values[key] = ast.literal_eval(TRANSLATIONS.get(value, value))
+
+  # TODO(msw): Mojo's script uses GN's is_debug arg to determine the build dir.
+  #            It should probably just use the argument build_dir instead.
+  if not "is_debug" in values:
+    values["is_debug"] = "Debug" in build_dir
+
   return values
diff --git a/mojo/tools/mopy/gtest.py b/mojo/tools/mopy/gtest.py
new file mode 100644
index 0000000..1cde8ece
--- /dev/null
+++ b/mojo/tools/mopy/gtest.py
@@ -0,0 +1,132 @@
+# 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 logging
+import os
+import re
+import sys
+
+from mopy import test_util
+from mopy.print_process_error import print_process_error
+
+
+_logger = logging.getLogger()
+
+
+def set_color():
+  """Run gtests with color if we're on a TTY (and we're not being told
+  explicitly what to do)."""
+  if sys.stdout.isatty() and "GTEST_COLOR" not in os.environ:
+    _logger.debug("Setting GTEST_COLOR=yes")
+    os.environ["GTEST_COLOR"] = "yes"
+
+# TODO(vtl): The return value is bizarre. Should just make it either return
+# True/False, or a list of failing fixtures. But the dart_apptest runner would
+# also need to be updated in the same way.
+def run_fixtures(config, shell, apptest_dict, apptest, isolate, test_args,
+                 shell_args):
+  """Run the gtest fixtures in isolation."""
+
+  if not isolate:
+    if not RunApptestInShell(config, shell, apptest, test_args, shell_args):
+      return "Failed test(s) in %r" % apptest_dict
+    return "Succeeded"
+
+  # List the apptest fixtures so they can be run independently for isolation.
+  fixtures = get_fixtures(config, shell, shell_args, apptest)
+
+  if not fixtures:
+    return "Failed with no tests found."
+
+  apptest_result = "Succeeded"
+  for fixture in fixtures:
+    apptest_args = test_args + ["--gtest_filter=%s" % fixture]
+    success = RunApptestInShell(config, shell, apptest, apptest_args,
+                                shell_args)
+
+    if not success:
+      apptest_result = "Failed test(s) in %r" % apptest_dict
+
+  return apptest_result
+
+
+def run_test(config, shell, shell_args, apps_and_args=None):
+  """Runs a command line and checks the output for signs of gtest failure.
+
+  Args:
+    config: The mopy.config.Config object for the build.
+    shell_args: The arguments for mojo_shell.
+    apps_and_args: A Dict keyed by application URL associated to the
+        application's specific arguments.
+  """
+  apps_and_args = apps_and_args or {}
+  output = test_util.try_run_test(config, shell, shell_args, apps_and_args)
+  # Fail on output with gtest's "[  FAILED  ]" or a lack of "[  PASSED  ]".
+  # The latter condition ensures failure on broken command lines or output.
+  # Check output instead of exit codes because mojo_shell always exits with 0.
+  if (output is None or
+      (output.find("[  FAILED  ]") != -1 or output.find("[  PASSED  ]") == -1)):
+    print "Failed test:"
+    print_process_error(
+        test_util.build_command_line(config, shell_args, apps_and_args),
+        output)
+    return False
+  _logger.debug("Succeeded with output:\n%s" % output)
+  return True
+
+
+def get_fixtures(config, shell, shell_args, apptest):
+  """Returns the "Test.Fixture" list from an apptest using mojo_shell.
+
+  Tests are listed by running the given apptest in mojo_shell and passing
+  --gtest_list_tests. The output is parsed and reformatted into a list like
+  [TestSuite.TestFixture, ... ]
+  An empty list is returned on failure, with errors logged.
+
+  Args:
+    config: The mopy.config.Config object for the build.
+    apptest: The URL of the test application to run.
+  """
+  try:
+    apps_and_args = {apptest: ["--gtest_list_tests"]}
+    list_output = test_util.run_test(config, shell, shell_args, apps_and_args)
+    _logger.debug("Tests listed:\n%s" % list_output)
+    return _gtest_list_tests(list_output)
+  except Exception as e:
+    print "Failed to get test fixtures:"
+    print_process_error(
+        test_util.build_command_line(config, shell_args, apps_and_args), e)
+  return []
+
+
+def _gtest_list_tests(gtest_list_tests_output):
+  """Returns a list of strings formatted as TestSuite.TestFixture from the
+  output of running --gtest_list_tests on a GTEST application."""
+
+  # Remove log lines.
+  gtest_list_tests_output = re.sub("^(\[|WARNING: linker:).*\n",
+                                   "",
+                                   gtest_list_tests_output,
+                                   flags=re.MULTILINE)
+
+  if not re.match("^(\w*\.\r?\n(  \w*\r?\n)+)+", gtest_list_tests_output):
+    raise Exception("Unrecognized --gtest_list_tests output:\n%s" %
+                    gtest_list_tests_output)
+
+  output_lines = gtest_list_tests_output.split("\n")
+
+  test_list = []
+  for line in output_lines:
+    if not line:
+      continue
+    if line[0] != " ":
+      suite = line.strip()
+      continue
+    test_list.append(suite + line.strip())
+
+  return test_list
+
+
+def RunApptestInShell(config, shell, application, application_args, shell_args):
+  return run_test(config, shell, shell_args, {application: application_args})
diff --git a/mojo/tools/mopy/log.py b/mojo/tools/mopy/log.py
new file mode 100644
index 0000000..af57232
--- /dev/null
+++ b/mojo/tools/mopy/log.py
@@ -0,0 +1,29 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Logging utilities, for use with the standard logging module."""
+
+
+import logging
+
+
+def InitLogging(verbose_count):
+  """Ensures that the logger (obtained via logging.getLogger(), as usual) is
+  initialized, with the log level set as appropriate for |verbose_count|
+  instances of --verbose on the command line."""
+
+  assert(verbose_count >= 0)
+  if verbose_count == 0:
+    level = logging.WARNING
+  elif verbose_count == 1:
+    level = logging.INFO
+  else:  # verbose_count >= 2
+    level = logging.DEBUG
+
+  logging.basicConfig(format="%(relativeCreated).3f:%(levelname)s:%(message)s")
+  logger = logging.getLogger()
+  logger.setLevel(level)
+
+  logger.debug("Initialized logging: verbose_count=%d, level=%d" %
+               (verbose_count, level))
diff --git a/mojo/tools/mopy/paths.py b/mojo/tools/mopy/paths.py
index 49e1c50..60181e89 100644
--- a/mojo/tools/mopy/paths.py
+++ b/mojo/tools/mopy/paths.py
@@ -16,6 +16,8 @@
     self.src_root = os.path.abspath(os.path.join(__file__,
       os.pardir, os.pardir, os.pardir, os.pardir))
     self.mojo_dir = os.path.join(self.src_root, "mojo")
+    self.adb_path = os.path.join(self.src_root, 'third_party', 'android_tools',
+                                 'sdk', 'platform-tools', 'adb')
 
     if config:
       self.build_dir = BuildDirectoryForConfig(config, self.src_root)
@@ -25,13 +27,11 @@
       self.build_dir = None
 
     if self.build_dir is not None:
-      self.mojo_launcher_path = os.path.join(self.build_dir, "mojo_launcher")
       self.mojo_shell_path = os.path.join(self.build_dir, "mojo_shell")
       # TODO(vtl): Use the host OS here, since |config| may not be available.
       # In any case, if the target is Windows, but the host isn't, using
       # |os.path| isn't correct....
       if Config.GetHostOS() == Config.OS_WINDOWS:
-        self.mojo_launcher_path += ".exe"
         self.mojo_shell_path += ".exe"
       if config and config.target_os == Config.OS_ANDROID:
         self.target_mojo_shell_path = os.path.join(self.build_dir,
@@ -40,7 +40,6 @@
       else:
         self.target_mojo_shell_path = self.mojo_shell_path
     else:
-      self.mojo_launcher_path = None
       self.mojo_shell_path = None
       self.target_mojo_shell_path = None
 
diff --git a/mojo/tools/mopy/print_process_error.py b/mojo/tools/mopy/print_process_error.py
new file mode 100644
index 0000000..ec565d1
--- /dev/null
+++ b/mojo/tools/mopy/print_process_error.py
@@ -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.
+
+def print_process_error(command_line, error):
+  """Properly format an exception raised from a failed command execution."""
+
+  if command_line:
+    print 'Failed command: %r' % command_line
+  else:
+    print 'Failed command:'
+  print 72 * '-'
+
+  if hasattr(error, 'returncode'):
+    print '  with exit code %d' % error.returncode
+    print 72 * '-'
+
+  if hasattr(error, 'output'):
+    print error.output
+  else:
+    print error
+  print 72 * '-'
diff --git a/mojo/tools/mopy/test_util.py b/mojo/tools/mopy/test_util.py
new file mode 100644
index 0000000..4a4c128
--- /dev/null
+++ b/mojo/tools/mopy/test_util.py
@@ -0,0 +1,95 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+import os
+import subprocess
+import time
+
+from mopy.config import Config
+from mopy.paths import Paths
+from mopy.print_process_error import print_process_error
+
+
+_logger = logging.getLogger()
+
+
+def build_shell_arguments(shell_args, apps_and_args=None):
+  """Build the list of arguments for the shell. |shell_args| are the base
+  arguments, |apps_and_args| is a dictionary that associates each application to
+  its specific arguments|. Each app included will be run by the shell.
+  """
+  result = shell_args[:]
+  if apps_and_args:
+    # TODO(msw): Mojo's script uses --args-for; Chromium lacks support for that.
+    for app_and_args in apps_and_args.items():
+      result += app_and_args[1]
+    result += apps_and_args.keys()
+  return result
+
+
+def get_shell_executable(config):
+  paths = Paths(config=config)
+  if config.target_os == Config.OS_ANDROID:
+    return os.path.join(paths.src_root, "mojo", "tools",
+                        "android_mojo_shell.py")
+  else:
+    return paths.mojo_shell_path
+
+
+def build_command_line(config, shell_args, apps_and_args):
+  executable = get_shell_executable(config)
+  return "%s %s" % (executable, " ".join(["%r" % x for x in
+                                          build_shell_arguments(
+                                              shell_args, apps_and_args)]))
+
+
+def run_test_android(shell, shell_args, apps_and_args):
+  """Run the given test on the single/default android device."""
+  assert shell
+  (r, w) = os.pipe()
+  with os.fdopen(r, "r") as rf:
+    with os.fdopen(w, "w") as wf:
+      arguments = build_shell_arguments(shell_args, apps_and_args)
+      _logger.debug("Starting shell with arguments: %s" % arguments)
+      start_time = time.time()
+      # TODO(vtl): Do more logging in lower layers.
+      shell.StartShell(arguments, wf, wf.close, False)
+      rv = rf.read()
+      run_time = time.time() - start_time
+      _logger.debug("Shell completed")
+      # Only log if it took more than 3 seconds.
+      if run_time >= 3:
+        _logger.info("Shell test took %.3f seconds; arguments: %s" %
+                     (run_time, arguments))
+      return rv
+
+
+def run_test(config, shell, shell_args, apps_and_args):
+  """Run the given test."""
+  if (config.target_os == Config.OS_ANDROID):
+    return run_test_android(shell, shell_args, apps_and_args)
+
+  executable = get_shell_executable(config)
+  command = ([executable] + build_shell_arguments(shell_args, apps_and_args))
+  _logger.debug("Starting: %s" % " ".join(command))
+  start_time = time.time()
+  rv = subprocess.check_output(command, stderr=subprocess.STDOUT)
+  run_time = time.time() - start_time
+  _logger.debug("Completed: %s" % " ".join(command))
+  # Only log if it took more than 1 second.
+  if run_time >= 1:
+    _logger.info("Test took %.3f seconds: %s" % (run_time, " ".join(command)))
+  return rv
+
+
+def try_run_test(config, shell, shell_args, apps_and_args):
+  """Returns the output of a command line or an empty string on error."""
+  command_line = build_command_line(config, shell_args, apps_and_args)
+  _logger.debug("Running command line: %s" % command_line)
+  try:
+    return run_test(config, shell, shell_args, apps_and_args)
+  except Exception as e:
+    print_process_error(command_line, e)
+  return None
diff --git a/mojo/tools/rev_sdk.py b/mojo/tools/rev_sdk.py
new file mode 100755
index 0000000..c7508683
--- /dev/null
+++ b/mojo/tools/rev_sdk.py
@@ -0,0 +1,69 @@
+#!/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.
+
+"""Tool to roll Mojo into Chromium. See:
+https://github.com/domokit/mojo/wiki/Rolling-code-between-chromium-and-mojo#mojo---chromium-updates-sdk--edk
+"""
+
+import os
+import sys
+from utils import commit
+from utils import mojo_root_dir
+from utils import system
+
+sdk_prefix_in_chromium = "third_party/mojo/src"
+sdk_dirs_to_clone = [
+  "mojo/edk",
+  "mojo/public",
+  "nacl_bindings",
+]
+
+
+services_prefix_in_mojo = "mojo/services"
+services_prefix_in_chromium = "third_party/mojo_services/src"
+
+# A dictionary mapping dirs to clone to their destination locations in Chromium.
+dirs_to_clone = {}
+
+for sdk_dir in sdk_dirs_to_clone:
+  sdk_dir_in_chromium = os.path.join(sdk_prefix_in_chromium, sdk_dir)
+  dirs_to_clone[sdk_dir] = sdk_dir_in_chromium
+
+def rev(source_dir, chromium_dir):
+  src_commit = system(["git", "show-ref", "HEAD", "-s"], cwd=source_dir).strip()
+
+  for input_dir, dest_dir in dirs_to_clone.iteritems():
+    if os.path.exists(os.path.join(chromium_dir, dest_dir)):
+      print "removing directory %s" % dest_dir
+      system(["git", "rm", "-r", dest_dir], cwd=chromium_dir)
+    print "cloning directory %s into %s" % (input_dir, dest_dir)
+    files = system(["git", "ls-files", input_dir], cwd=source_dir)
+    for f in files.splitlines():
+      # Don't copy presubmit files over since the code is read-only on the
+      # chromium side.
+      if os.path.basename(f) == "PRESUBMIT.py":
+        continue
+
+      # Clone |f| into Chromium under |dest_dir| at its location relative to
+      # |input_dir|.
+      f_relpath = os.path.relpath(f, input_dir)
+      dest_path = os.path.join(chromium_dir, dest_dir, f_relpath)
+      system(["mkdir", "-p", os.path.dirname(dest_path)])
+      system(["cp", os.path.join(source_dir, f), dest_path])
+    os.chdir(chromium_dir)
+    system(["git", "add", dest_dir], cwd=chromium_dir)
+
+  mojo_public_dest_dir = os.path.join(sdk_prefix_in_chromium, "mojo/public")
+  version_filename = os.path.join(mojo_public_dest_dir, "VERSION")
+  with open(version_filename, "w") as version_file:
+    version_file.write(src_commit)
+  system(["git", "add", version_filename], cwd=chromium_dir)
+  commit("Update mojo sdk to rev " + src_commit, cwd=chromium_dir)
+
+if len(sys.argv) != 2:
+  print "usage: rev_sdk.py <chromium source dir>"
+  sys.exit(1)
+
+rev(mojo_root_dir, sys.argv[1])
diff --git a/native_client_sdk/native_client_sdk_untrusted.gyp b/native_client_sdk/native_client_sdk_untrusted.gyp
index 140664f..2cd3dc5 100644
--- a/native_client_sdk/native_client_sdk_untrusted.gyp
+++ b/native_client_sdk/native_client_sdk_untrusted.gyp
@@ -35,7 +35,6 @@
             '>!@pymod_do_main(dsc_info -s -l src/libraries/nacl_io nacl_io)',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../ppapi/native_client/native_client.gyp:ppapi_lib',
           ],
         },
diff --git a/net/BUILD.gn b/net/BUILD.gn
index b425371..130a597 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -194,11 +194,7 @@
       "cert/ct_objects_extractor_nss.cc",
       "cert/jwk_serializer_nss.cc",
       "cert/scoped_nss_types.h",
-      "cert/test_root_certs_nss.cc",
       "cert/x509_util_nss.cc",
-      "cert/x509_util_nss.h",
-      "cert_net/nss_ocsp.cc",
-      "cert_net/nss_ocsp.h",
       "quic/crypto/aead_base_decrypter_nss.cc",
       "quic/crypto/aead_base_encrypter_nss.cc",
       "quic/crypto/aes_128_gcm_12_decrypter_nss.cc",
@@ -214,31 +210,6 @@
       "socket/ssl_server_socket_nss.cc",
       "socket/ssl_server_socket_nss.h",
     ]
-    if (is_chromeos) {
-      sources -= [
-        "cert/nss_cert_database_chromeos.cc",
-        "cert/nss_cert_database_chromeos.h",
-        "cert/nss_profile_filter_chromeos.cc",
-        "cert/nss_profile_filter_chromeos.h",
-      ]
-    }
-    if (is_linux) {
-      # These are always removed for non-Linux cases below.
-      sources -= [
-        "base/crypto_module_nss.cc",
-        "base/keygen_handler_nss.cc",
-        "cert/cert_database_nss.cc",
-        "cert/nss_cert_database.cc",
-        "cert/nss_cert_database.h",
-        "cert/x509_certificate_nss.cc",
-        "third_party/mozilla_security_manager/nsKeygenHandler.cpp",
-        "third_party/mozilla_security_manager/nsKeygenHandler.h",
-        "third_party/mozilla_security_manager/nsNSSCertificateDB.cpp",
-        "third_party/mozilla_security_manager/nsNSSCertificateDB.h",
-        "third_party/mozilla_security_manager/nsPKCS12Blob.cpp",
-        "third_party/mozilla_security_manager/nsPKCS12Blob.h",
-      ]
-    }
     if (is_ios) {
       # Always removed for !ios below.
       sources -= [
@@ -249,9 +220,11 @@
     if (is_win) {
       sources -= [ "cert/sha256_legacy_support_nss_win.cc" ]
     }
+    if (!use_nss_certs && !is_ios) {
+      sources -= [ "cert/x509_util_nss.h" ]
+    }
   } else {
     sources -= [
-      "base/crypto_module_openssl.cc",
       "cert/ct_log_verifier_openssl.cc",
       "cert/ct_objects_extractor_openssl.cc",
       "cert/jwk_serializer_openssl.cc",
@@ -272,6 +245,7 @@
       "socket/ssl_server_socket_openssl.cc",
       "socket/ssl_server_socket_openssl.h",
       "ssl/openssl_platform_key.h",
+      "ssl/openssl_platform_key_nss.cc",
       "ssl/openssl_ssl_util.cc",
       "ssl/openssl_ssl_util.h",
       "ssl/ssl_client_session_cache_openssl.cc",
@@ -290,6 +264,7 @@
 
   if (!use_openssl_certs) {
     sources -= [
+      "base/crypto_module_openssl.cc",
       "base/keygen_handler_openssl.cc",
       "base/openssl_private_key_store.h",
       "base/openssl_private_key_store_memory.cc",
@@ -321,7 +296,9 @@
 
   if (is_linux) {
     configs += [ "//build/config/linux:libresolv" ]
-  } else {
+  }
+
+  if (!use_nss_certs) {
     sources -= [
       "base/crypto_module_nss.cc",
       "base/keygen_handler_nss.cc",
@@ -329,6 +306,8 @@
       "cert/nss_cert_database.cc",
       "cert/nss_cert_database.h",
       "cert/x509_certificate_nss.cc",
+      "ssl/client_cert_store_nss.cc",
+      "ssl/client_cert_store_nss.h",
       "third_party/mozilla_security_manager/nsKeygenHandler.cpp",
       "third_party/mozilla_security_manager/nsKeygenHandler.h",
       "third_party/mozilla_security_manager/nsNSSCertificateDB.cpp",
@@ -336,38 +315,37 @@
       "third_party/mozilla_security_manager/nsPKCS12Blob.cpp",
       "third_party/mozilla_security_manager/nsPKCS12Blob.h",
     ]
-
-    if (!is_ios && !use_openssl) {
-      # These files are part of the partial implementation of NSS on iOS so
-      # keep them in that case.
-      sources -= [
-        "cert/test_root_certs_nss.cc",
-        "cert_net/nss_ocsp.cc",
-        "cert_net/nss_ocsp.h",
-      ]
-    }
-  }
-
-  if (!use_nss_certs) {
-    sources -= [
-      "ssl/client_cert_store_nss.cc",
-      "ssl/client_cert_store_nss.h",
-    ]
     if (!is_ios) {
       # These files are part of the partial implementation of NSS on iOS so
       # keep them in that case (even though use_nss_certs is not set).
       sources -= [
         "cert/cert_verify_proc_nss.cc",
         "cert/cert_verify_proc_nss.h",
+        "cert/test_root_certs_nss.cc",
+        "cert/x509_util_nss_certs.cc",
+        "cert_net/nss_ocsp.cc",
+        "cert_net/nss_ocsp.h",
       ]
     }
     if (is_chromeos) {
       # These were already removed on non-ChromeOS.
       sources -= [
+        "cert/nss_cert_database_chromeos.cc",
+        "cert/nss_cert_database_chromeos.h",
+        "cert/nss_profile_filter_chromeos.cc",
+        "cert/nss_profile_filter_chromeos.h",
         "ssl/client_cert_store_chromeos.cc",
         "ssl/client_cert_store_chromeos.h",
       ]
     }
+    if (use_openssl) {
+      sources -= [ "ssl/openssl_platform_key_nss.cc" ]
+    }
+  } else if (use_openssl) {
+    # client_cert_store_nss.c requires NSS_CmpCertChainWCANames from NSS's
+    # libssl, but our bundled copy is not built in OpenSSL ports. Pull that file
+    # in directly.
+    sources += [ "third_party/nss/ssl/cmpcert.c" ]
   }
 
   if (!enable_websockets) {
@@ -460,8 +438,8 @@
   }
 
   if (is_ios) {
-    # Add back some sources that were otherwise filtered out. iOS additionally
-    # doesn't set USE_NSS_CERTS but needs some of the files.
+    # Add back some sources that were otherwise filtered out. iOS needs some Mac
+    # files.
     set_sources_assignment_filter([])
     sources += [
       "base/net_util_mac.cc",
@@ -469,13 +447,6 @@
       "base/network_change_notifier_mac.cc",
       "base/network_config_watcher_mac.cc",
       "base/platform_mime_util_mac.mm",
-      "cert/cert_verify_proc_nss.cc",
-      "cert/cert_verify_proc_nss.h",
-      "cert/test_root_certs_nss.cc",
-      "cert/x509_util_nss.cc",
-      "cert/x509_util_nss.h",
-      "cert_net/nss_ocsp.cc",
-      "cert_net/nss_ocsp.h",
       "proxy/proxy_resolver_mac.cc",
       "proxy/proxy_server_mac.cc",
     ]
@@ -1317,9 +1288,8 @@
 }
 
 # TODO(GYP) make this compile on Android, we need some native test deps done.
-# TODO(GYP) Also doesn't work on Windows; dependency on boringssl is wrong.
 # TODO(GYP) Also doesn't work on Mac, need to figure out why not.
-if (!is_android && !is_win && !is_mac) {
+if (!is_android && !is_mac) {
   test("net_unittests") {
     sources = gypi_values.net_test_sources
 
@@ -1328,11 +1298,11 @@
     defines = []
 
     deps = [
+      ":balsa",
       ":extras",
       ":http_server",
       ":net",
       ":net_quic_proto",
-      ":epoll_quic_tools",
       ":simple_quic_tools",
       ":test_support",
       "//base",
@@ -1352,6 +1322,9 @@
       "//url",
     ]
 
+    if (is_desktop_linux) {
+      deps += [ ":epoll_quic_tools" ]
+    }
     if (is_linux) {
       sources += gypi_values.net_linux_test_sources
       deps += [
@@ -1390,9 +1363,16 @@
     }
 
     if (!use_nss_certs) {
-      sources -= [ "ssl/client_cert_store_nss_unittest.cc" ]
+      sources -= [
+        "cert/nss_cert_database_unittest.cc",
+        "ssl/client_cert_store_nss_unittest.cc",
+      ]
       if (is_chromeos) {  # Already removed for all non-ChromeOS builds.
-        sources -= [ "ssl/client_cert_store_chromeos_unittest.cc" ]
+        sources -= [
+          "cert/nss_cert_database_chromeos_unittest.cc",
+          "cert/nss_profile_filter_chromeos_unittest.cc",
+          "ssl/client_cert_store_chromeos_unittest.cc",
+        ]
       }
     }
 
@@ -1402,17 +1382,9 @@
       # TODO(bulach): Add equivalent tests when the underlying
       #               functionality is ported to OpenSSL.
       sources -= [
-        "cert/nss_cert_database_unittest.cc",
         "cert/x509_util_nss_unittest.cc",
         "quic/test_tools/crypto_test_utils_nss.cc",
       ]
-      if (is_chromeos) {
-        # These were already removed in the non-ChromeOS case.
-        sources -= [
-          "cert/nss_cert_database_chromeos_unittest.cc",
-          "cert/nss_profile_filter_chromeos_unittest.cc",
-        ]
-      }
     } else {
       sources -= [
         "cert/x509_util_openssl_unittest.cc",
@@ -1420,9 +1392,6 @@
         "socket/ssl_client_socket_openssl_unittest.cc",
         "ssl/ssl_client_session_cache_openssl_unittest.cc",
       ]
-      if (!is_desktop_linux && !is_chromeos) {
-        sources -= [ "cert/nss_cert_database_unittest.cc" ]
-      }
     }
 
     if (use_kerberos) {
diff --git a/net/base/address_list.cc b/net/base/address_list.cc
index 02a762bf..a62b5d05 100644
--- a/net/base/address_list.cc
+++ b/net/base/address_list.cc
@@ -15,7 +15,7 @@
 namespace {
 
 base::Value* NetLogAddressListCallback(const AddressList* address_list,
-                                       NetLog::LogLevel log_level) {
+                                       NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::ListValue* list = new base::ListValue();
 
diff --git a/net/base/elements_upload_data_stream_unittest.cc b/net/base/elements_upload_data_stream_unittest.cc
index e2a431c..78229d2 100644
--- a/net/base/elements_upload_data_stream_unittest.cc
+++ b/net/base/elements_upload_data_stream_unittest.cc
@@ -64,13 +64,13 @@
         init_result_(OK),
         read_result_(OK) {}
 
-  virtual ~MockUploadElementReader() {}
+  ~MockUploadElementReader() override {}
 
   // UploadElementReader overrides.
   MOCK_METHOD1(Init, int(const CompletionCallback& callback));
-  virtual uint64 GetContentLength() const override { return content_length_; }
-  virtual uint64 BytesRemaining() const override { return bytes_remaining_; }
-  virtual bool IsInMemory() const override { return is_in_memory_; }
+  uint64 GetContentLength() const override { return content_length_; }
+  uint64 BytesRemaining() const override { return bytes_remaining_; }
+  bool IsInMemory() const override { return is_in_memory_; }
   MOCK_METHOD3(Read, int(IOBuffer* buf,
                          int buf_length,
                          const CompletionCallback& callback));
diff --git a/net/base/network_change_notifier_win_unittest.cc b/net/base/network_change_notifier_win_unittest.cc
index 25873c3..ca59750 100644
--- a/net/base/network_change_notifier_win_unittest.cc
+++ b/net/base/network_change_notifier_win_unittest.cc
@@ -24,15 +24,15 @@
  public:
   TestNetworkChangeNotifierWin() {}
 
-  virtual ~TestNetworkChangeNotifierWin() {
+  ~TestNetworkChangeNotifierWin() override {
     // This is needed so we don't try to stop watching for IP address changes,
     // as we never actually started.
     set_is_watching(false);
   }
 
   // From NetworkChangeNotifierWin.
-  virtual NetworkChangeNotifier::ConnectionType
-      RecomputeCurrentConnectionType() const override {
+  NetworkChangeNotifier::ConnectionType RecomputeCurrentConnectionType()
+      const override {
     return NetworkChangeNotifier::CONNECTION_UNKNOWN;
   }
 
diff --git a/net/base/sdch_net_log_params.cc b/net/base/sdch_net_log_params.cc
index 02e0ad78..a89117ec 100644
--- a/net/base/sdch_net_log_params.cc
+++ b/net/base/sdch_net_log_params.cc
@@ -11,7 +11,7 @@
 namespace net {
 
 base::Value* NetLogSdchResourceProblemCallback(SdchProblemCode problem,
-                                               NetLog::LogLevel log_level) {
+                                               NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("sdch_problem_code", problem);
   dict->SetInteger("net_error", ERR_FAILED);
@@ -22,7 +22,7 @@
     SdchProblemCode problem,
     const GURL& url,
     bool is_error,
-    NetLog::LogLevel log_level) {
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("sdch_problem_code", problem);
   dict->SetString("dictionary_url", url.spec());
diff --git a/net/base/sdch_net_log_params.h b/net/base/sdch_net_log_params.h
index 1849f96..a13d9de 100644
--- a/net/base/sdch_net_log_params.h
+++ b/net/base/sdch_net_log_params.h
@@ -17,7 +17,7 @@
 
 NET_EXPORT base::Value* NetLogSdchResourceProblemCallback(
     SdchProblemCode problem,
-    NetLog::LogLevel log_level);
+    NetLogCaptureMode capture_mode);
 
 // If |is_error| is false, "net_error" field won't be added to the JSON and the
 // event won't be painted red in the netlog.
@@ -25,7 +25,7 @@
     SdchProblemCode problem,
     const GURL& url,
     bool is_error,
-    NetLog::LogLevel log_level);
+    NetLogCaptureMode capture_mode);
 
 }  // namespace net
 
diff --git a/net/cert/cert_policy_enforcer.cc b/net/cert/cert_policy_enforcer.cc
index d4bae50..4c6d38d2 100644
--- a/net/cert/cert_policy_enforcer.cc
+++ b/net/cert/cert_policy_enforcer.cc
@@ -185,11 +185,12 @@
   base::Version whitelist_version;
 };
 
-base::Value* NetLogComplianceCheckResultCallback(X509Certificate* cert,
-                                                 ComplianceDetails* details,
-                                                 NetLog::LogLevel log_level) {
+base::Value* NetLogComplianceCheckResultCallback(
+    X509Certificate* cert,
+    ComplianceDetails* details,
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
-  dict->Set("certificate", NetLogX509CertificateCallback(cert, log_level));
+  dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode));
   dict->SetBoolean("policy_enforcement_required",
                    details->ct_presence_required);
   if (details->ct_presence_required) {
diff --git a/net/cert/ct_known_logs_static.h b/net/cert/ct_known_logs_static.h
index 25356520..0163caa 100644
--- a/net/cert/ct_known_logs_static.h
+++ b/net/cert/ct_known_logs_static.h
@@ -12,48 +12,49 @@
 };
 
 const CTLogInfo kCTLogList[] = {
-  {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
-    "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7d\xa8\x4b\x12\x29\x80\xa3"
-    "\x3d\xad\xd3\x5a\x77\xb8\xcc\xe2\x88\xb3\xa5\xfd\xf1\xd3\x0c\xcd\x18"
-    "\x0c\xe8\x41\x46\xe8\x81\x01\x1b\x15\xe1\x4b\xf1\x1b\x62\xdd\x36\x0a"
-    "\x08\x18\xba\xed\x0b\x35\x84\xd0\x9e\x40\x3c\x2d\x9e\x9b\x82\x65\xbd"
-    "\x1f\x04\x10\x41\x4c\xa0",
-    "Google 'Pilot' log"
-  },
-  {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
-    "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xf4\xcc\x69\xb2\xe4\x0e"
-    "\x90\xa3\x8a\xea\x5a\x70\x09\x4f\xef\x13\x62\xd0\x8d\x49\x60\xff\x1b"
-    "\x40\x50\x07\x0c\x6d\x71\x86\xda\x25\x49\x8d\x65\xe1\x08\x0d\x47\x34"
-    "\x6b\xbd\x27\xbc\x96\x21\x3e\x34\xf5\x87\x76\x31\xb1\x7f\x1d\xc9\x85"
-    "\x3b\x0d\xf7\x1f\x3f\xe9",
-    "Google 'Aviator' log"
-  },
-  {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
-    "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x02\x46\xc5\xbe\x1b\xbb\x82"
-    "\x40\x16\xe8\xc1\xd2\xac\x19\x69\x13\x59\xf8\xf8\x70\x85\x46\x40\xb9"
-    "\x38\xb0\x23\x82\xa8\x64\x4c\x7f\xbf\xbb\x34\x9f\x4a\x5f\x28\x8a\xcf"
-    "\x19\xc4\x00\xf6\x36\x06\x93\x65\xed\x4c\xf5\xa9\x21\x62\x5a\xd8\x91"
-    "\xeb\x38\x24\x40\xac\xe8",
-    "DigiCert Log Server"
-  },
-  {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
-    "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x5b\x18\xc8\x3c\xc1\x8b"
-    "\xb3\x31\x08\x00\xbf\xa0\x90\x57\x2b\xb7\x47\x8c\x6f\xb5\x68\xb0\x8e"
-    "\x90\x78\xe9\xa0\x73\xea\x4f\x28\x21\x2e\x9c\xc0\xf4\x16\x1b\xaa\xf9"
-    "\xd5\xd7\xa9\x80\xc3\x4e\x2f\x52\x3c\x98\x01\x25\x46\x24\x25\x28\x23"
-    "\x77\x2d\x05\xc2\x40\x7a",
-    "Google 'Rocketeer' log"
-  },
-  {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
-    "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x0b\x23\xcb\x85\x62\x98\x61"
-    "\x48\x04\x73\xeb\x54\x5d\xf3\xd0\x07\x8c\x2d\x19\x2d\x8c\x36\xf5\xeb"
-    "\x8f\x01\x42\x0a\x7c\x98\x26\x27\xc1\xb5\xdd\x92\x93\xb0\xae\xf8\x9b"
-    "\x3d\x0c\xd8\x4c\x4e\x1d\xf9\x15\xfb\x47\x68\x7b\xba\x66\xb7\x25\x9c"
-    "\xd0\x4a\xc2\x66\xdb\x48",
-    "Certly.IO log"
-  }
-};
+    {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
+     "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7d\xa8\x4b\x12\x29\x80\xa3"
+     "\x3d\xad\xd3\x5a\x77\xb8\xcc\xe2\x88\xb3\xa5\xfd\xf1\xd3\x0c\xcd\x18"
+     "\x0c\xe8\x41\x46\xe8\x81\x01\x1b\x15\xe1\x4b\xf1\x1b\x62\xdd\x36\x0a"
+     "\x08\x18\xba\xed\x0b\x35\x84\xd0\x9e\x40\x3c\x2d\x9e\x9b\x82\x65\xbd"
+     "\x1f\x04\x10\x41\x4c\xa0",
+     "Google 'Pilot' log"},
+    {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
+     "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xf4\xcc\x69\xb2\xe4\x0e"
+     "\x90\xa3\x8a\xea\x5a\x70\x09\x4f\xef\x13\x62\xd0\x8d\x49\x60\xff\x1b"
+     "\x40\x50\x07\x0c\x6d\x71\x86\xda\x25\x49\x8d\x65\xe1\x08\x0d\x47\x34"
+     "\x6b\xbd\x27\xbc\x96\x21\x3e\x34\xf5\x87\x76\x31\xb1\x7f\x1d\xc9\x85"
+     "\x3b\x0d\xf7\x1f\x3f\xe9",
+     "Google 'Aviator' log"},
+    {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
+     "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x02\x46\xc5\xbe\x1b\xbb\x82"
+     "\x40\x16\xe8\xc1\xd2\xac\x19\x69\x13\x59\xf8\xf8\x70\x85\x46\x40\xb9"
+     "\x38\xb0\x23\x82\xa8\x64\x4c\x7f\xbf\xbb\x34\x9f\x4a\x5f\x28\x8a\xcf"
+     "\x19\xc4\x00\xf6\x36\x06\x93\x65\xed\x4c\xf5\xa9\x21\x62\x5a\xd8\x91"
+     "\xeb\x38\x24\x40\xac\xe8",
+     "DigiCert Log Server"},
+    {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
+     "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x5b\x18\xc8\x3c\xc1\x8b"
+     "\xb3\x31\x08\x00\xbf\xa0\x90\x57\x2b\xb7\x47\x8c\x6f\xb5\x68\xb0\x8e"
+     "\x90\x78\xe9\xa0\x73\xea\x4f\x28\x21\x2e\x9c\xc0\xf4\x16\x1b\xaa\xf9"
+     "\xd5\xd7\xa9\x80\xc3\x4e\x2f\x52\x3c\x98\x01\x25\x46\x24\x25\x28\x23"
+     "\x77\x2d\x05\xc2\x40\x7a",
+     "Google 'Rocketeer' log"},
+    {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
+     "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x0b\x23\xcb\x85\x62\x98\x61"
+     "\x48\x04\x73\xeb\x54\x5d\xf3\xd0\x07\x8c\x2d\x19\x2d\x8c\x36\xf5\xeb"
+     "\x8f\x01\x42\x0a\x7c\x98\x26\x27\xc1\xb5\xdd\x92\x93\xb0\xae\xf8\x9b"
+     "\x3d\x0c\xd8\x4c\x4e\x1d\xf9\x15\xfb\x47\x68\x7b\xba\x66\xb7\x25\x9c"
+     "\xd0\x4a\xc2\x66\xdb\x48",
+     "Certly.IO log"},
+    {"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86"
+     "\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x27\x64\x39\x0c\x2d\xdc\x50"
+     "\x18\xf8\x21\x00\xa2\x0e\xed\x2c\xea\x3e\x75\xba\x9f\x93\x64\x09\x00"
+     "\x11\xc4\x11\x17\xab\x5c\xcf\x0f\x74\xac\xb5\x97\x90\x93\x00\x5b\xb8"
+     "\xeb\xf7\x27\x3d\xd9\xb2\x0a\x81\x5f\x2f\x0d\x75\x38\x94\x37\x99\x1e"
+     "\xf6\x07\x76\xe0\xee\xbe",
+     "Izenpe log"}};
 
-const size_t kNumKnownCTLogs = 5;
+const size_t kNumKnownCTLogs = 6;
 
 #endif  // NET_CERT_CT_KNOWN_LOGS_STATIC_H_
diff --git a/net/cert/ct_signed_certificate_timestamp_log_param.cc b/net/cert/ct_signed_certificate_timestamp_log_param.cc
index e7bb97c..71c8469f 100644
--- a/net/cert/ct_signed_certificate_timestamp_log_param.cc
+++ b/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -129,7 +129,8 @@
 }  // namespace
 
 base::Value* NetLogSignedCertificateTimestampCallback(
-    const ct::CTVerifyResult* ct_result, NetLog::LogLevel log_level) {
+    const ct::CTVerifyResult* ct_result,
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->Set("verified_scts",
@@ -148,7 +149,7 @@
     const std::string* embedded_scts,
     const std::string* sct_list_from_ocsp,
     const std::string* sct_list_from_tls_extension,
-    NetLog::LogLevel log_level) {
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   SetBinaryData("embedded_scts", *embedded_scts, dict);
diff --git a/net/cert/ct_signed_certificate_timestamp_log_param.h b/net/cert/ct_signed_certificate_timestamp_log_param.h
index 5c4db191..25e1fb5 100644
--- a/net/cert/ct_signed_certificate_timestamp_log_param.h
+++ b/net/cert/ct_signed_certificate_timestamp_log_param.h
@@ -18,7 +18,8 @@
 // See the documentation for SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED
 // in net/log/net_log_event_type_list.h
 base::Value* NetLogSignedCertificateTimestampCallback(
-    const ct::CTVerifyResult* ct_result, NetLog::LogLevel log_level);
+    const ct::CTVerifyResult* ct_result,
+    NetLogCaptureMode capture_mode);
 
 // Creates a dictionary of raw Signed Certificate Timestamps to be logged
 // in the NetLog.
@@ -28,7 +29,7 @@
     const std::string* embedded_scts,
     const std::string* sct_list_from_ocsp,
     const std::string* sct_list_from_tls_extension,
-    NetLog::LogLevel log_level);
+    NetLogCaptureMode capture_mode);
 
 }  // namespace net
 
diff --git a/net/cert/ev_root_ca_metadata_unittest.cc b/net/cert/ev_root_ca_metadata_unittest.cc
index 39699e26..9da0064 100644
--- a/net/cert/ev_root_ca_metadata_unittest.cc
+++ b/net/cert/ev_root_ca_metadata_unittest.cc
@@ -9,6 +9,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(USE_NSS_CERTS)
+#include "crypto/nss_util.h"
 #include "crypto/scoped_nss_types.h"
 #endif
 
@@ -63,6 +64,7 @@
 }
 
 bool EVOidData::Init() {
+  crypto::EnsureNSSInit();
   crypto::ScopedPLArenaPool pool(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
   if (!pool.get())
     return false;
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc
index 9e78abb..128987f 100644
--- a/net/cert/multi_threaded_cert_verifier.cc
+++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -82,7 +82,7 @@
 const unsigned kTTLSecs = 1800;  // 30 minutes.
 
 base::Value* CertVerifyResultCallback(const CertVerifyResult& verify_result,
-                                      NetLog::LogLevel log_level) {
+                                      NetLogCaptureMode capture_mode) {
   base::DictionaryValue* results = new base::DictionaryValue();
   results->SetBoolean("has_md5", verify_result.has_md5);
   results->SetBoolean("has_md2", verify_result.has_md2);
@@ -96,7 +96,7 @@
   results->SetInteger("cert_status", verify_result.cert_status);
   results->Set("verified_cert",
                NetLogX509CertificateCallback(verify_result.verified_cert.get(),
-                                             log_level));
+                                             capture_mode));
 
   base::ListValue* hashes = new base::ListValue();
   for (std::vector<HashValue>::const_iterator it =
diff --git a/net/cert/x509_certificate_net_log_param.cc b/net/cert/x509_certificate_net_log_param.cc
index 3c52b96..a9445c6 100644
--- a/net/cert/x509_certificate_net_log_param.cc
+++ b/net/cert/x509_certificate_net_log_param.cc
@@ -13,7 +13,7 @@
 namespace net {
 
 base::Value* NetLogX509CertificateCallback(const X509Certificate* certificate,
-                                           NetLog::LogLevel log_level) {
+                                           NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::ListValue* certs = new base::ListValue();
   std::vector<std::string> encoded_chain;
diff --git a/net/cert/x509_certificate_net_log_param.h b/net/cert/x509_certificate_net_log_param.h
index 822cb53..9e3e3a9 100644
--- a/net/cert/x509_certificate_net_log_param.h
+++ b/net/cert/x509_certificate_net_log_param.h
@@ -12,9 +12,8 @@
 class X509Certificate;
 
 // Creates NetLog parameter to describe an X509Certificate.
-base::Value* NetLogX509CertificateCallback(
-    const X509Certificate* certificate,
-    NetLog::LogLevel log_level);
+base::Value* NetLogX509CertificateCallback(const X509Certificate* certificate,
+                                           NetLogCaptureMode capture_mode);
 
 }  // namespace net
 
diff --git a/net/cert/x509_util_nss.cc b/net/cert/x509_util_nss.cc
index 9711ef6..ecdf08b 100644
--- a/net/cert/x509_util_nss.cc
+++ b/net/cert/x509_util_nss.cc
@@ -194,58 +194,6 @@
   return true;
 }
 
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
-// Callback for CERT_DecodeCertPackage(), used in
-// CreateOSCertHandlesFromBytes().
-SECStatus PR_CALLBACK CollectCertsCallback(void* arg,
-                                           SECItem** certs,
-                                           int num_certs) {
-  X509Certificate::OSCertHandles* results =
-      reinterpret_cast<X509Certificate::OSCertHandles*>(arg);
-
-  for (int i = 0; i < num_certs; ++i) {
-    X509Certificate::OSCertHandle handle =
-        X509Certificate::CreateOSCertHandleFromBytes(
-            reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
-    if (handle)
-      results->push_back(handle);
-  }
-
-  return SECSuccess;
-}
-
-typedef scoped_ptr<
-    CERTName,
-    crypto::NSSDestroyer<CERTName, CERT_DestroyName> > ScopedCERTName;
-
-// Create a new CERTName object from its encoded representation.
-// |arena| is the allocation pool to use.
-// |data| points to a DER-encoded X.509 DistinguishedName.
-// Return a new CERTName pointer on success, or NULL.
-CERTName* CreateCertNameFromEncoded(PLArenaPool* arena,
-                                    const base::StringPiece& data) {
-  if (!arena)
-    return NULL;
-
-  ScopedCERTName name(PORT_ArenaZNew(arena, CERTName));
-  if (!name.get())
-    return NULL;
-
-  SECItem item;
-  item.len = static_cast<unsigned int>(data.length());
-  item.data = reinterpret_cast<unsigned char*>(
-      const_cast<char*>(data.data()));
-
-  SECStatus rv = SEC_ASN1DecodeItem(
-      arena, name.get(), SEC_ASN1_GET(CERT_NameTemplate), &item);
-  if (rv != SECSuccess)
-    return NULL;
-
-  return name.release();
-}
-
-#endif  // defined(USE_NSS_CERTS) || defined(OS_IOS)
-
 }  // namespace
 
 namespace x509_util {
@@ -368,271 +316,6 @@
   return true;
 }
 
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
-void ParsePrincipal(CERTName* name, CertPrincipal* principal) {
-// Starting in NSS 3.15, CERTGetNameFunc takes a const CERTName* argument.
-#if NSS_VMINOR >= 15
-  typedef char* (*CERTGetNameFunc)(const CERTName* name);
-#else
-  typedef char* (*CERTGetNameFunc)(CERTName* name);
-#endif
-
-  // TODO(jcampan): add business_category and serial_number.
-  // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and
-  // CERT_GetDomainComponentName functions, but they return only the most
-  // general (the first) RDN.  NSS doesn't have a function for the street
-  // address.
-  static const SECOidTag kOIDs[] = {
-    SEC_OID_AVA_STREET_ADDRESS,
-    SEC_OID_AVA_ORGANIZATION_NAME,
-    SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
-    SEC_OID_AVA_DC };
-
-  std::vector<std::string>* values[] = {
-    &principal->street_addresses,
-    &principal->organization_names,
-    &principal->organization_unit_names,
-    &principal->domain_components };
-  DCHECK_EQ(arraysize(kOIDs), arraysize(values));
-
-  CERTRDN** rdns = name->rdns;
-  for (size_t rdn = 0; rdns[rdn]; ++rdn) {
-    CERTAVA** avas = rdns[rdn]->avas;
-    for (size_t pair = 0; avas[pair] != 0; ++pair) {
-      SECOidTag tag = CERT_GetAVATag(avas[pair]);
-      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
-        if (kOIDs[oid] == tag) {
-          SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
-          if (!decode_item)
-            break;
-          // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
-          std::string value(reinterpret_cast<char*>(decode_item->data),
-                            decode_item->len);
-          values[oid]->push_back(value);
-          SECITEM_FreeItem(decode_item, PR_TRUE);
-          break;
-        }
-      }
-    }
-  }
-
-  // Get CN, L, S, and C.
-  CERTGetNameFunc get_name_funcs[4] = {
-    CERT_GetCommonName, CERT_GetLocalityName,
-    CERT_GetStateName, CERT_GetCountryName };
-  std::string* single_values[4] = {
-    &principal->common_name, &principal->locality_name,
-    &principal->state_or_province_name, &principal->country_name };
-  for (size_t i = 0; i < arraysize(get_name_funcs); ++i) {
-    char* value = get_name_funcs[i](name);
-    if (value) {
-      single_values[i]->assign(value);
-      PORT_Free(value);
-    }
-  }
-}
-
-void ParseDate(const SECItem* der_date, base::Time* result) {
-  PRTime prtime;
-  SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
-  DCHECK_EQ(SECSuccess, rv);
-  *result = crypto::PRTimeToBaseTime(prtime);
-}
-
-std::string ParseSerialNumber(const CERTCertificate* certificate) {
-  return std::string(reinterpret_cast<char*>(certificate->serialNumber.data),
-                     certificate->serialNumber.len);
-}
-
-void GetSubjectAltName(CERTCertificate* cert_handle,
-                       std::vector<std::string>* dns_names,
-                       std::vector<std::string>* ip_addrs) {
-  if (dns_names)
-    dns_names->clear();
-  if (ip_addrs)
-    ip_addrs->clear();
-
-  SECItem alt_name;
-  SECStatus rv = CERT_FindCertExtension(cert_handle,
-                                        SEC_OID_X509_SUBJECT_ALT_NAME,
-                                        &alt_name);
-  if (rv != SECSuccess)
-    return;
-
-  PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-  DCHECK(arena != NULL);
-
-  CERTGeneralName* alt_name_list;
-  alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
-  SECITEM_FreeItem(&alt_name, PR_FALSE);
-
-  CERTGeneralName* name = alt_name_list;
-  while (name) {
-    // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs
-    // respectively, both of which can be byte copied from
-    // SECItemType::data into the appropriate output vector.
-    if (dns_names && name->type == certDNSName) {
-      dns_names->push_back(std::string(
-          reinterpret_cast<char*>(name->name.other.data),
-          name->name.other.len));
-    } else if (ip_addrs && name->type == certIPAddress) {
-      ip_addrs->push_back(std::string(
-          reinterpret_cast<char*>(name->name.other.data),
-          name->name.other.len));
-    }
-    name = CERT_GetNextGeneralName(name);
-    if (name == alt_name_list)
-      break;
-  }
-  PORT_FreeArena(arena, PR_FALSE);
-}
-
-X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
-    const char* data,
-    int length,
-    X509Certificate::Format format) {
-  X509Certificate::OSCertHandles results;
-  if (length < 0)
-    return results;
-
-  crypto::EnsureNSSInit();
-
-  if (!NSS_IsInitialized())
-    return results;
-
-  switch (format) {
-    case X509Certificate::FORMAT_SINGLE_CERTIFICATE: {
-      X509Certificate::OSCertHandle handle =
-          X509Certificate::CreateOSCertHandleFromBytes(data, length);
-      if (handle)
-        results.push_back(handle);
-      break;
-    }
-    case X509Certificate::FORMAT_PKCS7: {
-      // Make a copy since CERT_DecodeCertPackage may modify it
-      std::vector<char> data_copy(data, data + length);
-
-      SECStatus result = CERT_DecodeCertPackage(&data_copy[0],
-          length, CollectCertsCallback, &results);
-      if (result != SECSuccess)
-        results.clear();
-      break;
-    }
-    default:
-      NOTREACHED() << "Certificate format " << format << " unimplemented";
-      break;
-  }
-
-  return results;
-}
-
-X509Certificate::OSCertHandle ReadOSCertHandleFromPickle(
-    PickleIterator* pickle_iter) {
-  const char* data;
-  int length;
-  if (!pickle_iter->ReadData(&data, &length))
-    return NULL;
-
-  return X509Certificate::CreateOSCertHandleFromBytes(data, length);
-}
-
-void GetPublicKeyInfo(CERTCertificate* handle,
-                      size_t* size_bits,
-                      X509Certificate::PublicKeyType* type) {
-  // Since we might fail, set the output parameters to default values first.
-  *type = X509Certificate::kPublicKeyTypeUnknown;
-  *size_bits = 0;
-
-  crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(handle));
-  if (!key.get())
-    return;
-
-  *size_bits = SECKEY_PublicKeyStrengthInBits(key.get());
-
-  switch (key->keyType) {
-    case rsaKey:
-      *type = X509Certificate::kPublicKeyTypeRSA;
-      break;
-    case dsaKey:
-      *type = X509Certificate::kPublicKeyTypeDSA;
-      break;
-    case dhKey:
-      *type = X509Certificate::kPublicKeyTypeDH;
-      break;
-    case ecKey:
-      *type = X509Certificate::kPublicKeyTypeECDSA;
-      break;
-    default:
-      *type = X509Certificate::kPublicKeyTypeUnknown;
-      *size_bits = 0;
-      break;
-  }
-}
-
-bool GetIssuersFromEncodedList(
-    const std::vector<std::string>& encoded_issuers,
-    PLArenaPool* arena,
-    std::vector<CERTName*>* out) {
-  std::vector<CERTName*> result;
-  for (size_t n = 0; n < encoded_issuers.size(); ++n) {
-    CERTName* name = CreateCertNameFromEncoded(arena, encoded_issuers[n]);
-    if (name != NULL)
-      result.push_back(name);
-  }
-
-  if (result.size() == encoded_issuers.size()) {
-    out->swap(result);
-    return true;
-  }
-
-  for (size_t n = 0; n < result.size(); ++n)
-    CERT_DestroyName(result[n]);
-  return false;
-}
-
-
-bool IsCertificateIssuedBy(const std::vector<CERTCertificate*>& cert_chain,
-                           const std::vector<CERTName*>& valid_issuers) {
-  for (size_t n = 0; n < cert_chain.size(); ++n) {
-    CERTName* cert_issuer = &cert_chain[n]->issuer;
-    for (size_t i = 0; i < valid_issuers.size(); ++i) {
-      if (CERT_CompareName(valid_issuers[i], cert_issuer) == SECEqual)
-        return true;
-    }
-  }
-  return false;
-}
-
-std::string GetUniqueNicknameForSlot(const std::string& nickname,
-                                     const SECItem* subject,
-                                     PK11SlotInfo* slot) {
-  int index = 2;
-  std::string new_name = nickname;
-  std::string temp_nickname = new_name;
-  std::string token_name;
-
-  if (!slot)
-    return new_name;
-
-  if (!PK11_IsInternalKeySlot(slot)) {
-    token_name.assign(PK11_GetTokenName(slot));
-    token_name.append(":");
-
-    temp_nickname = token_name + new_name;
-  }
-
-  while (SEC_CertNicknameConflict(temp_nickname.c_str(),
-                                  const_cast<SECItem*>(subject),
-                                  CERT_GetDefaultCertDB())) {
-    base::SStringPrintf(&new_name, "%s #%d", nickname.c_str(), index++);
-    temp_nickname = token_name + new_name;
-  }
-
-  return new_name;
-}
-
-#endif  // defined(USE_NSS_CERTS) || defined(OS_IOS)
-
 } // namespace x509_util
 
 } // namespace net
diff --git a/net/cert/x509_util_nss_certs.cc b/net/cert/x509_util_nss_certs.cc
new file mode 100644
index 0000000..b308355
--- /dev/null
+++ b/net/cert/x509_util_nss_certs.cc
@@ -0,0 +1,346 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cert.h>  // Must be included before certdb.h
+#include <certdb.h>
+#include <cryptohi.h>
+#include <nss.h>
+#include <pk11pub.h>
+#include <prerror.h>
+#include <secder.h>
+#include <secmod.h>
+#include <secport.h>
+
+#include "base/debug/leak_annotations.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+#include "base/pickle.h"
+#include "base/strings/stringprintf.h"
+#include "crypto/ec_private_key.h"
+#include "crypto/nss_util.h"
+#include "crypto/nss_util_internal.h"
+#include "crypto/rsa_private_key.h"
+#include "crypto/scoped_nss_types.h"
+#include "crypto/third_party/nss/chromium-nss.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
+#include "net/cert/x509_util_nss.h"
+
+namespace net {
+
+namespace {
+
+// Callback for CERT_DecodeCertPackage(), used in
+// CreateOSCertHandlesFromBytes().
+SECStatus PR_CALLBACK
+CollectCertsCallback(void* arg, SECItem** certs, int num_certs) {
+  X509Certificate::OSCertHandles* results =
+      reinterpret_cast<X509Certificate::OSCertHandles*>(arg);
+
+  for (int i = 0; i < num_certs; ++i) {
+    X509Certificate::OSCertHandle handle =
+        X509Certificate::CreateOSCertHandleFromBytes(
+            reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
+    if (handle)
+      results->push_back(handle);
+  }
+
+  return SECSuccess;
+}
+
+typedef scoped_ptr<CERTName, crypto::NSSDestroyer<CERTName, CERT_DestroyName>>
+    ScopedCERTName;
+
+// Create a new CERTName object from its encoded representation.
+// |arena| is the allocation pool to use.
+// |data| points to a DER-encoded X.509 DistinguishedName.
+// Return a new CERTName pointer on success, or NULL.
+CERTName* CreateCertNameFromEncoded(PLArenaPool* arena,
+                                    const base::StringPiece& data) {
+  if (!arena)
+    return NULL;
+
+  ScopedCERTName name(PORT_ArenaZNew(arena, CERTName));
+  if (!name.get())
+    return NULL;
+
+  SECItem item;
+  item.len = static_cast<unsigned int>(data.length());
+  item.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data.data()));
+
+  SECStatus rv = SEC_ASN1DecodeItem(arena, name.get(),
+                                    SEC_ASN1_GET(CERT_NameTemplate), &item);
+  if (rv != SECSuccess)
+    return NULL;
+
+  return name.release();
+}
+
+}  // namespace
+
+namespace x509_util {
+
+void ParsePrincipal(CERTName* name, CertPrincipal* principal) {
+// Starting in NSS 3.15, CERTGetNameFunc takes a const CERTName* argument.
+#if NSS_VMINOR >= 15
+  typedef char* (*CERTGetNameFunc)(const CERTName* name);
+#else
+  typedef char* (*CERTGetNameFunc)(CERTName* name);
+#endif
+
+  // TODO(jcampan): add business_category and serial_number.
+  // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and
+  // CERT_GetDomainComponentName functions, but they return only the most
+  // general (the first) RDN.  NSS doesn't have a function for the street
+  // address.
+  static const SECOidTag kOIDs[] = {SEC_OID_AVA_STREET_ADDRESS,
+                                    SEC_OID_AVA_ORGANIZATION_NAME,
+                                    SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
+                                    SEC_OID_AVA_DC};
+
+  std::vector<std::string>* values[] = {&principal->street_addresses,
+                                        &principal->organization_names,
+                                        &principal->organization_unit_names,
+                                        &principal->domain_components};
+  DCHECK_EQ(arraysize(kOIDs), arraysize(values));
+
+  CERTRDN** rdns = name->rdns;
+  for (size_t rdn = 0; rdns[rdn]; ++rdn) {
+    CERTAVA** avas = rdns[rdn]->avas;
+    for (size_t pair = 0; avas[pair] != 0; ++pair) {
+      SECOidTag tag = CERT_GetAVATag(avas[pair]);
+      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
+        if (kOIDs[oid] == tag) {
+          SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
+          if (!decode_item)
+            break;
+          // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
+          std::string value(reinterpret_cast<char*>(decode_item->data),
+                            decode_item->len);
+          values[oid]->push_back(value);
+          SECITEM_FreeItem(decode_item, PR_TRUE);
+          break;
+        }
+      }
+    }
+  }
+
+  // Get CN, L, S, and C.
+  CERTGetNameFunc get_name_funcs[4] = {CERT_GetCommonName,
+                                       CERT_GetLocalityName,
+                                       CERT_GetStateName,
+                                       CERT_GetCountryName};
+  std::string* single_values[4] = {&principal->common_name,
+                                   &principal->locality_name,
+                                   &principal->state_or_province_name,
+                                   &principal->country_name};
+  for (size_t i = 0; i < arraysize(get_name_funcs); ++i) {
+    char* value = get_name_funcs[i](name);
+    if (value) {
+      single_values[i]->assign(value);
+      PORT_Free(value);
+    }
+  }
+}
+
+void ParseDate(const SECItem* der_date, base::Time* result) {
+  PRTime prtime;
+  SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
+  DCHECK_EQ(SECSuccess, rv);
+  *result = crypto::PRTimeToBaseTime(prtime);
+}
+
+std::string ParseSerialNumber(const CERTCertificate* certificate) {
+  return std::string(reinterpret_cast<char*>(certificate->serialNumber.data),
+                     certificate->serialNumber.len);
+}
+
+void GetSubjectAltName(CERTCertificate* cert_handle,
+                       std::vector<std::string>* dns_names,
+                       std::vector<std::string>* ip_addrs) {
+  if (dns_names)
+    dns_names->clear();
+  if (ip_addrs)
+    ip_addrs->clear();
+
+  SECItem alt_name;
+  SECStatus rv = CERT_FindCertExtension(
+      cert_handle, SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name);
+  if (rv != SECSuccess)
+    return;
+
+  PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+  DCHECK(arena != NULL);
+
+  CERTGeneralName* alt_name_list;
+  alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
+  SECITEM_FreeItem(&alt_name, PR_FALSE);
+
+  CERTGeneralName* name = alt_name_list;
+  while (name) {
+    // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs
+    // respectively, both of which can be byte copied from
+    // SECItemType::data into the appropriate output vector.
+    if (dns_names && name->type == certDNSName) {
+      dns_names->push_back(
+          std::string(reinterpret_cast<char*>(name->name.other.data),
+                      name->name.other.len));
+    } else if (ip_addrs && name->type == certIPAddress) {
+      ip_addrs->push_back(
+          std::string(reinterpret_cast<char*>(name->name.other.data),
+                      name->name.other.len));
+    }
+    name = CERT_GetNextGeneralName(name);
+    if (name == alt_name_list)
+      break;
+  }
+  PORT_FreeArena(arena, PR_FALSE);
+}
+
+X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
+    const char* data,
+    int length,
+    X509Certificate::Format format) {
+  X509Certificate::OSCertHandles results;
+  if (length < 0)
+    return results;
+
+  crypto::EnsureNSSInit();
+
+  if (!NSS_IsInitialized())
+    return results;
+
+  switch (format) {
+    case X509Certificate::FORMAT_SINGLE_CERTIFICATE: {
+      X509Certificate::OSCertHandle handle =
+          X509Certificate::CreateOSCertHandleFromBytes(data, length);
+      if (handle)
+        results.push_back(handle);
+      break;
+    }
+    case X509Certificate::FORMAT_PKCS7: {
+      // Make a copy since CERT_DecodeCertPackage may modify it
+      std::vector<char> data_copy(data, data + length);
+
+      SECStatus result = CERT_DecodeCertPackage(&data_copy[0], length,
+                                                CollectCertsCallback, &results);
+      if (result != SECSuccess)
+        results.clear();
+      break;
+    }
+    default:
+      NOTREACHED() << "Certificate format " << format << " unimplemented";
+      break;
+  }
+
+  return results;
+}
+
+X509Certificate::OSCertHandle ReadOSCertHandleFromPickle(
+    PickleIterator* pickle_iter) {
+  const char* data;
+  int length;
+  if (!pickle_iter->ReadData(&data, &length))
+    return NULL;
+
+  return X509Certificate::CreateOSCertHandleFromBytes(data, length);
+}
+
+void GetPublicKeyInfo(CERTCertificate* handle,
+                      size_t* size_bits,
+                      X509Certificate::PublicKeyType* type) {
+  // Since we might fail, set the output parameters to default values first.
+  *type = X509Certificate::kPublicKeyTypeUnknown;
+  *size_bits = 0;
+
+  crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(handle));
+  if (!key.get())
+    return;
+
+  *size_bits = SECKEY_PublicKeyStrengthInBits(key.get());
+
+  switch (key->keyType) {
+    case rsaKey:
+      *type = X509Certificate::kPublicKeyTypeRSA;
+      break;
+    case dsaKey:
+      *type = X509Certificate::kPublicKeyTypeDSA;
+      break;
+    case dhKey:
+      *type = X509Certificate::kPublicKeyTypeDH;
+      break;
+    case ecKey:
+      *type = X509Certificate::kPublicKeyTypeECDSA;
+      break;
+    default:
+      *type = X509Certificate::kPublicKeyTypeUnknown;
+      *size_bits = 0;
+      break;
+  }
+}
+
+bool GetIssuersFromEncodedList(const std::vector<std::string>& encoded_issuers,
+                               PLArenaPool* arena,
+                               std::vector<CERTName*>* out) {
+  std::vector<CERTName*> result;
+  for (size_t n = 0; n < encoded_issuers.size(); ++n) {
+    CERTName* name = CreateCertNameFromEncoded(arena, encoded_issuers[n]);
+    if (name != NULL)
+      result.push_back(name);
+  }
+
+  if (result.size() == encoded_issuers.size()) {
+    out->swap(result);
+    return true;
+  }
+
+  for (size_t n = 0; n < result.size(); ++n)
+    CERT_DestroyName(result[n]);
+  return false;
+}
+
+bool IsCertificateIssuedBy(const std::vector<CERTCertificate*>& cert_chain,
+                           const std::vector<CERTName*>& valid_issuers) {
+  for (size_t n = 0; n < cert_chain.size(); ++n) {
+    CERTName* cert_issuer = &cert_chain[n]->issuer;
+    for (size_t i = 0; i < valid_issuers.size(); ++i) {
+      if (CERT_CompareName(valid_issuers[i], cert_issuer) == SECEqual)
+        return true;
+    }
+  }
+  return false;
+}
+
+std::string GetUniqueNicknameForSlot(const std::string& nickname,
+                                     const SECItem* subject,
+                                     PK11SlotInfo* slot) {
+  int index = 2;
+  std::string new_name = nickname;
+  std::string temp_nickname = new_name;
+  std::string token_name;
+
+  if (!slot)
+    return new_name;
+
+  if (!PK11_IsInternalKeySlot(slot)) {
+    token_name.assign(PK11_GetTokenName(slot));
+    token_name.append(":");
+
+    temp_nickname = token_name + new_name;
+  }
+
+  while (SEC_CertNicknameConflict(temp_nickname.c_str(),
+                                  const_cast<SECItem*>(subject),
+                                  CERT_GetDefaultCertDB())) {
+    base::SStringPrintf(&new_name, "%s #%d", nickname.c_str(), index++);
+    temp_nickname = token_name + new_name;
+  }
+
+  return new_name;
+}
+
+}  // namespace x509_util
+
+}  // namespace net
diff --git a/net/cert_net/cert_net_fetcher_impl.cc b/net/cert_net/cert_net_fetcher_impl.cc
index 7b119ca..51947e32 100644
--- a/net/cert_net/cert_net_fetcher_impl.cc
+++ b/net/cert_net/cert_net_fetcher_impl.cc
@@ -272,7 +272,7 @@
 
   // If there are no longer any requests attached to the job then
   // cancel and delete it.
-  if (requests_.empty())
+  if (requests_.empty() && !parent_->IsCurrentlyCompletingJob(this))
     delete_this = parent_->RemoveJob(this);
 }
 
@@ -532,7 +532,7 @@
 scoped_ptr<CertNetFetcherImpl::Job> CertNetFetcherImpl::RemoveJob(Job* job) {
   DCHECK(thread_checker_.CalledOnValidThread());
   bool erased_job = jobs_.erase(job) == 1;
-  DCHECK(erased_job);
+  CHECK(erased_job);
   return make_scoped_ptr(job);
 }
 
@@ -547,4 +547,8 @@
   currently_completing_job_ = nullptr;
 }
 
+bool CertNetFetcherImpl::IsCurrentlyCompletingJob(Job* job) {
+  return job == currently_completing_job_;
+}
+
 }  // namespace net
diff --git a/net/cert_net/cert_net_fetcher_impl.h b/net/cert_net/cert_net_fetcher_impl.h
index 692647a..ac5cd90 100644
--- a/net/cert_net/cert_net_fetcher_impl.h
+++ b/net/cert_net/cert_net_fetcher_impl.h
@@ -84,6 +84,7 @@
   // Indicates which Job is currently executing inside of OnJobCompleted().
   void SetCurrentlyCompletingJob(Job* job);
   void ClearCurrentlyCompletingJob(Job* job);
+  bool IsCurrentlyCompletingJob(Job* job);
 
   // The in-progress jobs. This set does not contain the job which is actively
   // invoking callbacks (OnJobCompleted). Instead that is tracked by
diff --git a/net/cert_net/cert_net_fetcher_impl_unittest.cc b/net/cert_net/cert_net_fetcher_impl_unittest.cc
index 2003a41..c803b4c 100644
--- a/net/cert_net/cert_net_fetcher_impl_unittest.cc
+++ b/net/cert_net/cert_net_fetcher_impl_unittest.cc
@@ -726,4 +726,33 @@
   EXPECT_FALSE(callback[2].HasResult());
 }
 
+// Cancel the final request while executing a callback for the same job. Ensure
+// that the job is not deleted twice.
+TEST_F(CertNetFetcherImplTest, CancelLastRequestWithinCallback) {
+  ASSERT_TRUE(test_server_.Start());
+
+  CertNetFetcherImpl fetcher(&context_);
+
+  GURL url = test_server_.GetURL("files/cert.crt");
+
+  TestFetchCallback callback1;
+  scoped_ptr<CertNetFetcher::Request> request1 =
+      StartRequest(&fetcher, url, callback1);
+
+  TestFetchCallback callback2;
+  scoped_ptr<CertNetFetcher::Request> request2 =
+      StartRequest(&fetcher, url, callback1);
+
+  // Cancel request2 when the callback for request1 runs.
+  callback1.set_extra_closure(base::Bind(CancelRequest, &request2));
+
+  EXPECT_EQ(1, network_delegate_.created_requests());
+
+  scoped_ptr<FetchResult> result = callback1.WaitForResult();
+  result->VerifySuccess("-cert.crt-\n");
+
+  // request2 was cancelled.
+  EXPECT_FALSE(callback2.HasResult());
+}
+
 }  // namespace net
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index d799758..d335ae4 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -557,7 +557,7 @@
       : CookieMonsterTask(cookie_monster), callback_(callback) {}
 
   // CookieMonsterTask:
-  virtual void Run() override;
+  void Run() override;
 
  protected:
   ~DeleteTask() override;
diff --git a/net/der/input.cc b/net/der/input.cc
new file mode 100644
index 0000000..7c875a4
--- /dev/null
+++ b/net/der/input.cc
@@ -0,0 +1,90 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "net/der/input.h"
+
+namespace net {
+
+namespace der {
+
+Input::Input() : data_(nullptr), len_(0) {
+}
+Input::Input(const uint8_t* data, size_t len) : data_(data), len_(len) {
+}
+Input::Input(const std::string& s)
+    : data_(reinterpret_cast<const uint8_t*>(s.data())), len_(s.size()) {
+}
+
+ByteReader::ByteReader(const Input& in)
+    : data_(in.UnsafeData()), len_(in.Length()) {
+}
+
+bool ByteReader::ReadByte(uint8_t* byte_p) {
+  if (!HasMore())
+    return false;
+  *byte_p = *data_;
+  Advance(1);
+  return true;
+}
+
+bool ByteReader::ReadBytes(size_t len, Input* out) {
+  if (len > len_)
+    return false;
+  *out = Input(data_, len);
+  Advance(len);
+  return true;
+}
+
+// Returns whether there is any more data to be read.
+bool ByteReader::HasMore() {
+  return len_ > 0;
+}
+
+Mark ByteReader::NewMark() {
+  return Mark(data_);
+}
+
+bool ByteReader::AdvanceToMark(Mark mark) {
+  if (mark.ptr_ < data_)
+    return false;
+  // mark.ptr_ >= data_, so no concern of integer underflow here.
+  size_t advance_len = mark.ptr_ - data_;
+  if (advance_len > len_)
+    return false;
+  Advance(advance_len);
+  return true;
+}
+
+bool ByteReader::ReadToMark(Mark mark, Input* out) {
+  if (mark.ptr_ < data_)
+    return false;
+  // mark.ptr_ >= data_, so no concern of integer underflow here.
+  size_t len = mark.ptr_ - data_;
+  return ReadBytes(len, out);
+}
+
+void ByteReader::Advance(size_t len) {
+  CHECK_LE(len, len_);
+  data_ += len;
+  len_ -= len;
+}
+
+Mark Mark::NullMark() {
+  return Mark();
+}
+
+bool Mark::IsEmpty() {
+  return ptr_ == nullptr;
+}
+
+Mark::Mark(const uint8_t* ptr) : ptr_(ptr) {
+}
+
+Mark::Mark() : ptr_(nullptr) {
+}
+
+}  // namespace der
+
+}  // namespace net
diff --git a/net/der/input.h b/net/der/input.h
new file mode 100644
index 0000000..667bd89
--- /dev/null
+++ b/net/der/input.h
@@ -0,0 +1,152 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DER_INPUT_H_
+#define NET_DER_INPUT_H_
+
+#include <stdint.h>
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace der {
+
+class Mark;
+
+// An opaque class that represents a fixed buffer of data of a fixed length,
+// to be used as an input to other operations. An Input object does not own
+// the data it references, so callers are responsible for making sure that
+// the data outlives the Input object and any other associated objects.
+//
+// All data access for an Input should be done through the ByteReader and Mark
+// classes. This class and associated classes are designed with safety in mind
+// to make it difficult to read memory outside of an Input. ByteReader provides
+// a simple API for reading through the Input sequentially. For more
+// complicated uses, multiple instances of a ByteReader for a particular Input
+// can be created, and instances of Mark can be used to coordinate between the
+// ByteReaders.
+//
+// One such use case of multiple ByteReaders would be looking ahead in an
+// input: A ByteReader is copied and then is used to read some number of
+// bytes into the input, based on the content it is reading. A Mark can then be
+// set using the temporary ByteReader to indicate how far it read into the
+// Input. The original ByteReader can then be synchronized with how far the
+// temporary ByteReader read, by using either AdvanceToMark() or ReadToMark().
+class NET_EXPORT_PRIVATE Input {
+ public:
+  // Creates an empty Input, one from which no data can be read.
+  Input();
+
+  // Creates an Input from the given |data| and |len|.
+  Input(const uint8_t* data, size_t len);
+
+  // Creates an Input from the given string |s|.
+  explicit Input(const std::string& s);
+
+  // Returns the length in bytes of an Input's data.
+  size_t Length() const { return len_; }
+
+  // Returns a pointer to the Input's data. This method is marked as "unsafe"
+  // because access to the Input's data should be done through ByteReader
+  // instead. This method should only be used where using a ByteReader truly
+  // is not an option.
+  const uint8_t* UnsafeData() const { return data_; }
+
+ private:
+  const uint8_t* data_;
+  size_t len_;
+};
+
+// This class provides ways to read data from an Input in a bounds-checked way.
+// The ByteReader is designed to read through the input sequentially. Once a
+// byte has been read with a ByteReader, the caller can't go back and re-read
+// that byte with the same reader. Of course, the caller can create multiple
+// ByteReaders for the same input (or copy an existing ByteReader).
+//
+// For something simple like a single byte lookahead, the easiest way to do
+// that is to copy the ByteReader and call ReadByte() on the copy - the original
+// ByteReader will be unaffected and the peeked byte will be read through
+// ReadByte(). For other read patterns, it can be useful to mark where one is
+// in a ByteReader to be able to return to that spot.
+//
+// Some operations using Mark can also be done by creating a copy of the
+// ByteReader. By using a Mark instead, you use less memory, but more
+// importantly, you end up with an immutable object that matches the semantics
+// of what is intended.
+class NET_EXPORT_PRIVATE ByteReader {
+ public:
+  // Creates a ByteReader to read the data represented by an Input.
+  explicit ByteReader(const Input& in);
+
+  // Reads a single byte from the input source, putting the byte read in
+  // |*byte_p|. If a byte cannot be read from the input (because there is
+  // no input left), then this method returns false.
+  bool ReadByte(uint8_t* out) WARN_UNUSED_RESULT;
+
+  // Reads |len| bytes from the input source, and initializes an Input to
+  // point to that data. If there aren't enough bytes left in the input source,
+  // then this method returns false.
+  bool ReadBytes(size_t len, Input* out) WARN_UNUSED_RESULT;
+
+  // Returns how many bytes are left to read.
+  size_t BytesLeft() const { return len_; }
+
+  // Returns whether there is any more data to be read.
+  bool HasMore();
+
+  // Creates a new Mark at the current position of this ByteReader. If another
+  // ByteReader is advanced to this mark, the next byte read by the other
+  // ByteReader will be the same as the next byte read by this ByteReader.
+  Mark NewMark();
+
+  // Advances this ByteReader to the position marked by |mark|. Note that
+  // a ByteReader can only advance forward - it is not possible to "rewind"
+  // to a previous mark. To do this, one would need to create a new ByteReader
+  // (from the same input) and AdvanceToMark() on the new ByteReader.
+  //
+  // If it is not possible to advance this ByteReader to the mark, this method
+  // returns false and does nothing.
+  bool AdvanceToMark(Mark mark) WARN_UNUSED_RESULT;
+
+  // Reads all data from the cursor of this ByteReader up to the mark, and
+  // initializes an Input to point to that data. If the Mark is not valid for
+  // this ByteReader, then this method returns false and does not modify |*out|.
+  bool ReadToMark(Mark mark, Input* out) WARN_UNUSED_RESULT;
+
+ private:
+  void Advance(size_t len);
+
+  const uint8_t* data_;
+  size_t len_;
+};
+
+// An immutable opaque pointer into the data represented by an Input. A Mark
+// object is used to save and restore the state (position) of a ByteReader to
+// allow for lookahead or backtracking. All interaction with a Mark object is
+// done through the ByteReader class.
+class NET_EXPORT_PRIVATE Mark {
+ public:
+  // Creates a null Mark. This Mark will not be usable with any ByteReader.
+  // This only exists so that a class can have a Mark member which may or may
+  // not be a valid Mark at any given time.
+  static Mark NullMark();
+
+  // Checks whether a given Mark is an empty Mark.
+  bool IsEmpty();
+  friend class ByteReader;
+
+ private:
+  explicit Mark(const uint8_t* ptr);
+  Mark();
+  const uint8_t* ptr_;
+};
+
+}  // namespace der
+
+}  // namespace net
+
+#endif  // NET_DER_INPUT_H_
diff --git a/net/der/input_unittest.cc b/net/der/input_unittest.cc
new file mode 100644
index 0000000..a6a9b8c
--- /dev/null
+++ b/net/der/input_unittest.cc
@@ -0,0 +1,125 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "net/der/input.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace der {
+namespace test {
+
+const uint8_t kInput[] = {'t', 'e', 's', 't'};
+
+TEST(ByteReaderTest, NoReadPastEnd) {
+  ByteReader reader(Input(nullptr, 0));
+  uint8_t data;
+  EXPECT_FALSE(reader.ReadByte(&data));
+}
+
+TEST(ByteReaderTest, ReadToEnd) {
+  uint8_t out;
+  ByteReader reader(Input(kInput, arraysize(kInput)));
+  for (size_t i = 0; i < arraysize(kInput); ++i) {
+    ASSERT_TRUE(reader.ReadByte(&out));
+    ASSERT_EQ(kInput[i], out);
+  }
+  EXPECT_FALSE(reader.ReadByte(&out));
+}
+
+TEST(ByteReaderTest, PartialReadFails) {
+  Input out;
+  ByteReader reader(Input(kInput, arraysize(kInput)));
+  EXPECT_FALSE(reader.ReadBytes(5, &out));
+}
+
+TEST(ByteReaderTest, HasMore) {
+  Input out;
+  ByteReader reader(Input(kInput, arraysize(kInput)));
+
+  ASSERT_TRUE(reader.HasMore());
+  ASSERT_TRUE(reader.ReadBytes(arraysize(kInput), &out));
+  ASSERT_FALSE(reader.HasMore());
+}
+
+TEST(ByteReaderTest, ReadToMark) {
+  uint8_t out;
+  Input input(kInput, arraysize(kInput));
+  ByteReader reader(input);
+
+  // Read 2 bytes from the reader and then set a mark.
+  ASSERT_TRUE(reader.ReadByte(&out));
+  ASSERT_TRUE(reader.ReadByte(&out));
+  Mark mark = reader.NewMark();
+
+  // Reset the reader and check that we can read to a mark previously set.
+  reader = ByteReader(input);
+  Input marked_data;
+  ASSERT_TRUE(reader.ReadToMark(mark, &marked_data));
+}
+
+TEST(ByteReaderTest, CantReadToWrongMark) {
+  Input out;
+  Input in1(kInput, arraysize(kInput));
+  Input in2("test");
+  ByteReader reader1(in1);
+  ByteReader reader2(in2);
+  ASSERT_TRUE(reader1.ReadBytes(2, &out));
+  ASSERT_TRUE(reader2.ReadBytes(2, &out));
+  Mark mark1 = reader1.NewMark();
+  Mark mark2 = reader2.NewMark();
+  reader1 = ByteReader(in1);
+  reader2 = ByteReader(in2);
+
+  // It is not possible to advance to a mark outside the underlying input.
+  ASSERT_FALSE(reader1.AdvanceToMark(mark2));
+  ASSERT_FALSE(reader2.AdvanceToMark(mark1));
+}
+
+TEST(ByteReaderTest, MarksAreSharedBetweenSameInputs) {
+  Input out;
+  Input in1(kInput, arraysize(kInput));
+  Input in2(kInput, 1);
+  ByteReader reader1(in1);
+  ByteReader reader2(in2);
+  ASSERT_TRUE(reader1.ReadBytes(2, &out));
+  ASSERT_TRUE(reader2.ReadBytes(1, &out));
+  Mark mark1 = reader1.NewMark();
+  Mark mark2 = reader2.NewMark();
+  reader1 = ByteReader(in1);
+  reader2 = ByteReader(in2);
+
+  // If Marks are created on the same underlying data, they can be shared
+  // across ByteReaders and Inputs. However, they still must be inside the
+  // bounds for the ByteReader they are being used on.
+
+  // mark1 is past the end of the input for reader2.
+  EXPECT_FALSE(reader2.AdvanceToMark(mark1));
+  // mark2 is within the bounds of reader1.
+  EXPECT_TRUE(reader1.AdvanceToMark(mark2));
+}
+
+TEST(ByteReaderTest, CantReadToWrongMarkWithInputsOnStack) {
+  const uint8_t data1[] = "test";
+  const uint8_t data2[] = "foo";
+  Input out;
+  Input in1(data1, arraysize(data1));
+  Input in2(data2, arraysize(data2));
+
+  ByteReader reader1(in1);
+  ByteReader reader2(in2);
+  ASSERT_TRUE(reader1.ReadBytes(2, &out));
+  ASSERT_TRUE(reader2.ReadBytes(2, &out));
+  Mark mark1 = reader1.NewMark();
+  Mark mark2 = reader2.NewMark();
+  reader1 = ByteReader(in1);
+  reader2 = ByteReader(in2);
+
+  ASSERT_FALSE(reader1.AdvanceToMark(mark2));
+  ASSERT_FALSE(reader2.AdvanceToMark(mark1));
+}
+
+}  // namespace test
+}  // namespace der
+}  // namespace net
diff --git a/net/der/parse_values.cc b/net/der/parse_values.cc
new file mode 100644
index 0000000..bbf765f
--- /dev/null
+++ b/net/der/parse_values.cc
@@ -0,0 +1,269 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/numerics/safe_math.h"
+#include "net/der/parse_values.h"
+
+namespace net {
+
+namespace der {
+
+namespace {
+
+bool ParseBoolInternal(const Input& in, bool* out, bool relaxed) {
+  // According to ITU-T X.690 section 8.2, a bool is encoded as a single octet
+  // where the octet of all zeroes is FALSE and a non-zero value for the octet
+  // is TRUE.
+  if (in.Length() != 1)
+    return false;
+  ByteReader data(in);
+  uint8_t byte;
+  if (!data.ReadByte(&byte))
+    return false;
+  if (byte == 0) {
+    *out = false;
+    return true;
+  }
+  // ITU-T X.690 section 11.1 specifies that for DER, the TRUE value must be
+  // encoded as an octet of all ones.
+  if (byte == 0xff || relaxed) {
+    *out = true;
+    return true;
+  }
+  return false;
+}
+
+// Reads a positive decimal number with |digits| digits and stores it in
+// |*out|. This function does not check that the type of |*out| is large
+// enough to hold 10^digits - 1; the caller must choose an appropriate type
+// based on the number of digits they wish to parse.
+template <typename UINT>
+bool DecimalStringToUint(ByteReader& in, size_t digits, UINT* out) {
+  UINT value = 0;
+  for (size_t i = 0; i < digits; ++i) {
+    uint8_t digit;
+    if (!in.ReadByte(&digit)) {
+      return false;
+    }
+    if (digit < '0' || digit > '9') {
+      return false;
+    }
+    value = (value * 10) + (digit - '0');
+  }
+  *out = value;
+  return true;
+}
+
+// Checks that the values in a GeneralizedTime struct are valid. This involves
+// checking that the year is 4 digits, the month is between 1 and 12, the day
+// is a day that exists in that month (following current leap year rules),
+// hours are between 0 and 23, minutes between 0 and 59, and seconds between
+// 0 and 60 (to allow for leap seconds; no validation is done that a leap
+// second is on a day that could be a leap second).
+bool ValidateGeneralizedTime(const GeneralizedTime& time) {
+  CHECK(time.year > 0 && time.year < 9999);
+  if (time.month < 1 || time.month > 12)
+    return false;
+  if (time.day < 1)
+    return false;
+  if (time.hours < 0 || time.hours > 23)
+    return false;
+  if (time.minutes < 0 || time.minutes > 59)
+    return false;
+  // Leap seconds are allowed.
+  if (time.seconds < 0 || time.seconds > 60)
+    return false;
+
+  // validate upper bound for day of month
+  switch (time.month) {
+    case 4:
+    case 6:
+    case 9:
+    case 11:
+      if (time.day > 30)
+        return false;
+      break;
+    case 1:
+    case 3:
+    case 5:
+    case 7:
+    case 8:
+    case 10:
+    case 12:
+      if (time.day > 31)
+        return false;
+      break;
+    case 2:
+      if (time.year % 4 == 0 &&
+          (time.year % 100 != 0 || time.year % 400 == 0)) {
+        if (time.day > 29)
+          return false;
+      } else {
+        if (time.day > 28)
+          return false;
+      }
+      break;
+    default:
+      NOTREACHED();
+      return false;
+  }
+  return true;
+}
+
+}  // namespace
+
+bool ParseBool(const Input& in, bool* out) {
+  return ParseBoolInternal(in, out, false /* relaxed */);
+}
+
+// BER interprets any non-zero value as true, while DER requires a bool to
+// have either all bits zero (false) or all bits one (true). To support
+// malformed certs, we recognized the BER encoding instead of failing to
+// parse.
+bool ParseBoolRelaxed(const Input& in, bool* out) {
+  return ParseBoolInternal(in, out, true /* relaxed */);
+}
+
+bool ParseUint64(const Input& in, uint64_t* out) {
+  ByteReader reader(in);
+  size_t bytes_read = 0;
+  uint8_t data;
+  uint64_t value = 0;
+  // Note that for simplicity, this check only admits integers up to 2^63-1.
+  if (in.Length() > sizeof(uint64_t) || in.Length() == 0)
+    return false;
+  while (reader.ReadByte(&data)) {
+    if (bytes_read == 0 && (data & 0x80)) {
+      return false;
+    }
+    value <<= 8;
+    value |= data;
+    bytes_read++;
+  }
+  // ITU-T X.690 section 8.3.2 specifies that an integer value must be encoded
+  // in the smallest number of octets. If the encoding consists of more than
+  // one octet, then the bits of the first octet and the most significant bit
+  // of the second octet must not be all zeroes or all ones.
+  // Because this function only parses unsigned integers, there's no need to
+  // check for the all ones case.
+  if (bytes_read > 1) {
+    ByteReader first_bytes_reader(in);
+    uint8_t first_byte;
+    uint8_t second_byte;
+    if (!first_bytes_reader.ReadByte(&first_byte) ||
+        !first_bytes_reader.ReadByte(&second_byte)) {
+      return false;
+    }
+    if (first_byte == 0 && !(second_byte & 0x80)) {
+      return false;
+    }
+  }
+  *out = value;
+  return true;
+}
+
+bool operator<(const GeneralizedTime& lhs, const GeneralizedTime& rhs) {
+  if (lhs.year != rhs.year)
+    return lhs.year < rhs.year;
+  if (lhs.month != rhs.month)
+    return lhs.month < rhs.month;
+  if (lhs.day != rhs.day)
+    return lhs.day < rhs.day;
+  if (lhs.hours != rhs.hours)
+    return lhs.hours < rhs.hours;
+  if (lhs.minutes != rhs.minutes)
+    return lhs.minutes < rhs.minutes;
+  return lhs.seconds < rhs.seconds;
+}
+
+// A UTC Time in DER encoding should be YYMMDDHHMMSSZ, but some CAs encode
+// the time following BER rules, which allows for YYMMDDHHMMZ. If the length
+// is 11, assume it's YYMMDDHHMMZ, and in converting it to a GeneralizedTime,
+// add in the seconds (set to 0).
+bool ParseUTCTimeRelaxed(const Input& in, GeneralizedTime* value) {
+  ByteReader reader(in);
+  GeneralizedTime time;
+  if (!DecimalStringToUint(reader, 2, &time.year) ||
+      !DecimalStringToUint(reader, 2, &time.month) ||
+      !DecimalStringToUint(reader, 2, &time.day) ||
+      !DecimalStringToUint(reader, 2, &time.hours) ||
+      !DecimalStringToUint(reader, 2, &time.minutes)) {
+    return false;
+  }
+
+  // Try to read the 'Z' at the end. If we read something else, then for it to
+  // be valid the next bytes should be seconds (and then followed by 'Z').
+  uint8_t zulu;
+  ByteReader zulu_reader = reader;
+  if (!zulu_reader.ReadByte(&zulu))
+    return false;
+  if (zulu == 'Z' && !zulu_reader.HasMore()) {
+    time.seconds = 0;
+    *value = time;
+    return true;
+  }
+  if (!DecimalStringToUint(reader, 2, &time.seconds))
+    return false;
+  if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore())
+    return false;
+  if (!ValidateGeneralizedTime(time))
+    return false;
+  if (time.year < 50) {
+    time.year += 2000;
+  } else {
+    time.year += 1900;
+  }
+  *value = time;
+  return true;
+}
+
+bool ParseUTCTime(const Input& in, GeneralizedTime* value) {
+  ByteReader reader(in);
+  GeneralizedTime time;
+  if (!DecimalStringToUint(reader, 2, &time.year) ||
+      !DecimalStringToUint(reader, 2, &time.month) ||
+      !DecimalStringToUint(reader, 2, &time.day) ||
+      !DecimalStringToUint(reader, 2, &time.hours) ||
+      !DecimalStringToUint(reader, 2, &time.minutes) ||
+      !DecimalStringToUint(reader, 2, &time.seconds)) {
+    return false;
+  }
+  uint8_t zulu;
+  if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore())
+    return false;
+  if (!ValidateGeneralizedTime(time))
+    return false;
+  if (time.year < 50) {
+    time.year += 2000;
+  } else {
+    time.year += 1900;
+  }
+  *value = time;
+  return true;
+}
+
+bool ParseGeneralizedTime(const Input& in, GeneralizedTime* value) {
+  ByteReader reader(in);
+  GeneralizedTime time;
+  if (!DecimalStringToUint(reader, 4, &time.year) ||
+      !DecimalStringToUint(reader, 2, &time.month) ||
+      !DecimalStringToUint(reader, 2, &time.day) ||
+      !DecimalStringToUint(reader, 2, &time.hours) ||
+      !DecimalStringToUint(reader, 2, &time.minutes) ||
+      !DecimalStringToUint(reader, 2, &time.seconds)) {
+    return false;
+  }
+  uint8_t zulu;
+  if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore())
+    return false;
+  if (!ValidateGeneralizedTime(time))
+    return false;
+  *value = time;
+  return true;
+}
+
+}  // namespace der
+
+}  // namespace net
diff --git a/net/der/parse_values.h b/net/der/parse_values.h
new file mode 100644
index 0000000..23c534e
--- /dev/null
+++ b/net/der/parse_values.h
@@ -0,0 +1,69 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DER_PARSE_TYPES_H_
+#define NET_DER_PARSE_TYPES_H_
+
+#include "base/compiler_specific.h"
+#include "net/base/net_export.h"
+#include "net/der/input.h"
+
+namespace net {
+
+namespace der {
+
+// Reads a DER-encoded ASN.1 BOOLEAN value from |in| and puts the resulting
+// value in |out|. Returns whether the encoded value could successfully be
+// read.
+NET_EXPORT bool ParseBool(const Input& in, bool* out) WARN_UNUSED_RESULT;
+
+// Like ParseBool, except it is more relaxed in what inputs it accepts: Any
+// value that is a valid BER encoding will be parsed successfully.
+NET_EXPORT bool ParseBoolRelaxed(const Input& in, bool* out) WARN_UNUSED_RESULT;
+
+// Reads a DER-encoded ASN.1 INTEGER value from |in| and puts the resulting
+// value in |out|. ASN.1 INTEGERs are arbitrary precision; this function is
+// provided as a convenience when the caller knows that the value is unsigned
+// and is between 0 and 2^63-1. This function does not support the full range of
+// uint64_t. This function returns false if the value is too big to fit in a
+// uint64_t, is negative, or if there is an error reading the integer.
+NET_EXPORT bool ParseUint64(const Input& in, uint64_t* out) WARN_UNUSED_RESULT;
+
+struct GeneralizedTime {
+  uint16_t year;
+  uint8_t month;
+  uint8_t day;
+  uint8_t hours;
+  uint8_t minutes;
+  uint8_t seconds;
+};
+
+NET_EXPORT_PRIVATE bool operator<(const GeneralizedTime& lhs,
+                                  const GeneralizedTime& rhs);
+
+// Reads a DER-encoded ASN.1 UTCTime value from |in| and puts the resulting
+// value in |out|, returning true if the UTCTime could be parsed successfully.
+NET_EXPORT bool ParseUTCTime(const Input& in,
+                             GeneralizedTime* out) WARN_UNUSED_RESULT;
+
+// Like ParseUTCTime, but it is more lenient in what is accepted. DER requires
+// a UTCTime to be in the format YYMMDDhhmmssZ; this function will accept both
+// that and YYMMDDhhmmZ, which is a valid BER encoding of a UTCTime which
+// sometimes incorrectly appears in X.509 certificates.
+NET_EXPORT bool ParseUTCTimeRelaxed(const Input& in,
+                                    GeneralizedTime* out) WARN_UNUSED_RESULT;
+
+// Reads a DER-encoded ASN.1 GeneralizedTime value from |in| and puts the
+// resulting value in |out|, returning true if the GeneralizedTime could
+// be parsed sucessfully. This function is even more restrictive than the
+// DER rules - it follows the rules from RFC5280, which does not allow for
+// fractional seconds.
+NET_EXPORT bool ParseGeneralizedTime(const Input& in,
+                                     GeneralizedTime* out) WARN_UNUSED_RESULT;
+
+}  // namespace der
+
+}  // namespace net
+
+#endif  // NET_DER_PARSE_TYPES_H_
diff --git a/net/der/parse_values_unittest.cc b/net/der/parse_values_unittest.cc
new file mode 100644
index 0000000..82330424
--- /dev/null
+++ b/net/der/parse_values_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "net/der/parse_values.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace der {
+namespace test {
+
+TEST(ParseValuesTest, ParseBool) {
+  uint8_t buf[] = {0xFF, 0x00};
+  Input value(buf, 1);
+  bool out;
+  EXPECT_TRUE(ParseBool(value, &out));
+  EXPECT_TRUE(out);
+
+  buf[0] = 0;
+  EXPECT_TRUE(ParseBool(value, &out));
+  EXPECT_FALSE(out);
+
+  buf[0] = 1;
+  EXPECT_FALSE(ParseBool(value, &out));
+  EXPECT_TRUE(ParseBoolRelaxed(value, &out));
+  EXPECT_TRUE(out);
+
+  buf[0] = 0xFF;
+  value = Input(buf, 2);
+  EXPECT_FALSE(ParseBool(value, &out));
+  value = Input(buf, 0);
+  EXPECT_FALSE(ParseBool(value, &out));
+}
+
+TEST(ParseValuesTest, ParseTimes) {
+  GeneralizedTime out;
+
+  EXPECT_TRUE(ParseUTCTime(Input("140218161200Z"), &out));
+
+  // DER-encoded UTCTime must end with 'Z'.
+  EXPECT_FALSE(ParseUTCTime(Input("140218161200X"), &out));
+
+  // Check that a negative number (-4 in this case) doesn't get parsed as
+  // a 2-digit number.
+  EXPECT_FALSE(ParseUTCTime(Input("-40218161200Z"), &out));
+
+  // Check that numbers with a leading 0 don't get parsed in octal by making
+  // the second digit an invalid octal digit (e.g. 09).
+  EXPECT_TRUE(ParseUTCTime(Input("090218161200Z"), &out));
+
+  // Check that the length is validated.
+  EXPECT_FALSE(ParseUTCTime(Input("140218161200"), &out));
+  EXPECT_FALSE(ParseUTCTime(Input("140218161200Z0"), &out));
+  EXPECT_FALSE(ParseUTCTimeRelaxed(Input("140218161200"), &out));
+  EXPECT_FALSE(ParseUTCTimeRelaxed(Input("140218161200Z0"), &out));
+
+  // Check strictness of UTCTime parsers.
+  EXPECT_FALSE(ParseUTCTime(Input("1402181612Z"), &out));
+  EXPECT_TRUE(ParseUTCTimeRelaxed(Input("1402181612Z"), &out));
+
+  // Check that the time ends in Z.
+  EXPECT_FALSE(ParseUTCTimeRelaxed(Input("1402181612Z0"), &out));
+
+  // Check format of GeneralizedTime.
+
+  // Leap seconds are allowed.
+  EXPECT_TRUE(ParseGeneralizedTime(Input("20140218161260Z"), &out));
+
+  // But nothing larger than a leap second.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140218161261Z"), &out));
+
+  // Minutes only go up to 59.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140218166000Z"), &out));
+
+  // Hours only go up to 23.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140218240000Z"), &out));
+  // The 0th day of a month is invalid.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140200161200Z"), &out));
+  // The 0th month is invalid.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140018161200Z"), &out));
+  // Months greater than 12 are invalid.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20141318161200Z"), &out));
+
+  // Some months have 31 days.
+  EXPECT_TRUE(ParseGeneralizedTime(Input("20140131000000Z"), &out));
+
+  // September has only 30 days.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140931000000Z"), &out));
+
+  // February has only 28 days...
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140229000000Z"), &out));
+
+  // ... unless it's a leap year.
+  EXPECT_TRUE(ParseGeneralizedTime(Input("20160229000000Z"), &out));
+
+  // There aren't any leap days in years divisible by 100...
+  EXPECT_FALSE(ParseGeneralizedTime(Input("21000229000000Z"), &out));
+
+  // ...unless it's also divisible by 400.
+  EXPECT_TRUE(ParseGeneralizedTime(Input("20000229000000Z"), &out));
+
+  // Check more perverse invalid inputs.
+
+  const uint8_t trailing_null_bytes[] = {'2',
+                                         '0',
+                                         '0',
+                                         '0',
+                                         '1',
+                                         '2',
+                                         '3',
+                                         '1',
+                                         '0',
+                                         '1',
+                                         '0',
+                                         '2',
+                                         '0',
+                                         '3',
+                                         'Z',
+                                         '\0'};
+  Input trailing_null(trailing_null_bytes, sizeof(trailing_null_bytes));
+  EXPECT_FALSE(ParseGeneralizedTime(trailing_null, &out));
+  const uint8_t embedded_null_bytes[] = {'2',
+                                         '0',
+                                         '0',
+                                         '\0',
+                                         '1',
+                                         '2',
+                                         '3',
+                                         '1',
+                                         '0',
+                                         '1',
+                                         '0',
+                                         '2',
+                                         '0',
+                                         '3',
+                                         'Z'};
+  Input embedded_null(embedded_null_bytes, sizeof(embedded_null_bytes));
+  EXPECT_FALSE(ParseGeneralizedTime(embedded_null, &out));
+
+  // The year can't be in hex.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("0x201231000000Z"), &out));
+
+  // The last byte must be 'Z'.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20001231000000X"), &out));
+
+  // Check that the length is validated.
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140218161200"), &out));
+  EXPECT_FALSE(ParseGeneralizedTime(Input("20140218161200Z0"), &out));
+}
+
+TEST(ParseValuesTest, TimesCompare) {
+  GeneralizedTime time1;
+  GeneralizedTime time2;
+  GeneralizedTime time3;
+
+  ASSERT_TRUE(ParseGeneralizedTime(Input("20140218161200Z"), &time1));
+  ASSERT_TRUE(ParseUTCTime(Input("150218161200Z"), &time2));
+  ASSERT_TRUE(ParseGeneralizedTime(Input("20160218161200Z"), &time3));
+  EXPECT_TRUE(time1 < time2);
+  EXPECT_TRUE(time2 < time3);
+  EXPECT_TRUE(time1 < time3);
+}
+
+struct Uint64TestData {
+  bool should_pass;
+  const uint8_t input[9];
+  size_t length;
+  uint64_t expected_value;
+};
+
+const Uint64TestData kUint64TestData[] = {
+    {true, {0x00}, 1, 0},
+    {true, {0x01}, 1, 1},
+    {false, {0xFF}, 1, 0},
+    {true, {0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 8, INT64_MAX},
+    {false, {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 8, 0},
+    {false, {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 9, 0},
+    {false, {0x00, 0x01}, 2, 1},
+    {false, {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}, 9, 0},
+    {false, {0}, 0, 0},
+};
+
+TEST(ParseValuesTest, ParseUint64) {
+  for (size_t i = 0; i < arraysize(kUint64TestData); i++) {
+    Uint64TestData test_case = kUint64TestData[i];
+    SCOPED_TRACE(i);
+
+    uint64_t result;
+    EXPECT_EQ(test_case.should_pass,
+              ParseUint64(Input(test_case.input, test_case.length), &result));
+    if (test_case.should_pass)
+      EXPECT_EQ(test_case.expected_value, result);
+  }
+}
+
+}  // namespace test
+}  // namespace der
+}  // namespace net
diff --git a/net/der/parser.cc b/net/der/parser.cc
new file mode 100644
index 0000000..7263fba
--- /dev/null
+++ b/net/der/parser.cc
@@ -0,0 +1,192 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/numerics/safe_math.h"
+#include "net/der/parse_values.h"
+#include "net/der/parser.h"
+
+namespace net {
+
+namespace der {
+
+Parser::Parser() : input_(Input()), advance_mark_(Mark::NullMark()) {
+}
+Parser::Parser(const Input& input)
+    : input_(input), advance_mark_(Mark::NullMark()) {
+}
+
+// Reads the next TLV from the input and writes the tag and value to the
+// output parameters |tag| and |out|.
+bool Parser::PeekTagAndValue(Tag* tag, Input* out) {
+  ByteReader reader = input_;
+
+  // Don't support tags > 30.
+  uint8_t tag_byte;
+  if (!reader.ReadByte(&tag_byte))
+    return false;
+
+  // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a
+  // tag number no greater than 30. This parser only supports tag numbers up
+  // to 30.
+  // If the tag number is 31 (0x1F, the largest value that fits in the allotted
+  // bytes), then the tag is more than one byte long and the continuation bytes
+  // contain the real tag number. We only support tag numbers < 31 (and thus
+  // single-byte tags).
+  if ((tag_byte & kTagNumberMask) == 31)
+    return false;
+
+  // Parse length. The format for the length encoding is specified in
+  // ITU-T X.690 section 8.1.3.
+  size_t value_len = 0;  // Number of bytes used to encode just the value.
+
+  uint8_t length_first_byte;
+  if (!reader.ReadByte(&length_first_byte))
+    return false;
+  if ((length_first_byte & 0x80) == 0) {
+    // Short form for length - it's only one byte long.
+    value_len = length_first_byte & 0x7f;
+  } else {
+    // Long form for length - it's encoded across multiple bytes.
+    if (length_first_byte == 0xff) {
+      // ITU-T X.690 clause 8.1.3.5.c specifies the value 0xff shall not be
+      // used.
+      return false;
+    }
+    // The high bit indicated that this is the long form, while the next 7 bits
+    // encode the number of subsequent octets used to encode the length
+    // (ITU-T X.690 clause 8.1.3.5.b).
+    size_t length_len = length_first_byte & 0x7f;
+    if (length_len == 0) {
+      // ITU-T X.690 section 10.1 (DER length forms) requires encoding the
+      // length with the minimum number of octets. Besides, it makes no sense
+      // for the length to be encoded in 0 octets.
+      return false;
+    }
+    if (length_len > sizeof(value_len)) {
+      // The length is encoded in multiple octets, with the first octet
+      // indicating how many octets follow. Those octets need to be combined
+      // to form a size_t, so the number of octets to follow (length_len)
+      // must be small enough so that they fit in a size_t.
+      return false;
+    }
+    uint8_t length_byte;
+    for (size_t i = 0; i < length_len; i++) {
+      if (!reader.ReadByte(&length_byte))
+        return false;
+      // A first length byte of all zeroes means the length was not encoded in
+      // minimum length.
+      if (i == 0 && length_byte == 0)
+        return false;
+      value_len <<= 8;
+      value_len += length_byte;
+    }
+    if (value_len < 0x80) {
+      // If value_len is < 0x80, then it could have been encoded in a single
+      // byte, meaning it was not encoded in minimum length.
+      return false;
+    }
+  }
+
+  if (!reader.ReadBytes(value_len, out))
+    return false;
+  advance_mark_ = reader.NewMark();
+  *tag = tag_byte;
+  return true;
+}
+
+bool Parser::Advance() {
+  if (advance_mark_.IsEmpty())
+    return false;
+  if (!input_.AdvanceToMark(advance_mark_))
+    return false;
+  advance_mark_ = Mark::NullMark();
+  return true;
+}
+
+bool Parser::HasMore() {
+  return input_.HasMore();
+}
+
+bool Parser::ReadRawTLV(Input* out) {
+  Tag tag;
+  Input value;
+  if (!PeekTagAndValue(&tag, &value))
+    return false;
+  if (!input_.ReadToMark(advance_mark_, out))
+    return false;
+  advance_mark_ = Mark::NullMark();
+
+  return true;
+}
+
+bool Parser::ReadTagAndValue(Tag* tag, Input* out) {
+  if (!PeekTagAndValue(tag, out))
+    return false;
+  CHECK(Advance());
+  return true;
+}
+
+bool Parser::ReadOptionalTag(Tag tag, Input* out, bool* present) {
+  if (!HasMore()) {
+    *present = false;
+    return true;
+  }
+
+  Tag read_tag;
+  Input value;
+  if (!PeekTagAndValue(&read_tag, &value))
+    return false;
+  *present = false;
+  if (read_tag == tag) {
+    *present = true;
+    *out = value;
+    CHECK(Advance());
+  } else {
+    advance_mark_ = Mark::NullMark();
+  }
+  return true;
+}
+
+bool Parser::SkipOptionalTag(Tag tag, bool* present) {
+  Input out;
+  return ReadOptionalTag(tag, &out, present);
+}
+
+bool Parser::ReadTag(Tag tag, Input* out) {
+  bool present;
+  return ReadOptionalTag(tag, out, &present) && present;
+}
+
+bool Parser::SkipTag(Tag tag) {
+  Input out;
+  return ReadTag(tag, &out);
+}
+
+// Type-specific variants of ReadTag
+
+bool Parser::ReadConstructed(Tag tag, Parser* out) {
+  if (!IsConstructed(tag))
+    return false;
+  Input data;
+  if (!ReadTag(tag, &data))
+    return false;
+  *out = Parser(data);
+  return true;
+}
+
+bool Parser::ReadSequence(Parser* out) {
+  return ReadConstructed(kSequence, out);
+}
+
+bool Parser::ReadUint64(uint64_t* out) {
+  Input encodedInt;
+  if (!ReadTag(kInteger, &encodedInt))
+    return false;
+  return ParseUint64(encodedInt, out);
+}
+
+}  // namespace der
+
+}  // namespace net
diff --git a/net/der/parser.h b/net/der/parser.h
new file mode 100644
index 0000000..4e60239b
--- /dev/null
+++ b/net/der/parser.h
@@ -0,0 +1,177 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DER_PARSER_H_
+#define NET_DER_PARSER_H_
+
+#include "base/compiler_specific.h"
+#include "base/time/time.h"
+#include "net/base/net_export.h"
+#include "net/der/input.h"
+#include "net/der/tag.h"
+
+namespace net {
+
+namespace der {
+
+// Parses a DER-encoded ASN.1 structure. DER (distinguished encoding rules)
+// encodes each data value with a tag, length, and value (TLV). The tag
+// indicates the type of the ASN.1 value. Depending on the type of the value,
+// it could contain arbitrary bytes, so the length of the value is encoded
+// after the tag and before the value to indicate how many bytes of value
+// follow. DER also defines how the values are encoded for particular types.
+//
+// This Parser places a few restrictions on the DER encoding it can parse. The
+// largest restriction is that it only supports tags which have a tag number
+// no greater than 30 - these are the tags that fit in a single octet. The
+// second restriction is that the maximum length for a value that can be parsed
+// is 4GB. Both of these restrictions should be fine for any reasonable input.
+//
+// The Parser class is mainly focused on parsing the TLV structure of DER
+// encoding, and does not directly handle parsing primitive values (other
+// functions in the net::der namespace are provided for this.) When a Parser
+// is created, it is passed in a reference to the encoded data. Because the
+// encoded data is not owned by the Parser, the data cannot change during the
+// lifespan of the Parser. The Parser functions by keeping a pointer to the
+// current TLV which starts at the beginning of the input and advancing through
+// the input as each TLV is read. As such, a Parser instance is thread-unsafe.
+//
+// Most methods for using the Parser write the current tag and/or value to
+// the output parameters provided and then advance the input to the next TLV.
+// None of the methods explicitly expose the length because it is part of the
+// value. All methods return a boolean indicating whether there was a parsing
+// error with the current TLV.
+//
+// Some methods are provided in the Parser class as convenience to both read
+// the current TLV from the input and also parse the DER encoded value,
+// converting it to a corresponding C++ type. These methods simply combine
+// ReadTag() with the appropriate ParseType() free function.
+//
+// The design of DER encoding allows for nested data structures with
+// constructed values, where the value is a series of TLVs. The Parser class
+// is not designed to traverse through a nested encoding from a single object,
+// but it does facilitate parsing nested data structures through the
+// convenience methods ReadSequence() and the more general ReadConstructed(),
+// which provide the user with another Parser object to traverse the next
+// level of TLVs.
+//
+// For a brief example of how to use the Parser, suppose we have the following
+// ASN.1 type definition:
+//
+//   Foo ::= SEQUENCE {
+//     bar OCTET STRING OPTIONAL,
+//     quux OCTET STRING }
+//
+// If we have a DER-encoded Foo in an Input |encoded_value|, the
+// following code shows an example of how to parse the quux field from the
+// encoded data.
+//
+//   bool ReadQuux(const Input& encoded_value, Input* quux_out) {
+//     Parser parser(encoded_value);
+//     Parser foo_parser;
+//     if (!parser.ReadSequence(&foo_parser))
+//       return false;
+//     if (!foo_parser->SkipOptionalTag(kOctetString))
+//       return false;
+//     if (!foo_parser->ReadTag(kOctetString, &quux))
+//       return false;
+//     return true;
+//   }
+class NET_EXPORT Parser {
+ public:
+  // Default constructor; equivalent to calling Parser(Input()). This only
+  // exists so that a Parser can be stack allocated and passed in to
+  // ReadConstructed() and similar methods.
+  Parser();
+
+  // Creates a parser to parse over the data represented by input. This class
+  // assumes that the underlying data will not change over the lifetime of
+  // the Parser object.
+  explicit Parser(const Input& input);
+
+  // Returns whether there is any more data left in the input to parse. This
+  // does not guarantee that the data is parseable.
+  bool HasMore();
+
+  // Reads the current TLV from the input and advances. If the tag or length
+  // encoding for the current value is invalid, this method returns false and
+  // does not advance the input. Otherwise, it returns true, putting the
+  // read tag in |tag| and the value in |out|.
+  bool ReadTagAndValue(Tag* tag, Input* out) WARN_UNUSED_RESULT;
+
+  // Reads the current TLV from the input and advances. Unlike ReadTagAndValue
+  // where only the value is put in |out|, this puts the raw bytes from the
+  // tag, length, and value in |out|.
+  bool ReadRawTLV(Input* out) WARN_UNUSED_RESULT;
+
+  // Basic methods for reading or skipping the current TLV, with an
+  // expectation of what the current tag should be. It should be possible
+  // to parse any structure with these 4 methods; convenience methods are also
+  // provided to make some cases easier.
+
+  // If the current tag in the input is |tag|, it puts the corresponding value
+  // in |out|, sets |was_present| to true, and advances the input to the next
+  // TLV. If the current tag is something else, then |was_present| is set to
+  // false and the input is not advanced. Like ReadTagAndValue, it returns
+  // false if the encoding is invalid and does not advance the input.
+  bool ReadOptionalTag(Tag tag,
+                       Input* out,
+                       bool* was_present) WARN_UNUSED_RESULT;
+
+  // Like ReadOptionalTag, but the value is discarded.
+  bool SkipOptionalTag(Tag tag, bool* was_present) WARN_UNUSED_RESULT;
+
+  // If the current tag matches |tag|, it puts the current value in |out|,
+  // advances the input, and returns true. Otherwise, it returns false.
+  bool ReadTag(Tag tag, Input* out) WARN_UNUSED_RESULT;
+
+  // Advances the input and returns true if the current tag matches |tag|;
+  // otherwise it returns false.
+  bool SkipTag(Tag tag) WARN_UNUSED_RESULT;
+
+  // Convenience methods to combine parsing the TLV with parsing the DER
+  // encoding for a specific type.
+
+  // Reads the current TLV from the input, checks that the tag matches |tag|
+  // and is a constructed tag, and creates a new Parser from the value.
+  bool ReadConstructed(Tag tag, Parser* out) WARN_UNUSED_RESULT;
+
+  // A more specific form of ReadConstructed that expects the current tag
+  // to be 0x30 (SEQUENCE).
+  bool ReadSequence(Parser* out) WARN_UNUSED_RESULT;
+
+  // Expects the current tag to be kInteger, and calls ParseUint64 on the
+  // current value. Note that DER-encoded integers are arbitrary precision,
+  // so this method will fail for valid input that represents an integer
+  // outside the range of an int64.
+  bool ReadUint64(uint64_t* out) WARN_UNUSED_RESULT;
+
+  // Lower level methods. The previous methods couple reading data from the
+  // input with advancing the Parser's internal pointer to the next TLV; these
+  // lower level methods decouple those two steps into methods that read from
+  // the current TLV and a method that advances the internal pointer to the
+  // next TLV.
+
+  // Reads the current TLV from the input, putting the tag in |tag| and the raw
+  // value in |out|, but does not advance the input. Returns true if the tag
+  // and length are successfully read and the output exists.
+  bool PeekTagAndValue(Tag* tag, Input* out) WARN_UNUSED_RESULT;
+
+  // Advances the input to the next TLV. This method only needs to be called
+  // after PeekTagAndValue; all other methods will advance the input if they
+  // read something.
+  bool Advance();
+
+ private:
+  ByteReader input_;
+  Mark advance_mark_;
+
+  DISALLOW_COPY(Parser);
+};
+
+}  // namespace der
+
+}  // namespace net
+
+#endif  // NET_DER_PARSER_H_
diff --git a/net/der/parser_unittest.cc b/net/der/parser_unittest.cc
new file mode 100644
index 0000000..6c0e177d
--- /dev/null
+++ b/net/der/parser_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/numerics/safe_math.h"
+#include "net/der/input.h"
+#include "net/der/parse_values.h"
+#include "net/der/parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace der {
+namespace test {
+
+TEST(ParserTest, ConsumesAllBytesOfTLV) {
+  const uint8_t der[] = {0x04, 0x00};
+  Parser parser(Input(der, sizeof(der)));
+  Tag tag;
+  Input value;
+  ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_EQ(0x04, tag);
+  ASSERT_FALSE(parser.HasMore());
+}
+
+TEST(ParserTest, CanReadRawTLV) {
+  const uint8_t der[] = {0x02, 0x01, 0x01};
+  Parser parser(Input(der, sizeof(der)));
+  Input tlv;
+  ASSERT_TRUE(parser.ReadRawTLV(&tlv));
+  ByteReader tlv_reader(tlv);
+  size_t tlv_len = tlv_reader.BytesLeft();
+  ASSERT_EQ(3u, tlv_len);
+  Input tlv_data;
+  ASSERT_TRUE(tlv_reader.ReadBytes(tlv_len, &tlv_data));
+  ASSERT_FALSE(parser.HasMore());
+}
+
+TEST(ParserTest, IgnoresContentsOfInnerValues) {
+  // This is a SEQUENCE which has one member. The member is another SEQUENCE
+  // with an invalid encoding - its length is too long.
+  const uint8_t der[] = {0x30, 0x02, 0x30, 0x7e};
+  Parser parser(Input(der, sizeof(der)));
+  Tag tag;
+  Input value;
+  ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
+}
+
+TEST(ParserTest, FailsIfLengthOverlapsAnotherTLV) {
+  // This DER encoding has 2 top-level TLV tuples. The first is a SEQUENCE;
+  // the second is an INTEGER. The SEQUENCE contains an INTEGER, but its length
+  // is longer than what it has contents for.
+  const uint8_t der[] = {0x30, 0x02, 0x02, 0x01, 0x02, 0x01, 0x01};
+  Parser parser(Input(der, sizeof(der)));
+
+  Parser inner_sequence;
+  ASSERT_TRUE(parser.ReadSequence(&inner_sequence));
+  uint64_t int_value;
+  ASSERT_TRUE(parser.ReadUint64(&int_value));
+  ASSERT_EQ(1u, int_value);
+  ASSERT_FALSE(parser.HasMore());
+
+  // Try to read the INTEGER from the SEQUENCE, which should fail.
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(inner_sequence.ReadTagAndValue(&tag, &value));
+}
+
+TEST(ParserTest, CanSkipOptionalTagAtEndOfInput) {
+  const uint8_t der[] = {0x02, 0x01, 0x01};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
+  bool present;
+  ASSERT_TRUE(parser.ReadOptionalTag(0x02, &value, &present));
+  ASSERT_FALSE(present);
+  ASSERT_FALSE(parser.HasMore());
+}
+
+TEST(ParserTest, SkipOptionalTagDoesntConsumePresentNonMatchingTLVs) {
+  const uint8_t der[] = {0x02, 0x01, 0x01};
+  Parser parser(Input(der, sizeof(der)));
+
+  bool present;
+  ASSERT_TRUE(parser.SkipOptionalTag(0x04, &present));
+  ASSERT_FALSE(present);
+  ASSERT_TRUE(parser.SkipOptionalTag(0x02, &present));
+  ASSERT_TRUE(present);
+  ASSERT_FALSE(parser.HasMore());
+}
+
+TEST(ParserTest, TagNumbersAboveThirtyUnsupported) {
+  // Context-specific class, tag number 31, length 0.
+  const uint8_t der[] = {0x9f, 0x1f, 0x00};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_TRUE(parser.HasMore());
+}
+
+TEST(ParserTest, IncompleteEncodingTagOnly) {
+  const uint8_t der[] = {0x01};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_TRUE(parser.HasMore());
+}
+
+TEST(ParserTest, IncompleteEncodingLengthTruncated) {
+  // Tag: octet string; length: long form, should have 2 total octets, but
+  // the last one is missing. (There's also no value.)
+  const uint8_t der[] = {0x04, 0x81};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_TRUE(parser.HasMore());
+}
+
+TEST(ParserTest, IncompleteEncodingValueShorterThanLength) {
+  // Tag: octet string; length: 2; value: first octet 'T', second octet missing.
+  const uint8_t der[] = {0x04, 0x02, 0x84};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_TRUE(parser.HasMore());
+}
+
+TEST(ParserTest, LengthMustBeEncodedWithMinimumNumberOfOctets) {
+  const uint8_t der[] = {0x01, 0x81, 0x01, 0x00};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_TRUE(parser.HasMore());
+}
+
+TEST(ParserTest, LengthMustNotHaveLeadingZeroes) {
+  // Tag: octet string; length: 3 bytes of length encoding a value of 128
+  // (it should be encoded in only 2 bytes). Value: 128 bytes of 0.
+  const uint8_t der[] = {
+      0x04, 0x83, 0x80, 0x81, 0x80,  // group the 0s separately
+      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};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag tag;
+  Input value;
+  ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
+  ASSERT_TRUE(parser.HasMore());
+}
+
+TEST(ParserTest, ReadConstructedFailsForNonConstructedTags) {
+  // Tag number is for SEQUENCE, but the constructed bit isn't set.
+  const uint8_t der[] = {0x10, 0x00};
+  Parser parser(Input(der, sizeof(der)));
+
+  Tag expected_tag = 0x10;
+  Parser sequence_parser;
+  ASSERT_FALSE(parser.ReadConstructed(expected_tag, &sequence_parser));
+
+  // Check that we didn't fail above because of a tag mismatch or an improperly
+  // encoded TLV.
+  Input value;
+  ASSERT_TRUE(parser.ReadTag(expected_tag, &value));
+  ASSERT_FALSE(parser.HasMore());
+}
+
+TEST(ParserTest, CannotAdvanceAfterReadOptionalTag) {
+  const uint8_t der[] = {0x02, 0x01, 0x01};
+  Parser parser(Input(der, sizeof(der)));
+
+  Input value;
+  bool present;
+  ASSERT_TRUE(parser.ReadOptionalTag(0x04, &value, &present));
+  ASSERT_FALSE(present);
+  ASSERT_FALSE(parser.Advance());
+}
+
+}  // namespace test
+}  // namespace der
+}  // namespace net
diff --git a/net/der/tag.cc b/net/der/tag.cc
new file mode 100644
index 0000000..00ced68
--- /dev/null
+++ b/net/der/tag.cc
@@ -0,0 +1,28 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "net/der/tag.h"
+
+namespace net {
+
+namespace der {
+
+Tag ContextSpecificConstructed(uint8_t base) {
+  DCHECK_EQ(base, base & kTagNumberMask);
+  return (base & kTagNumberMask) | kTagConstructed | kTagContextSpecific;
+}
+
+Tag ContextSpecificPrimitive(uint8_t base) {
+  DCHECK_EQ(base, base & kTagNumberMask);
+  return (base & kTagNumberMask) | kTagPrimitive | kTagContextSpecific;
+}
+
+bool IsConstructed(Tag tag) {
+  return (tag & kTagConstructionMask) == kTagConstructed;
+}
+
+}  // namespace der
+
+}  // namespace net
diff --git a/net/der/tag.h b/net/der/tag.h
new file mode 100644
index 0000000..e9092cb
--- /dev/null
+++ b/net/der/tag.h
@@ -0,0 +1,63 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DER_TAG_H_
+#define NET_DER_TAG_H_
+
+#include <stdint.h>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace der {
+
+// This Tag type represents the identifier for an ASN.1 tag as encoded with DER.
+// It follows the same bit-for-bit representation (including the class, tag
+// number, and primitive/constructed bit) as DER. Constants are provided for
+// universal class types, and functions are provided for building context
+// specific tags. Tags can also be built from the provided constants and
+// bitmasks.
+using Tag = uint8_t;
+
+// Universal class primitive types
+const Tag kBool = 0x01;
+const Tag kInteger = 0x02;
+const Tag kBitString = 0x03;
+const Tag kOctetString = 0x04;
+const Tag kNull = 0x05;
+const Tag kOid = 0x06;
+const Tag kUtf8String = 0x0C;
+const Tag kPrintableString = 0x13;
+const Tag kUtcTime = 0x17;
+const Tag kGeneralizedTime = 0x18;
+
+// Universal class constructed types
+const Tag kSequence = 0x30;
+const Tag kSet = 0x31;
+
+// Primitive/constructed bits
+const uint8_t kTagPrimitive = 0x00;
+const uint8_t kTagConstructed = 0x20;
+
+// Tag classes
+const uint8_t kTagUniversal = 0x00;
+const uint8_t kTagApplication = 0x40;
+const uint8_t kTagContextSpecific = 0x80;
+const uint8_t kTagPrivate = 0xC0;
+
+// Masks for the 3 components of a tag (class, primitive/constructed, number)
+const uint8_t kTagNumberMask = 0x1F;
+const uint8_t kTagConstructionMask = 0x20;
+const uint8_t kTagClassMask = 0xC0;
+
+NET_EXPORT Tag ContextSpecificConstructed(uint8_t base);
+NET_EXPORT Tag ContextSpecificPrimitive(uint8_t base);
+NET_EXPORT bool IsConstructed(Tag tag);
+
+}  // namespace der
+
+}  // namespace net
+
+#endif  // NET_DER_TAG_H_
diff --git a/net/disk_cache/blockfile/backend_impl_v3.cc b/net/disk_cache/blockfile/backend_impl_v3.cc
index 96157551..64016c4 100644
--- a/net/disk_cache/blockfile/backend_impl_v3.cc
+++ b/net/disk_cache/blockfile/backend_impl_v3.cc
@@ -667,8 +667,8 @@
       : background_queue_(background_queue), data_(NULL) {
   }
 
-  virtual int OpenNextEntry(Entry** next_entry,
-                            const net::CompletionCallback& callback) override {
+  int OpenNextEntry(Entry** next_entry,
+                    const net::CompletionCallback& callback) override {
     if (!background_queue_)
       return net::ERR_FAILED;
     background_queue_->OpenNextEntry(&data_, next_entry, callback);
diff --git a/net/disk_cache/blockfile/entry_impl.cc b/net/disk_cache/blockfile/entry_impl.cc
index 76bf7c7..add38de 100644
--- a/net/disk_cache/blockfile/entry_impl.cc
+++ b/net/disk_cache/blockfile/entry_impl.cc
@@ -62,7 +62,7 @@
 void SyncCallback::OnFileIOComplete(int bytes_copied) {
   entry_->DecrementIoCount();
   if (!callback_.is_null()) {
-    if (entry_->net_log().IsLogging()) {
+    if (entry_->net_log().GetCaptureMode().enabled()) {
       entry_->net_log().EndEvent(
           end_event_type_,
           disk_cache::CreateNetLogReadWriteCompleteCallback(bytes_copied));
@@ -315,7 +315,7 @@
 
 int EntryImpl::ReadDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
                             const CompletionCallback& callback) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_ENTRY_READ_DATA,
         CreateNetLogReadWriteDataCallback(index, offset, buf_len, false));
@@ -323,7 +323,7 @@
 
   int result = InternalReadData(index, offset, buf, buf_len, callback);
 
-  if (result != net::ERR_IO_PENDING && net_log_.IsLogging()) {
+  if (result != net::ERR_IO_PENDING && net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_ENTRY_READ_DATA,
         CreateNetLogReadWriteCompleteCallback(result));
@@ -334,7 +334,7 @@
 int EntryImpl::WriteDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
                              const CompletionCallback& callback,
                              bool truncate) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_ENTRY_WRITE_DATA,
         CreateNetLogReadWriteDataCallback(index, offset, buf_len, truncate));
@@ -343,7 +343,7 @@
   int result = InternalWriteData(index, offset, buf, buf_len, callback,
                                  truncate);
 
-  if (result != net::ERR_IO_PENDING && net_log_.IsLogging()) {
+  if (result != net::ERR_IO_PENDING && net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_ENTRY_WRITE_DATA,
         CreateNetLogReadWriteCompleteCallback(result));
diff --git a/net/disk_cache/blockfile/entry_impl_v3.cc b/net/disk_cache/blockfile/entry_impl_v3.cc
index 04e9ad9..78ef1b8 100644
--- a/net/disk_cache/blockfile/entry_impl_v3.cc
+++ b/net/disk_cache/blockfile/entry_impl_v3.cc
@@ -547,7 +547,7 @@
 
 int EntryImpl::ReadDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
                             const CompletionCallback& callback) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_ENTRY_READ_DATA,
         CreateNetLogReadWriteDataCallback(index, offset, buf_len, false));
@@ -555,7 +555,7 @@
 
   int result = InternalReadData(index, offset, buf, buf_len, callback);
 
-  if (result != net::ERR_IO_PENDING && net_log_.IsLogging()) {
+  if (result != net::ERR_IO_PENDING && net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_ENTRY_READ_DATA,
         CreateNetLogReadWriteCompleteCallback(result));
@@ -586,7 +586,7 @@
 int EntryImpl::WriteDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
                              const CompletionCallback& callback,
                              bool truncate) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_ENTRY_WRITE_DATA,
         CreateNetLogReadWriteDataCallback(index, offset, buf_len, truncate));
@@ -595,7 +595,7 @@
   int result = InternalWriteData(index, offset, buf, buf_len, callback,
                                  truncate);
 
-  if (result != net::ERR_IO_PENDING && net_log_.IsLogging()) {
+  if (result != net::ERR_IO_PENDING && net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_ENTRY_WRITE_DATA,
         CreateNetLogReadWriteCompleteCallback(result));
diff --git a/net/disk_cache/blockfile/sparse_control.cc b/net/disk_cache/blockfile/sparse_control.cc
index e5096dc..8ce659da0 100644
--- a/net/disk_cache/blockfile/sparse_control.cc
+++ b/net/disk_cache/blockfile/sparse_control.cc
@@ -161,7 +161,7 @@
 void LogChildOperationEnd(const net::BoundNetLog& net_log,
                           disk_cache::SparseControl::SparseOperation operation,
                           int result) {
-  if (net_log.IsLogging()) {
+  if (net_log.GetCaptureMode().enabled()) {
     net::NetLog::EventType event_type;
     switch (operation) {
       case disk_cache::SparseControl::kReadOperation:
@@ -275,7 +275,7 @@
   finished_ = false;
   abort_ = false;
 
-  if (entry_->net_log().IsLogging()) {
+  if (entry_->net_log().GetCaptureMode().enabled()) {
     entry_->net_log().BeginEvent(
         GetSparseEventType(operation_),
         CreateNetLogSparseOperationCallback(offset_, buf_len_));
@@ -679,14 +679,14 @@
   // Range operations are finished synchronously, often without setting
   // |finished_| to true.
   if (kGetRangeOperation == operation_ &&
-      entry_->net_log().IsLogging()) {
+      entry_->net_log().GetCaptureMode().enabled()) {
     entry_->net_log().EndEvent(
         net::NetLog::TYPE_SPARSE_GET_RANGE,
         CreateNetLogGetAvailableRangeResultCallback(offset_, result_));
   }
   if (finished_) {
     if (kGetRangeOperation != operation_ &&
-        entry_->net_log().IsLogging()) {
+        entry_->net_log().GetCaptureMode().enabled()) {
       entry_->net_log().EndEvent(GetSparseEventType(operation_));
     }
     if (pending_)
@@ -716,7 +716,7 @@
   int rv = 0;
   switch (operation_) {
     case kReadOperation:
-      if (entry_->net_log().IsLogging()) {
+      if (entry_->net_log().GetCaptureMode().enabled()) {
         entry_->net_log().BeginEvent(
             net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
             CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
@@ -726,7 +726,7 @@
                                 child_len_, callback);
       break;
     case kWriteOperation:
-      if (entry_->net_log().IsLogging()) {
+      if (entry_->net_log().GetCaptureMode().enabled()) {
         entry_->net_log().BeginEvent(
             net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
             CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
@@ -856,7 +856,7 @@
     // We'll return the current result of the operation, which may be less than
     // the bytes to read or write, but the user cancelled the operation.
     abort_ = false;
-    if (entry_->net_log().IsLogging()) {
+    if (entry_->net_log().GetCaptureMode().enabled()) {
       entry_->net_log().AddEvent(net::NetLog::TYPE_CANCELLED);
       entry_->net_log().EndEvent(GetSparseEventType(operation_));
     }
diff --git a/net/disk_cache/blockfile/sparse_control_v3.cc b/net/disk_cache/blockfile/sparse_control_v3.cc
index cba0ed5..91492b3 100644
--- a/net/disk_cache/blockfile/sparse_control_v3.cc
+++ b/net/disk_cache/blockfile/sparse_control_v3.cc
@@ -56,7 +56,7 @@
   ChildrenDeleter(disk_cache::BackendImpl* backend, const std::string& name)
       : backend_(backend->GetWeakPtr()), name_(name), signature_(0) {}
 
-  virtual void OnFileIOComplete(int bytes_copied) override;
+  void OnFileIOComplete(int bytes_copied) override;
 
   // Two ways of deleting the children: if we have the children map, use Start()
   // directly, otherwise pass the data address to ReadData().
@@ -65,7 +65,7 @@
 
  private:
   friend class base::RefCounted<ChildrenDeleter>;
-  virtual ~ChildrenDeleter() {}
+  ~ChildrenDeleter() override {}
 
   void DeleteChildren();
 
@@ -163,7 +163,7 @@
 void LogChildOperationEnd(const net::BoundNetLog& net_log,
                           disk_cache::SparseControl::SparseOperation operation,
                           int result) {
-  if (net_log.IsLogging()) {
+  if (net_log.GetCaptureMode().enabled()) {
     net::NetLog::EventType event_type;
     switch (operation) {
       case disk_cache::SparseControl::kReadOperation:
@@ -254,7 +254,7 @@
   finished_ = false;
   abort_ = false;
 
-  if (entry_->net_log().IsLogging()) {
+  if (entry_->net_log().GetCaptureMode().enabled()) {
     entry_->net_log().BeginEvent(
         GetSparseEventType(operation_),
         CreateNetLogSparseOperationCallback(offset_, buf_len_));
@@ -563,7 +563,7 @@
   int rv = 0;
   switch (operation_) {
     case kReadOperation:
-      if (entry_->net_log().IsLogging()) {
+      if (entry_->net_log().GetCaptureMode().enabled()) {
         entry_->net_log().BeginEvent(
             net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
             CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
@@ -573,7 +573,7 @@
                                 child_len_, callback);
       break;
     case kWriteOperation:
-      if (entry_->net_log().IsLogging()) {
+      if (entry_->net_log().GetCaptureMode().enabled()) {
         entry_->net_log().BeginEvent(
             net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
             CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
@@ -846,7 +846,7 @@
     // We'll return the current result of the operation, which may be less than
     // the bytes to read or write, but the user cancelled the operation.
     abort_ = false;
-    if (entry_->net_log().IsLogging()) {
+    if (entry_->net_log().GetCaptureMode().enabled()) {
       entry_->net_log().AddEvent(net::NetLog::TYPE_CANCELLED);
       entry_->net_log().EndEvent(GetSparseEventType(operation_));
     }
diff --git a/net/disk_cache/memory/mem_entry_impl.cc b/net/disk_cache/memory/mem_entry_impl.cc
index 7c6199b..c1dc8cf 100644
--- a/net/disk_cache/memory/mem_entry_impl.cc
+++ b/net/disk_cache/memory/mem_entry_impl.cc
@@ -48,7 +48,7 @@
 base::Value* NetLogChildEntryCreationCallback(
     const disk_cache::MemEntryImpl* parent,
     int child_id,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("key", GenerateChildName(parent->GetKey(), child_id));
   dict->SetBoolean("created", true);
@@ -185,7 +185,7 @@
 
 int MemEntryImpl::ReadData(int index, int offset, IOBuffer* buf, int buf_len,
                            const CompletionCallback& callback) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_ENTRY_READ_DATA,
         CreateNetLogReadWriteDataCallback(index, offset, buf_len, false));
@@ -193,7 +193,7 @@
 
   int result = InternalReadData(index, offset, buf, buf_len);
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_ENTRY_READ_DATA,
         CreateNetLogReadWriteCompleteCallback(result));
@@ -203,7 +203,7 @@
 
 int MemEntryImpl::WriteData(int index, int offset, IOBuffer* buf, int buf_len,
                             const CompletionCallback& callback, bool truncate) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_ENTRY_WRITE_DATA,
         CreateNetLogReadWriteDataCallback(index, offset, buf_len, truncate));
@@ -211,7 +211,7 @@
 
   int result = InternalWriteData(index, offset, buf, buf_len, truncate);
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_ENTRY_WRITE_DATA,
         CreateNetLogReadWriteCompleteCallback(result));
@@ -221,39 +221,39 @@
 
 int MemEntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
                                  const CompletionCallback& callback) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_SPARSE_READ,
         CreateNetLogSparseOperationCallback(offset, buf_len));
   }
   int result = InternalReadSparseData(offset, buf, buf_len);
-  if (net_log_.IsLogging())
+  if (net_log_.GetCaptureMode().enabled())
     net_log_.EndEvent(net::NetLog::TYPE_SPARSE_READ);
   return result;
 }
 
 int MemEntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
                                   const CompletionCallback& callback) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_SPARSE_WRITE,
         CreateNetLogSparseOperationCallback(offset, buf_len));
   }
   int result = InternalWriteSparseData(offset, buf, buf_len);
-  if (net_log_.IsLogging())
+  if (net_log_.GetCaptureMode().enabled())
     net_log_.EndEvent(net::NetLog::TYPE_SPARSE_WRITE);
   return result;
 }
 
 int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start,
                                     const CompletionCallback& callback) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.BeginEvent(
         net::NetLog::TYPE_SPARSE_GET_RANGE,
         CreateNetLogSparseOperationCallback(offset, len));
   }
   int result = GetAvailableRange(offset, len, start);
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEvent(
         net::NetLog::TYPE_SPARSE_GET_RANGE,
         CreateNetLogGetAvailableRangeResultCallback(*start, result));
@@ -373,7 +373,7 @@
     // we should stop.
     if (child_offset < child->child_first_pos_)
       break;
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.BeginEvent(
           net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
           CreateNetLogSparseReadWriteCallback(child->net_log().source(),
@@ -381,7 +381,7 @@
     }
     int ret = child->ReadData(kSparseData, child_offset, io_buf.get(),
                               io_buf->BytesRemaining(), CompletionCallback());
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.EndEventWithNetErrorCode(
           net::NetLog::TYPE_SPARSE_READ_CHILD_DATA, ret);
     }
@@ -430,7 +430,7 @@
     // Keep a record of the last byte position (exclusive) in the child.
     int data_size = child->GetDataSize(kSparseData);
 
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.BeginEvent(
           net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
           CreateNetLogSparseReadWriteCallback(child->net_log().source(),
@@ -443,7 +443,7 @@
     // continuous we may want to discard this write.
     int ret = child->WriteData(kSparseData, child_offset, io_buf.get(),
                                write_len, CompletionCallback(), true);
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.EndEventWithNetErrorCode(
           net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA, ret);
     }
diff --git a/net/disk_cache/net_log_parameters.cc b/net/disk_cache/net_log_parameters.cc
index 5d7e50f..b13f916 100644
--- a/net/disk_cache/net_log_parameters.cc
+++ b/net/disk_cache/net_log_parameters.cc
@@ -16,7 +16,7 @@
 base::Value* NetLogEntryCreationCallback(
     const disk_cache::Entry* entry,
     bool created,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("key", entry->GetKey());
   dict->SetBoolean("created", created);
@@ -28,7 +28,7 @@
     int offset,
     int buf_len,
     bool truncate,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("index", index);
   dict->SetInteger("offset", offset);
@@ -40,7 +40,7 @@
 
 base::Value* NetLogReadWriteCompleteCallback(
     int bytes_copied,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   DCHECK_NE(bytes_copied, net::ERR_IO_PENDING);
   base::DictionaryValue* dict = new base::DictionaryValue();
   if (bytes_copied < 0) {
@@ -54,7 +54,7 @@
 base::Value* NetLogSparseOperationCallback(
     int64 offset,
     int buff_len,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   // Values can only be created with at most 32-bit integers.  Using a string
   // instead circumvents that restriction.
@@ -66,7 +66,7 @@
 base::Value* NetLogSparseReadWriteCallback(
     const net::NetLog::Source& source,
     int child_len,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   source.AddToEventParameters(dict);
   dict->SetInteger("child_len", child_len);
@@ -76,7 +76,7 @@
 base::Value* NetLogGetAvailableRangeResultCallback(
     int64 start,
     int result,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   if (result > 0) {
     dict->SetInteger("length", result);
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index f8f1b85..a062dc2 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -347,7 +347,7 @@
                               const CompletionCallback& callback) {
   DCHECK(io_thread_checker_.CalledOnValidThread());
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_CALL,
         CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len,
                                           false));
@@ -355,7 +355,7 @@
 
   if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount ||
       buf_len < 0) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END,
           CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
     }
@@ -365,7 +365,7 @@
   }
   if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) ||
                                       offset < 0 || !buf_len)) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END,
           CreateNetLogReadWriteCompleteCallback(0));
     }
@@ -394,7 +394,7 @@
                                bool truncate) {
   DCHECK(io_thread_checker_.CalledOnValidThread());
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_CALL,
         CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len,
@@ -403,7 +403,7 @@
 
   if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount ||
       offset < 0 || buf_len < 0) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(
           net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END,
           CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
@@ -412,7 +412,7 @@
     return net::ERR_INVALID_ARGUMENT;
   }
   if (backend_.get() && offset + buf_len > backend_->GetMaxFileSize()) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(
           net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END,
           CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
@@ -454,7 +454,7 @@
     }
     op_callback = CompletionCallback();
     ret_value = buf_len;
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(
           net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_OPTIMISTIC,
           CreateNetLogReadWriteCompleteCallback(buf_len));
@@ -809,7 +809,7 @@
   DCHECK(io_thread_checker_.CalledOnValidThread());
   ScopedOperationRunner operation_runner(this);
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_BEGIN,
         CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len,
@@ -825,7 +825,7 @@
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE, base::Bind(callback, net::ERR_FAILED));
     }
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(
           net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END,
           CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
@@ -892,7 +892,7 @@
   DCHECK(io_thread_checker_.CalledOnValidThread());
   ScopedOperationRunner operation_runner(this);
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_BEGIN,
         CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len,
@@ -901,7 +901,7 @@
 
   if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
     RecordWriteResult(cache_type_, WRITE_RESULT_BAD_STATE);
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.AddEvent(
           net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END,
           CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
@@ -1230,7 +1230,7 @@
       crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE;
     }
   }
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END,
         CreateNetLogReadWriteCompleteCallback(*result));
@@ -1248,7 +1248,7 @@
     RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS);
   else
     RecordWriteResult(cache_type_, WRITE_RESULT_SYNC_WRITE_FAILURE);
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END,
         CreateNetLogReadWriteCompleteCallback(*result));
   }
@@ -1319,7 +1319,7 @@
   DCHECK_EQ(STATE_IO_PENDING, state_);
   DCHECK(result);
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEventWithNetErrorCode(
         net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_END,
         *result);
@@ -1334,7 +1334,7 @@
   } else {
     RecordReadResult(cache_type_, READ_RESULT_SYNC_CHECKSUM_FAILURE);
   }
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END,
         CreateNetLogReadWriteCompleteCallback(*result));
   }
diff --git a/net/disk_cache/simple/simple_net_log_parameters.cc b/net/disk_cache/simple/simple_net_log_parameters.cc
index 4756c83..f3d9fe5 100644
--- a/net/disk_cache/simple/simple_net_log_parameters.cc
+++ b/net/disk_cache/simple/simple_net_log_parameters.cc
@@ -17,7 +17,7 @@
 
 base::Value* NetLogSimpleEntryConstructionCallback(
     const disk_cache::SimpleEntryImpl* entry,
-    net::NetLog::LogLevel log_level) {
+    net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("entry_hash",
                   base::StringPrintf("%#016" PRIx64, entry->entry_hash()));
@@ -27,7 +27,7 @@
 base::Value* NetLogSimpleEntryCreationCallback(
     const disk_cache::SimpleEntryImpl* entry,
     int net_error,
-    net::NetLog::LogLevel /* log_level */) {
+    net::NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("net_error", net_error);
   if (net_error == net::OK)
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc
index aee3ba74..30e3d2e7 100644
--- a/net/dns/dns_test_util.cc
+++ b/net/dns/dns_test_util.cc
@@ -60,15 +60,11 @@
     }
   }
 
-  virtual const std::string& GetHostname() const override {
-    return hostname_;
-  }
+  const std::string& GetHostname() const override { return hostname_; }
 
-  virtual uint16 GetType() const override {
-    return qtype_;
-  }
+  uint16 GetType() const override { return qtype_; }
 
-  virtual void Start() override {
+  void Start() override {
     EXPECT_FALSE(started_);
     started_ = true;
     if (delayed_)
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index 8c0b28b..0147092 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -59,8 +59,8 @@
 }
 
 base::Value* NetLogStartCallback(const std::string* hostname,
-                           uint16 qtype,
-                           NetLog::LogLevel /* log_level */) {
+                                 uint16 qtype,
+                                 NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("hostname", *hostname);
   dict->SetInteger("query_type", qtype);
@@ -98,7 +98,7 @@
   // Returns a Value representing the received response, along with a reference
   // to the NetLog source source of the UDP socket used.  The request must have
   // completed before this is called.
-  base::Value* NetLogResponseCallback(NetLog::LogLevel log_level) const {
+  base::Value* NetLogResponseCallback(NetLogCaptureMode capture_mode) const {
     DCHECK(GetResponse()->IsValid());
 
     base::DictionaryValue* dict = new base::DictionaryValue();
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
index 35ea2fa2..5e050c6 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_impl.cc
@@ -297,10 +297,11 @@
 }
 
 // Creates NetLog parameters when the resolve failed.
-base::Value* NetLogProcTaskFailedCallback(uint32 attempt_number,
-                                          int net_error,
-                                          int os_error,
-                                          NetLog::LogLevel /* log_level */) {
+base::Value* NetLogProcTaskFailedCallback(
+    uint32 attempt_number,
+    int net_error,
+    int os_error,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   if (attempt_number)
     dict->SetInteger("attempt_number", attempt_number);
@@ -332,7 +333,7 @@
 // Creates NetLog parameters when the DnsTask failed.
 base::Value* NetLogDnsTaskFailedCallback(int net_error,
                                          int dns_error,
-                                         NetLog::LogLevel /* log_level */) {
+                                         NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("net_error", net_error);
   if (dns_error)
@@ -343,7 +344,7 @@
 // Creates NetLog parameters containing the information in a RequestInfo object,
 // along with the associated NetLog::Source.
 base::Value* NetLogRequestInfoCallback(const HostResolver::RequestInfo* info,
-                                       NetLog::LogLevel /* log_level */) {
+                                       NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("host", info->host_port_pair().ToString());
@@ -357,7 +358,7 @@
 // Creates NetLog parameters for the creation of a HostResolverImpl::Job.
 base::Value* NetLogJobCreationCallback(const NetLog::Source& source,
                                        const std::string* host,
-                                       NetLog::LogLevel /* log_level */) {
+                                       NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   source.AddToEventParameters(dict);
   dict->SetString("host", *host);
@@ -367,7 +368,7 @@
 // Creates NetLog parameters for HOST_RESOLVER_IMPL_JOB_ATTACH/DETACH events.
 base::Value* NetLogJobAttachCallback(const NetLog::Source& source,
                                      RequestPriority priority,
-                                     NetLog::LogLevel /* log_level */) {
+                                     NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   source.AddToEventParameters(dict);
   dict->SetString("priority", RequestPriorityToString(priority));
@@ -376,7 +377,7 @@
 
 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
 base::Value* NetLogDnsConfigCallback(const DnsConfig* config,
-                                     NetLog::LogLevel /* log_level */) {
+                                     NetLogCaptureMode /* capture_mode */) {
   return config->ToValue();
 }
 
diff --git a/net/dns/mock_mdns_socket_factory.h b/net/dns/mock_mdns_socket_factory.h
index 6278661..c1536bc1 100644
--- a/net/dns/mock_mdns_socket_factory.h
+++ b/net/dns/mock_mdns_socket_factory.h
@@ -15,7 +15,7 @@
 class MockMDnsDatagramServerSocket : public DatagramServerSocket {
  public:
   explicit MockMDnsDatagramServerSocket(AddressFamily address_family);
-  ~MockMDnsDatagramServerSocket();
+  ~MockMDnsDatagramServerSocket() override;
 
   // DatagramServerSocket implementation:
   MOCK_METHOD1(Listen, int(const IPEndPoint& address));
@@ -26,8 +26,10 @@
                              IPEndPoint* address,
                              const CompletionCallback& callback));
 
-  virtual int SendTo(IOBuffer* buf, int buf_len, const IPEndPoint& address,
-                     const CompletionCallback& callback) override;
+  int SendTo(IOBuffer* buf,
+             int buf_len,
+             const IPEndPoint& address,
+             const CompletionCallback& callback) override;
 
   MOCK_METHOD3(SendToInternal, int(const std::string& packet,
                                    const std::string address,
@@ -39,7 +41,7 @@
   MOCK_METHOD0(Close, void());
 
   MOCK_CONST_METHOD1(GetPeerAddress, int(IPEndPoint* address));
-  virtual int GetLocalAddress(IPEndPoint* address) const override;
+  int GetLocalAddress(IPEndPoint* address) const override;
   MOCK_CONST_METHOD0(NetLog, const BoundNetLog&());
 
   MOCK_METHOD0(AllowAddressReuse, void());
@@ -72,10 +74,9 @@
 class MockMDnsSocketFactory : public MDnsSocketFactory {
  public:
   MockMDnsSocketFactory();
-  virtual ~MockMDnsSocketFactory();
+  ~MockMDnsSocketFactory() override;
 
-  virtual void CreateSockets(
-      ScopedVector<DatagramServerSocket>* sockets) override;
+  void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) override;
 
   void SimulateReceive(const uint8* packet, int size);
 
diff --git a/net/filter/sdch_filter.cc b/net/filter/sdch_filter.cc
index 6b52d8f..858e101 100644
--- a/net/filter/sdch_filter.cc
+++ b/net/filter/sdch_filter.cc
@@ -93,7 +93,7 @@
 base::Value* NetLogSdchResponseCorruptionDetectionCallback(
     ResponseCorruptionDetectionCause cause,
     bool cached,
-    NetLog::LogLevel log_level) {
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("cause", ResponseCorruptionDetectionCauseToString(cause));
   dict->SetBoolean("cached", cached);
diff --git a/net/ftp/ftp_ctrl_response_buffer.cc b/net/ftp/ftp_ctrl_response_buffer.cc
index f7b14678..36486b7 100644
--- a/net/ftp/ftp_ctrl_response_buffer.cc
+++ b/net/ftp/ftp_ctrl_response_buffer.cc
@@ -80,7 +80,7 @@
 namespace {
 
 base::Value* NetLogFtpCtrlResponseCallback(const FtpCtrlResponse* response,
-                                           NetLog::LogLevel log_level) {
+                                           NetLogCaptureMode capture_mode) {
   base::ListValue* lines = new base::ListValue();
   lines->AppendStrings(response->lines);
 
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 5d6dc4d..cebecda 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -228,7 +228,7 @@
 base::Value* NetLogAsyncRevalidationInfoCallback(
     const net::NetLog::Source& source,
     const net::HttpRequestInfo* request,
-    net::NetLog::LogLevel log_level) {
+    net::NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   source.AddToEventParameters(dict);
 
@@ -1645,7 +1645,7 @@
   next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE;
   if (!entry_)
     return OK;
-  if (net_log_.IsLogging())
+  if (net_log_.GetCaptureMode().enabled())
     net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA);
   // Truncate the stream.
   return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_);
@@ -1653,7 +1653,7 @@
 
 int HttpCache::Transaction::DoTruncateCachedDataComplete(int result) {
   if (entry_) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA,
                                         result);
     }
@@ -1668,14 +1668,14 @@
   if (!entry_)
     return OK;
 
-  if (net_log_.IsLogging())
+  if (net_log_.GetCaptureMode().enabled())
     net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
   return WriteToEntry(kMetadataIndex, 0, NULL, 0, io_callback_);
 }
 
 int HttpCache::Transaction::DoTruncateCachedMetadataComplete(int result) {
   if (entry_) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO,
                                         result);
     }
@@ -1812,7 +1812,7 @@
           "422516 HttpCache::Transaction::DoCacheWriteResponse"));
 
   if (entry_) {
-    if (net_log_.IsLogging())
+    if (net_log_.GetCaptureMode().enabled())
       net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
   }
   return WriteResponseInfoToEntry(false);
@@ -1820,7 +1820,7 @@
 
 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
   if (entry_) {
-    if (net_log_.IsLogging())
+    if (net_log_.GetCaptureMode().enabled())
       net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
   }
   return WriteResponseInfoToEntry(true);
@@ -1831,7 +1831,7 @@
   target_state_ = STATE_NONE;
   if (!entry_)
     return OK;
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO,
                                       result);
   }
@@ -1883,7 +1883,7 @@
   DCHECK(entry_);
   next_state_ = STATE_CACHE_READ_DATA_COMPLETE;
 
-  if (net_log_.IsLogging())
+  if (net_log_.GetCaptureMode().enabled())
     net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA);
   if (partial_.get()) {
     return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_,
@@ -1896,7 +1896,7 @@
 }
 
 int HttpCache::Transaction::DoCacheReadDataComplete(int result) {
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA,
                                       result);
   }
@@ -1927,7 +1927,7 @@
   next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE;
   write_len_ = num_bytes;
   if (entry_) {
-    if (net_log_.IsLogging())
+    if (net_log_.GetCaptureMode().enabled())
       net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA);
   }
 
@@ -1936,7 +1936,7 @@
 
 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
   if (entry_) {
-    if (net_log_.IsLogging()) {
+    if (net_log_.GetCaptureMode().enabled()) {
       net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA,
                                         result);
     }
@@ -2758,7 +2758,7 @@
   if ((response_.headers->HasHeaderValue("cache-control", "no-store")) ||
       net::IsCertStatusError(response_.ssl_info.cert_status)) {
     DoneWritingToEntry(false);
-    if (net_log_.IsLogging())
+    if (net_log_.GetCaptureMode().enabled())
       net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
     return OK;
   }
diff --git a/net/http/http_log_util.cc b/net/http/http_log_util.cc
index 7e93911..0467fb605a 100644
--- a/net/http/http_log_util.cc
+++ b/net/http/http_log_util.cc
@@ -34,15 +34,14 @@
 
 }  // namespace
 
-std::string ElideHeaderValueForNetLog(NetLog::LogLevel log_level,
+std::string ElideHeaderValueForNetLog(NetLogCaptureMode capture_mode,
                                       const std::string& header,
                                       const std::string& value) {
   std::string::const_iterator redact_begin = value.begin();
   std::string::const_iterator redact_end = value.begin();
 
   if (redact_begin == redact_end &&
-      log_level >= NetLog::LOG_STRIP_PRIVATE_DATA) {
-
+      !capture_mode.include_cookies_and_credentials()) {
     // Note: this logic should be kept in sync with stripCookiesAndLoginInfo in
     // chrome/browser/resources/net_internals/log_view_painter.js.
 
diff --git a/net/http/http_log_util.h b/net/http/http_log_util.h
index 6894809..7758943 100644
--- a/net/http/http_log_util.h
+++ b/net/http/http_log_util.h
@@ -15,7 +15,7 @@
 // Given an HTTP header |header| with value |value|, returns the elided version
 // of the header value at |log_level|.
 NET_EXPORT_PRIVATE std::string ElideHeaderValueForNetLog(
-    NetLog::LogLevel log_level,
+    NetLogCaptureMode capture_mode,
     const std::string& header,
     const std::string& value);
 
diff --git a/net/http/http_log_util_unittest.cc b/net/http/http_log_util_unittest.cc
index dd6af69..bd9c79f 100644
--- a/net/http/http_log_util_unittest.cc
+++ b/net/http/http_log_util_unittest.cc
@@ -9,50 +9,63 @@
 
 TEST(HttpLogUtilTest, ElideHeaderValueForNetLog) {
   // Only elide for appropriate log level.
-  EXPECT_EQ("[10 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Cookie", "name=value"));
+  EXPECT_EQ("[10 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(), "Cookie",
+                                      "name=value"));
   EXPECT_EQ("name=value", ElideHeaderValueForNetLog(
-      NetLog::LOG_ALL_BUT_BYTES, "Cookie", "name=value"));
+                              NetLogCaptureMode::IncludeCookiesAndCredentials(),
+                              "Cookie", "name=value"));
 
   // Headers are compared case insensitively.
-  EXPECT_EQ("[10 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "cOoKiE", "name=value"));
+  EXPECT_EQ("[10 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(), "cOoKiE",
+                                      "name=value"));
 
   // These headers should be completely elided.
-  EXPECT_EQ("[10 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Set-Cookie", "name=value"));
-  EXPECT_EQ("[10 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Set-Cookie2", "name=value"));
-  EXPECT_EQ("[10 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Authorization", "Basic 1234"));
-  EXPECT_EQ("[10 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Proxy-Authorization", "Basic 1234"));
+  EXPECT_EQ("[10 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "Set-Cookie", "name=value"));
+  EXPECT_EQ("[10 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "Set-Cookie2", "name=value"));
+  EXPECT_EQ("[10 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "Authorization", "Basic 1234"));
+  EXPECT_EQ("[10 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "Proxy-Authorization", "Basic 1234"));
 
   // Unknown headers should pass through.
-  EXPECT_EQ("value", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Boring", "value"));
+  EXPECT_EQ("value", ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                               "Boring", "value"));
 
   // Basic and Digest auth challenges are public.
+  EXPECT_EQ("Basic realm=test",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "WWW-Authenticate", "Basic realm=test"));
+  EXPECT_EQ("Digest realm=test",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "WWW-Authenticate", "Digest realm=test"));
   EXPECT_EQ("Basic realm=test", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "WWW-Authenticate", "Basic realm=test"));
-  EXPECT_EQ("Digest realm=test", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "WWW-Authenticate", "Digest realm=test"));
-  EXPECT_EQ("Basic realm=test", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA,
-      "Proxy-Authenticate", "Basic realm=test"));
-  EXPECT_EQ("Digest realm=test", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA,
-      "Proxy-Authenticate", "Digest realm=test"));
+                                    NetLogCaptureMode::Default(),
+                                    "Proxy-Authenticate", "Basic realm=test"));
+  EXPECT_EQ(
+      "Digest realm=test",
+      ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                "Proxy-Authenticate", "Digest realm=test"));
 
   // Multi-round mechanisms partially elided.
-  EXPECT_EQ("NTLM [4 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "WWW-Authenticate", "NTLM 1234"));
-  EXPECT_EQ("NTLM [4 bytes were stripped]", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "Proxy-Authenticate", "NTLM 1234"));
+  EXPECT_EQ("NTLM [4 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "WWW-Authenticate", "NTLM 1234"));
+  EXPECT_EQ("NTLM [4 bytes were stripped]",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "Proxy-Authenticate", "NTLM 1234"));
 
   // Leave whitespace intact.
-  EXPECT_EQ("NTLM  [4 bytes were stripped] ", ElideHeaderValueForNetLog(
-      NetLog::LOG_STRIP_PRIVATE_DATA, "WWW-Authenticate", "NTLM  1234 "));
+  EXPECT_EQ("NTLM  [4 bytes were stripped] ",
+            ElideHeaderValueForNetLog(NetLogCaptureMode::Default(),
+                                      "WWW-Authenticate", "NTLM  1234 "));
 }
 
 }  // namspace net
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index b5e5d5c..3e9074ac 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -97,7 +97,7 @@
     int net_error,
     uint16 version_before,
     uint16 version_after,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("host_and_port", GetHostAndPort(*url));
   dict->SetInteger("net_error", net_error);
@@ -106,9 +106,10 @@
   return dict;
 }
 
-base::Value* NetLogSSLCipherFallbackCallback(const GURL* url,
-                                             int net_error,
-                                             NetLog::LogLevel /* log_level */) {
+base::Value* NetLogSSLCipherFallbackCallback(
+    const GURL* url,
+    int net_error,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("host_and_port", GetHostAndPort(*url));
   dict->SetInteger("net_error", net_error);
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index eb81161..a1bba94e 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -219,7 +219,7 @@
 void AddWebSocketHeaders(net::HttpRequestHeaders* headers) {
   headers->SetHeader("Connection", "Upgrade");
   headers->SetHeader("Upgrade", "websocket");
-  headers->SetHeader("Origin", "http://www.google.com");
+  headers->SetHeader("Origin", "http://www.example.org");
   headers->SetHeader("Sec-WebSocket-Version", "13");
   headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
 }
@@ -314,7 +314,7 @@
 
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/");
+    request.url = GURL("http://www.example.org/");
     request.load_flags = 0;
 
     BoundTestNetLog log;
@@ -329,7 +329,7 @@
 
     TestCompletionCallback callback;
 
-    EXPECT_TRUE(log.bound().IsLogging());
+    EXPECT_TRUE(log.bound().GetCaptureMode().enabled());
     int rv = trans->Start(&request, callback.callback(), log.bound());
     EXPECT_EQ(ERR_IO_PENDING, rv);
 
@@ -376,13 +376,13 @@
     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
     std::string value;
     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
-    EXPECT_EQ("www.google.com", value);
+    EXPECT_EQ("www.example.org", value);
     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
     EXPECT_EQ("keep-alive", value);
 
     std::string response_headers;
     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
-    EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
+    EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
               response_headers);
 
     out.totalReceivedBytes = trans->GetTotalReceivedBytes();
@@ -613,7 +613,7 @@
   if (!auth_challenge)
     return false;
   EXPECT_FALSE(auth_challenge->is_proxy);
-  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
+  EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
   EXPECT_EQ("MyRealm1", auth_challenge->realm);
   EXPECT_EQ("basic", auth_challenge->scheme);
   return true;
@@ -633,7 +633,7 @@
   if (!auth_challenge)
     return false;
   EXPECT_FALSE(auth_challenge->is_proxy);
-  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
+  EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
   EXPECT_EQ("digestive", auth_challenge->realm);
   EXPECT_EQ("digest", auth_challenge->scheme);
   return true;
@@ -1012,7 +1012,7 @@
 TEST_P(HttpNetworkTransactionTest, Head) {
   HttpRequestInfo request;
   request.method = "HEAD";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1024,10 +1024,11 @@
                  base::Unretained(&proxy_headers_handler)));
 
   MockWrite data_writes1[] = {
-    MockWrite("HEAD / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Content-Length: 0\r\n\r\n"),
+      MockWrite(
+          "HEAD / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Content-Length: 0\r\n\r\n"),
   };
   MockRead data_reads1[] = {
     MockRead("HTTP/1.1 404 Not Found\r\n"),
@@ -1095,7 +1096,7 @@
   for (int i = 0; i < 2; ++i) {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/");
+    request.url = GURL("http://www.example.org/");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
@@ -1558,7 +1559,7 @@
 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1611,7 +1612,7 @@
 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1661,7 +1662,7 @@
 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1693,7 +1694,7 @@
 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1734,7 +1735,7 @@
 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1883,7 +1884,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   TestNetLog log;
@@ -1893,9 +1894,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -1914,10 +1916,11 @@
   // After calling trans->RestartWithAuth(), this is the request we should
   // be issuing -- the final header line contains the credentials.
   MockWrite data_writes2[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -1984,7 +1987,7 @@
 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -1992,9 +1995,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -2030,7 +2034,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   TestNetLog log;
@@ -2038,16 +2042,18 @@
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
 
-    // After calling trans->RestartWithAuth(), this is the request we should
-    // be issuing -- the final header line contains the credentials.
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      // After calling trans->RestartWithAuth(), this is the request we should
+      // be issuing -- the final header line contains the credentials.
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -2130,22 +2136,24 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
 
-    // After calling trans->RestartWithAuth(), this is the request we should
-    // be issuing -- the final header line contains the credentials.
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      // After calling trans->RestartWithAuth(), this is the request we should
+      // be issuing -- the final header line contains the credentials.
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -2206,22 +2214,24 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
 
-    // After calling trans->RestartWithAuth(), this is the request we should
-    // be issuing -- the final header line contains the credentials.
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      // After calling trans->RestartWithAuth(), this is the request we should
+      // be issuing -- the final header line contains the credentials.
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   // Respond with 5 kb of response body.
@@ -2290,21 +2300,23 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
-    // This simulates the seemingly successful write to a closed connection
-    // if the bug is not fixed.
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
+      // This simulates the seemingly successful write to a closed connection
+      // if the bug is not fixed.
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -2321,10 +2333,11 @@
   // After calling trans->RestartWithAuth(), this is the request we should
   // be issuing -- the final header line contains the credentials.
   MockWrite data_writes2[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -2376,7 +2389,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   // when the no authentication data flag is set.
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
 
@@ -2390,21 +2403,21 @@
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n\r\n"),
 
       // After calling trans->RestartWithAuth(), this is the request we should
       // be issuing -- the final header line contains the credentials.
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n"
           "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
 
       MockWrite(
           "GET / HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "Host: www.example.org\r\n"
           "Connection: keep-alive\r\n\r\n"),
   };
 
@@ -2494,7 +2507,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   // when the no authentication data flag is set.
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
 
@@ -2507,20 +2520,23 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    // After calling trans->RestartWithAuth(), this is the request we should
-    // be issuing -- the final header line contains the credentials.
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      // After calling trans->RestartWithAuth(), this is the request we should
+      // be issuing -- the final header line contains the credentials.
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
 
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   // The proxy responds to the connect with a 407, using a persistent
@@ -2611,7 +2627,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   // Ensure that proxy authentication is attempted even
   // when the no authentication data flag is set.
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
@@ -2628,15 +2644,15 @@
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n\r\n"),
 
       // After calling trans->RestartWithAuth(), this is the request we should
       // be issuing -- the final header line contains the credentials.
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n"
           "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   };
@@ -2718,7 +2734,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   // Ensure that proxy authentication is attempted even
   // when the no authentication data flag is set.
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
@@ -2734,16 +2750,18 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    // After calling trans->RestartWithAuth(), this is the request we should
-    // be issuing -- the final header line contains the credentials.
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+      // After calling trans->RestartWithAuth(), this is the request we should
+      // be issuing -- the final header line contains the credentials.
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   };
 
   // The proxy responds to the connect with a 407, using a persistent
@@ -2822,7 +2840,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against proxy server "myproxy:70".
@@ -2835,9 +2853,10 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   // The proxy responds to the connect with a 407.
@@ -2881,7 +2900,7 @@
 TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against proxy server "myproxy:70".
@@ -2895,8 +2914,8 @@
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes[] = {
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
@@ -2944,7 +2963,7 @@
 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // We are using a DIRECT connection (i.e. no proxy) for this session.
@@ -2953,9 +2972,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -2990,7 +3010,7 @@
        HttpsServerRequestsProxyAuthThroughProxy) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
 
   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   BoundTestNetLog log;
@@ -2999,13 +3019,15 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -3048,11 +3070,11 @@
 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/1");
+  request1.url = GURL("https://www.example.org/1");
 
   HttpRequestInfo request2;
   request2.method = "GET";
-  request2.url = GURL("https://www.google.com/2");
+  request2.url = GURL("https://www.example.org/2");
 
   // Configure against proxy server "myproxy:70".
   session_deps_.proxy_service.reset(
@@ -3063,17 +3085,20 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET /1 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET /1 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET /2 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET /2 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   // The proxy responds to the connect with a 407, using a persistent
@@ -3146,11 +3171,11 @@
 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/1");
+  request1.url = GURL("https://www.example.org/1");
 
   HttpRequestInfo request2;
   request2.method = "GET";
-  request2.url = GURL("https://www.google.com/2");
+  request2.url = GURL("https://www.example.org/2");
 
   // Configure against proxy server "myproxy:70".
   session_deps_.proxy_service.reset(
@@ -3161,17 +3186,20 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET /1 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET /1 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET /2 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET /2 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   // The proxy responds to the connect with a 407, using a persistent
@@ -3245,7 +3273,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   // Configure against https proxy server "proxy:70".
   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
@@ -3256,9 +3284,10 @@
 
   // Since we have proxy, should use full url
   MockWrite data_writes1[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -3306,7 +3335,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // Configure against https proxy server "proxy:70".
@@ -3316,7 +3345,7 @@
   session_deps_.net_log = log.bound().net_log();
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
-  // fetch http://www.google.com/ via SPDY
+  // fetch http://www.example.org/ via SPDY
   scoped_ptr<SpdyFrame> req(
       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
@@ -3371,7 +3400,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // Configure SPDY proxy server "proxy:70".
@@ -3381,7 +3410,7 @@
   session_deps_.net_log = log.bound().net_log();
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
-  // Fetch http://www.google.com/ through the SPDY proxy.
+  // Fetch http://www.example.org/ through the SPDY proxy.
   scoped_ptr<SpdyFrame> req(
       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   MockWrite spdy_writes[] = {CreateMockWrite(*req)};
@@ -3445,7 +3474,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // Configure against https proxy server "myproxy:70".
@@ -3548,7 +3577,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against https proxy server "proxy:70".
@@ -3561,14 +3590,15 @@
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
-  // CONNECT to www.google.com:443 via SPDY
+  // CONNECT to www.example.org:443 via SPDY
   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
-  // fetch https://www.google.com/ via HTTP
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
+  // fetch https://www.example.org/ via HTTP
 
-  const char get[] = "GET / HTTP/1.1\r\n"
-    "Host: www.google.com\r\n"
-    "Connection: keep-alive\r\n\r\n";
+  const char get[] =
+      "GET / HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
+      "Connection: keep-alive\r\n\r\n";
   scoped_ptr<SpdyFrame> wrapped_get(
       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
   scoped_ptr<SpdyFrame> conn_resp(
@@ -3635,7 +3665,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against https proxy server "proxy:70".
@@ -3648,11 +3678,11 @@
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
-  // CONNECT to www.google.com:443 via SPDY
+  // CONNECT to www.example.org:443 via SPDY
   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
-  // fetch https://www.google.com/ via SPDY
-  const char kMyUrl[] = "https://www.google.com/";
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
+  // fetch https://www.example.org/ via SPDY
+  const char kMyUrl[] = "https://www.example.org/";
   scoped_ptr<SpdyFrame> get(
       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
   scoped_ptr<SpdyFrame> wrapped_get(
@@ -3724,7 +3754,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against https proxy server "proxy:70".
@@ -3737,9 +3767,9 @@
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
-  // CONNECT to www.google.com:443 via SPDY
+  // CONNECT to www.example.org:443 via SPDY
   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   scoped_ptr<SpdyFrame> get(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
 
@@ -3792,23 +3822,24 @@
 
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/");
+  request1.url = GURL("https://www.example.org/");
   request1.load_flags = 0;
 
   HttpRequestInfo request2;
   request2.method = "GET";
-  request2.url = GURL("https://news.google.com/");
+  request2.url = GURL("https://mail.example.org/");
   request2.load_flags = 0;
 
-  // CONNECT to www.google.com:443 via SPDY.
+  // CONNECT to www.example.org:443 via SPDY.
   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   scoped_ptr<SpdyFrame> conn_resp1(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
-  // Fetch https://www.google.com/ via HTTP.
-  const char get1[] = "GET / HTTP/1.1\r\n"
-      "Host: www.google.com\r\n"
+  // Fetch https://www.example.org/ via HTTP.
+  const char get1[] =
+      "GET / HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
   scoped_ptr<SpdyFrame> wrapped_get1(
       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
@@ -3821,11 +3852,11 @@
   scoped_ptr<SpdyFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
 
-  // CONNECT to news.google.com:443 via SPDY.
+  // CONNECT to mail.example.org:443 via SPDY.
   SpdyHeaderBlock connect2_block;
   connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
-  connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
-  connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
+  connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
+  connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
   spdy_util_.MaybeAddVersionHeader(&connect2_block);
   scoped_ptr<SpdyFrame> connect2(
       spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
@@ -3833,9 +3864,10 @@
   scoped_ptr<SpdyFrame> conn_resp2(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
 
-  // Fetch https://news.google.com/ via HTTP.
-  const char get2[] = "GET / HTTP/1.1\r\n"
-      "Host: news.google.com\r\n"
+  // Fetch https://mail.example.org/ via HTTP.
+  const char get2[] =
+      "GET / HTTP/1.1\r\n"
+      "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
   scoped_ptr<SpdyFrame> wrapped_get2(
       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
@@ -3942,23 +3974,24 @@
 
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/");
+  request1.url = GURL("https://www.example.org/");
   request1.load_flags = 0;
 
   HttpRequestInfo request2;
   request2.method = "GET";
-  request2.url = GURL("https://www.google.com/2");
+  request2.url = GURL("https://www.example.org/2");
   request2.load_flags = 0;
 
-  // CONNECT to www.google.com:443 via SPDY.
+  // CONNECT to www.example.org:443 via SPDY.
   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   scoped_ptr<SpdyFrame> conn_resp1(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
-  // Fetch https://www.google.com/ via HTTP.
-  const char get1[] = "GET / HTTP/1.1\r\n"
-      "Host: www.google.com\r\n"
+  // Fetch https://www.example.org/ via HTTP.
+  const char get1[] =
+      "GET / HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
   scoped_ptr<SpdyFrame> wrapped_get1(
       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
@@ -3971,9 +4004,10 @@
   scoped_ptr<SpdyFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
 
-  // Fetch https://www.google.com/2 via HTTP.
-  const char get2[] = "GET /2 HTTP/1.1\r\n"
-      "Host: www.google.com\r\n"
+  // Fetch https://www.example.org/2 via HTTP.
+  const char get2[] =
+      "GET /2 HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
   scoped_ptr<SpdyFrame> wrapped_get2(
       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
@@ -4073,17 +4107,17 @@
 
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("http://www.google.com/");
+  request1.url = GURL("http://www.example.org/");
   request1.load_flags = 0;
 
   HttpRequestInfo request2;
   request2.method = "GET";
-  request2.url = GURL("http://news.google.com/");
+  request2.url = GURL("http://mail.example.org/");
   request2.load_flags = 0;
 
-  // http://www.google.com/
+  // http://www.example.org/
   scoped_ptr<SpdyHeaderBlock> headers(
-      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
+      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
   scoped_ptr<SpdyFrame> get1(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
   scoped_ptr<SpdyFrame> get_resp1(
@@ -4091,9 +4125,9 @@
   scoped_ptr<SpdyFrame> body1(
       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
 
-  // http://news.google.com/
+  // http://mail.example.org/
   scoped_ptr<SpdyHeaderBlock> headers2(
-      spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
+      spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
   scoped_ptr<SpdyFrame> get2(
       spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
   scoped_ptr<SpdyFrame> get_resp2(
@@ -4177,7 +4211,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   // when the no authentication data flag is set.
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
 
@@ -4190,16 +4224,18 @@
 
   // Since we have proxy, should use full url
   MockWrite data_writes1[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    // After calling trans->RestartWithAuth(), this is the request we should
-    // be issuing -- the final header line contains the credentials.
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      // After calling trans->RestartWithAuth(), this is the request we should
+      // be issuing -- the final header line contains the credentials.
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   // The proxy responds to the GET with a 407, using a persistent
@@ -4276,7 +4312,7 @@
     const MockRead& status, int expected_status) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against proxy server "myproxy:70".
@@ -4285,9 +4321,10 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -4493,7 +4530,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // Configure against proxy server "myproxy:70".
@@ -4504,9 +4541,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -4526,10 +4564,11 @@
   // request we should be issuing -- the final header line contains the
   // proxy's credentials.
   MockWrite data_writes2[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   // Now the proxy server lets the request pass through to origin server.
@@ -4547,11 +4586,12 @@
   // After calling trans->RestartWithAuth() the second time, we should send
   // the credentials for both the proxy and origin server.
   MockWrite data_writes3[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
-              "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
+          "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   };
 
   // Lastly we get the desired content.
@@ -4957,7 +4997,7 @@
 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -4996,7 +5036,7 @@
        DontRecycleTransportSocketForSSLTunnel) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Configure against proxy server "myproxy:70".
@@ -5009,9 +5049,10 @@
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   // The proxy responds to the connect with a 404, using a persistent
@@ -5055,7 +5096,7 @@
 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5111,13 +5152,14 @@
 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -5170,16 +5212,18 @@
 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -5265,10 +5309,11 @@
 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
-                     "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
-                     "e=17259,18167,19592,19773,19981,20133,20173,20233&"
-                     "rt=prt.2642,ol.2649,xjs.2951");
+  request.url = GURL(
+      "http://www.example.org/csi?v=3&s=web&action=&"
+      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
+      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
+      "rt=prt.2642,ol.2649,xjs.2951");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5412,7 +5457,7 @@
 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://foo:b@r@www.google.com/");
+  request.url = GURL("http://foo:b@r@www.example.org/");
   request.load_flags = LOAD_NORMAL;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5424,9 +5469,10 @@
   EXPECT_EQ("b%40r", request.url.password());
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -5439,10 +5485,11 @@
   // After the challenge above, the transaction will be restarted using the
   // identity from the url (foo, b@r) to answer the challenge.
   MockWrite data_writes2[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   };
 
   MockRead data_reads2[] = {
@@ -5492,7 +5539,7 @@
   request.method = "GET";
   // Note: the URL has a username:password in it.  The password "baz" is
   // wrong (should be "bar").
-  request.url = GURL("http://foo:baz@www.google.com/");
+  request.url = GURL("http://foo:baz@www.example.org/");
 
   request.load_flags = LOAD_NORMAL;
 
@@ -5501,9 +5548,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -5516,10 +5564,11 @@
   // After the challenge above, the transaction will be restarted using the
   // identity from the url (foo, baz) to answer the challenge.
   MockWrite data_writes2[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   };
 
   MockRead data_reads2[] = {
@@ -5532,10 +5581,11 @@
   // After the challenge above, the transaction will be restarted using the
   // identity supplied by the user (foo, bar) to answer the challenge.
   MockWrite data_writes3[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   MockRead data_reads3[] = {
@@ -5601,7 +5651,7 @@
 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://foo:bar@www.google.com/");
+  request.url = GURL("http://foo:bar@www.example.org/");
   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5609,9 +5659,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -5625,10 +5676,11 @@
   // identity supplied by the user, not the one in the URL, to answer the
   // challenge.
   MockWrite data_writes3[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   MockRead data_reads3[] = {
@@ -5682,16 +5734,17 @@
   {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/x/y/z");
+    request.url = GURL("http://www.example.org/x/y/z");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /x/y/z HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/z HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n\r\n"),
     };
 
     MockRead data_reads1[] = {
@@ -5703,10 +5756,11 @@
 
     // Resend with authorization (username=foo, password=bar)
     MockWrite data_writes2[] = {
-      MockWrite("GET /x/y/z HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/z HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
     };
 
     // Sever accepts the authorization.
@@ -5758,18 +5812,19 @@
     request.method = "GET";
     // Note that Transaction 1 was at /x/y/z, so this is in the same
     // protection space as MyRealm1.
-    request.url = GURL("http://www.google.com/x/y/a/b");
+    request.url = GURL("http://www.example.org/x/y/a/b");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                // Send preemptive authorization for MyRealm1
-                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/a/b HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            // Send preemptive authorization for MyRealm1
+            "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
     };
 
     // The server didn't like the preemptive authorization, and
@@ -5783,10 +5838,11 @@
 
     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
     MockWrite data_writes2[] = {
-      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/a/b HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
     };
 
     // Sever accepts the authorization.
@@ -5815,7 +5871,7 @@
     ASSERT_TRUE(response != NULL);
     ASSERT_TRUE(response->auth_challenge.get());
     EXPECT_FALSE(response->auth_challenge->is_proxy);
-    EXPECT_EQ("www.google.com:80",
+    EXPECT_EQ("www.example.org:80",
               response->auth_challenge->challenger.ToString());
     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
     EXPECT_EQ("basic", response->auth_challenge->scheme);
@@ -5842,19 +5898,20 @@
   {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/x/y/z2");
+    request.url = GURL("http://www.example.org/x/y/z2");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                // The authorization for MyRealm1 gets sent preemptively
-                // (since the url is in the same protection space)
-                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/z2 HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            // The authorization for MyRealm1 gets sent preemptively
+            // (since the url is in the same protection space)
+            "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
     };
 
     // Sever accepts the preemptive authorization
@@ -5890,16 +5947,17 @@
   {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/x/1");
+    request.url = GURL("http://www.example.org/x/1");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /x/1 HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n\r\n"),
+        MockWrite(
+            "GET /x/1 HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n\r\n"),
     };
 
     MockRead data_reads1[] = {
@@ -5911,10 +5969,11 @@
 
     // Resend with authorization from MyRealm's cache.
     MockWrite data_writes2[] = {
-      MockWrite("GET /x/1 HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+        MockWrite(
+            "GET /x/1 HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
     };
 
     // Sever accepts the authorization.
@@ -5960,16 +6019,17 @@
   {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/p/q/t");
+    request.url = GURL("http://www.example.org/p/q/t");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /p/q/t HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n\r\n"),
+        MockWrite(
+            "GET /p/q/t HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n\r\n"),
     };
 
     MockRead data_reads1[] = {
@@ -5981,10 +6041,11 @@
 
     // Resend with authorization from cache for MyRealm.
     MockWrite data_writes2[] = {
-      MockWrite("GET /p/q/t HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+        MockWrite(
+            "GET /p/q/t HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
     };
 
     // Sever rejects the authorization.
@@ -5998,10 +6059,11 @@
     // At this point we should prompt for new credentials for MyRealm.
     // Restart with username=foo3, password=foo4.
     MockWrite data_writes3[] = {
-      MockWrite("GET /p/q/t HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
+        MockWrite(
+            "GET /p/q/t HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
     };
 
     // Sever accepts the authorization.
@@ -6072,16 +6134,17 @@
   {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/x/y/z");
+    request.url = GURL("http://www.example.org/x/y/z");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /x/y/z HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/z HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n\r\n"),
     };
 
     MockRead data_reads1[] = {
@@ -6093,13 +6156,14 @@
 
     // Resend with authorization (username=foo, password=bar)
     MockWrite data_writes2[] = {
-      MockWrite("GET /x/y/z HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
-                "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
-                "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
-                "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/z HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Digest username=\"foo\", realm=\"digestive\", "
+            "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
+            "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
+            "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
     };
 
     // Sever accepts the authorization.
@@ -6151,20 +6215,21 @@
     request.method = "GET";
     // Note that Transaction 1 was at /x/y/z, so this is in the same
     // protection space as digest.
-    request.url = GURL("http://www.google.com/x/y/a/b");
+    request.url = GURL("http://www.example.org/x/y/a/b");
     request.load_flags = 0;
 
     scoped_ptr<HttpTransaction> trans(
         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
     MockWrite data_writes1[] = {
-      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
-                "Connection: keep-alive\r\n"
-                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
-                "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
-                "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
-                "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
+        MockWrite(
+            "GET /x/y/a/b HTTP/1.1\r\n"
+            "Host: www.example.org\r\n"
+            "Connection: keep-alive\r\n"
+            "Authorization: Digest username=\"foo\", realm=\"digestive\", "
+            "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
+            "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
+            "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
     };
 
     // Sever accepts the authorization.
@@ -6239,7 +6304,7 @@
 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -6247,9 +6312,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -6297,13 +6363,14 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite proxy_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead proxy_reads[] = {
@@ -6312,12 +6379,14 @@
   };
 
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -6379,16 +6448,18 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -6443,13 +6514,14 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -6517,11 +6589,11 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   scoped_ptr<SpdyFrame> goaway(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite data_writes[] = {
@@ -6580,13 +6652,14 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads[] = {
@@ -6626,11 +6699,11 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   scoped_ptr<SpdyFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite data_writes[] = {
@@ -6684,7 +6757,7 @@
 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   // when the no authentication data flag is set.
   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
 
@@ -6697,7 +6770,7 @@
 
   // Since we have proxy, should try to establish tunnel.
   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
-      NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   scoped_ptr<SpdyFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
 
@@ -6708,11 +6781,12 @@
   };
   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
-      HostPortPair("www.google.com", 443)));
-  // fetch https://www.google.com/ via HTTP
-  const char get[] = "GET / HTTP/1.1\r\n"
-    "Host: www.google.com\r\n"
-    "Connection: keep-alive\r\n\r\n";
+      HostPortPair("www.example.org", 443)));
+  // fetch https://www.example.org/ via HTTP
+  const char get[] =
+      "GET / HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
+      "Connection: keep-alive\r\n\r\n";
   scoped_ptr<SpdyFrame> wrapped_get(
       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
 
@@ -6825,7 +6899,7 @@
   HttpRequestInfo push_request;
 
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   push_request.method = "GET";
   push_request.url = GURL("http://www.another-origin.com/foo.dat");
 
@@ -6942,7 +7016,7 @@
   HttpRequestInfo request;
 
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   // Configure against https proxy server "myproxy:70".
   session_deps_.proxy_service.reset(
@@ -7028,14 +7102,15 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // Attempt to fetch the URL from a server with a bad cert
   MockWrite bad_cert_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead bad_cert_reads[] = {
@@ -7045,12 +7120,14 @@
 
   // Attempt to fetch the URL with a good cert
   MockWrite good_data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead good_cert_reads[] = {
@@ -7106,7 +7183,7 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
                                   "Chromium Ultra Awesome X Edition");
 
@@ -7115,10 +7192,11 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7145,7 +7223,7 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
                                   "Chromium Ultra Awesome X Edition");
 
@@ -7155,10 +7233,11 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   };
   MockRead data_reads[] = {
     // Return an error, so the transaction stops here (this test isn't
@@ -7184,7 +7263,7 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
                                   "http://the.previous.site.com/");
@@ -7194,10 +7273,11 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Referer: http://the.previous.site.com/\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Referer: http://the.previous.site.com/\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7224,17 +7304,18 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("POST / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Content-Length: 0\r\n\r\n"),
+      MockWrite(
+          "POST / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Content-Length: 0\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7261,17 +7342,18 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   HttpRequestInfo request;
   request.method = "PUT";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("PUT / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Content-Length: 0\r\n\r\n"),
+      MockWrite(
+          "PUT / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Content-Length: 0\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7298,17 +7380,18 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   HttpRequestInfo request;
   request.method = "HEAD";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("HEAD / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Content-Length: 0\r\n\r\n"),
+      MockWrite(
+          "HEAD / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Content-Length: 0\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7335,7 +7418,7 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = LOAD_BYPASS_CACHE;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -7343,11 +7426,12 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Pragma: no-cache\r\n"
-              "Cache-Control: no-cache\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Pragma: no-cache\r\n"
+          "Cache-Control: no-cache\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7375,7 +7459,7 @@
        BuildRequest_CacheControlValidateCache) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = LOAD_VALIDATE_CACHE;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -7383,10 +7467,11 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Cache-Control: max-age=0\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Cache-Control: max-age=0\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7413,7 +7498,7 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.extra_headers.SetHeader("FooHeader", "Bar");
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -7421,10 +7506,11 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "FooHeader: Bar\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "FooHeader: Bar\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7451,7 +7537,7 @@
 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.extra_headers.SetHeader("referer", "www.foo.com");
   request.extra_headers.SetHeader("hEllo", "Kitty");
   request.extra_headers.SetHeader("FoO", "bar");
@@ -7461,12 +7547,13 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "referer: www.foo.com\r\n"
-              "hEllo: Kitty\r\n"
-              "FoO: bar\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "referer: www.foo.com\r\n"
+          "hEllo: Kitty\r\n"
+          "FoO: bar\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -7493,7 +7580,7 @@
 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   session_deps_.proxy_service.reset(
@@ -7509,11 +7596,11 @@
   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
 
   MockWrite data_writes[] = {
-    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n")
-  };
+      MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n")};
 
   MockRead data_reads[] = {
     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
@@ -7552,7 +7639,7 @@
 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   session_deps_.proxy_service.reset(
@@ -7568,12 +7655,12 @@
   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
 
   MockWrite data_writes[] = {
-    MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
-              arraysize(write_buffer)),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n")
-  };
+      MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
+                arraysize(write_buffer)),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n")};
 
   MockRead data_reads[] = {
     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
@@ -7616,7 +7703,7 @@
 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   session_deps_.proxy_service.reset(
@@ -7632,11 +7719,11 @@
   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
 
   MockWrite data_writes[] = {
-    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n")
-  };
+      MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n")};
 
   MockRead data_reads[] = {
     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
@@ -7675,7 +7762,7 @@
 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   session_deps_.proxy_service.reset(
@@ -7690,25 +7777,24 @@
   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   const char kSOCKS5OkRequest[] = {
-    0x05,  // Version
-    0x01,  // Command (CONNECT)
-    0x00,  // Reserved.
-    0x03,  // Address type (DOMAINNAME).
-    0x0E,  // Length of domain (14)
-    // Domain string:
-    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
-    0x00, 0x50,  // 16-bit port (80)
+      0x05,  // Version
+      0x01,  // Command (CONNECT)
+      0x00,  // Reserved.
+      0x03,  // Address type (DOMAINNAME).
+      0x0F,  // Length of domain (15)
+      'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e',  // Domain string
+      '.', 'o', 'r', 'g', 0x00, 0x50,  // 16-bit port (80)
   };
   const char kSOCKS5OkResponse[] =
       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
 
   MockWrite data_writes[] = {
-    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
-    MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n")
-  };
+      MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
+      MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n")};
 
   MockRead data_reads[] = {
     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
@@ -7748,7 +7834,7 @@
 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   session_deps_.proxy_service.reset(
@@ -7763,27 +7849,26 @@
   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   const unsigned char kSOCKS5OkRequest[] = {
-    0x05,  // Version
-    0x01,  // Command (CONNECT)
-    0x00,  // Reserved.
-    0x03,  // Address type (DOMAINNAME).
-    0x0E,  // Length of domain (14)
-    // Domain string:
-    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
-    0x01, 0xBB,  // 16-bit port (443)
+      0x05,  // Version
+      0x01,  // Command (CONNECT)
+      0x00,  // Reserved.
+      0x03,  // Address type (DOMAINNAME).
+      0x0F,  // Length of domain (15)
+      'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e',  // Domain string
+      '.', 'o', 'r', 'g', 0x01, 0xBB,  // 16-bit port (443)
   };
 
   const char kSOCKS5OkResponse[] =
       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
 
   MockWrite data_writes[] = {
-    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
-    MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
-              arraysize(kSOCKS5OkRequest)),
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n")
-  };
+      MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
+      MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
+                arraysize(kSOCKS5OkRequest)),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n")};
 
   MockRead data_reads[] = {
     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
@@ -7870,38 +7955,38 @@
 
 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
   const GroupNameTest tests[] = {
-    {
-      "",  // unused
-      "http://www.google.com/direct",
-      "www.google.com:80",
-      false,
-    },
-    {
-      "",  // unused
-      "http://[2001:1418:13:1::25]/direct",
-      "[2001:1418:13:1::25]:80",
-      false,
-    },
+      {
+       "",  // unused
+       "http://www.example.org/direct",
+       "www.example.org:80",
+       false,
+      },
+      {
+       "",  // unused
+       "http://[2001:1418:13:1::25]/direct",
+       "[2001:1418:13:1::25]:80",
+       false,
+      },
 
-    // SSL Tests
-    {
-      "",  // unused
-      "https://www.google.com/direct_ssl",
-      "ssl/www.google.com:443",
-      true,
-    },
-    {
-      "",  // unused
-      "https://[2001:1418:13:1::25]/direct",
-      "ssl/[2001:1418:13:1::25]:443",
-      true,
-    },
-    {
-      "",  // unused
-      "http://host.with.alternate/direct",
-      "ssl/host.with.alternate:443",
-      true,
-    },
+      // SSL Tests
+      {
+       "",  // unused
+       "https://www.example.org/direct_ssl",
+       "ssl/www.example.org:443",
+       true,
+      },
+      {
+       "",  // unused
+       "https://[2001:1418:13:1::25]/direct",
+       "ssl/[2001:1418:13:1::25]:443",
+       true,
+      },
+      {
+       "",  // unused
+       "http://host.with.alternate/direct",
+       "ssl/host.with.alternate:443",
+       true,
+      },
   };
 
   session_deps_.use_alternate_protocols = true;
@@ -7937,34 +8022,34 @@
 
 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
   const GroupNameTest tests[] = {
-    {
-      "http_proxy",
-      "http://www.google.com/http_proxy_normal",
-      "www.google.com:80",
-      false,
-    },
+      {
+       "http_proxy",
+       "http://www.example.org/http_proxy_normal",
+       "www.example.org:80",
+       false,
+      },
 
-    // SSL Tests
-    {
-      "http_proxy",
-      "https://www.google.com/http_connect_ssl",
-      "ssl/www.google.com:443",
-      true,
-    },
+      // SSL Tests
+      {
+       "http_proxy",
+       "https://www.example.org/http_connect_ssl",
+       "ssl/www.example.org:443",
+       true,
+      },
 
-    {
-      "http_proxy",
-      "http://host.with.alternate/direct",
-      "ssl/host.with.alternate:443",
-      true,
-    },
+      {
+       "http_proxy",
+       "http://host.with.alternate/direct",
+       "ssl/host.with.alternate:443",
+       true,
+      },
 
-    {
-      "http_proxy",
-      "ftp://ftp.google.com/http_proxy_normal",
-      "ftp/ftp.google.com:21",
-      false,
-    },
+      {
+       "http_proxy",
+       "ftp://ftp.google.com/http_proxy_normal",
+       "ftp/ftp.google.com:21",
+       false,
+      },
   };
 
   session_deps_.use_alternate_protocols = true;
@@ -8002,39 +8087,39 @@
 
 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
   const GroupNameTest tests[] = {
-    {
-      "socks4://socks_proxy:1080",
-      "http://www.google.com/socks4_direct",
-      "socks4/www.google.com:80",
-      false,
-    },
-    {
-      "socks5://socks_proxy:1080",
-      "http://www.google.com/socks5_direct",
-      "socks5/www.google.com:80",
-      false,
-    },
+      {
+       "socks4://socks_proxy:1080",
+       "http://www.example.org/socks4_direct",
+       "socks4/www.example.org:80",
+       false,
+      },
+      {
+       "socks5://socks_proxy:1080",
+       "http://www.example.org/socks5_direct",
+       "socks5/www.example.org:80",
+       false,
+      },
 
-    // SSL Tests
-    {
-      "socks4://socks_proxy:1080",
-      "https://www.google.com/socks4_ssl",
-      "socks4/ssl/www.google.com:443",
-      true,
-    },
-    {
-      "socks5://socks_proxy:1080",
-      "https://www.google.com/socks5_ssl",
-      "socks5/ssl/www.google.com:443",
-      true,
-    },
+      // SSL Tests
+      {
+       "socks4://socks_proxy:1080",
+       "https://www.example.org/socks4_ssl",
+       "socks4/ssl/www.example.org:443",
+       true,
+      },
+      {
+       "socks5://socks_proxy:1080",
+       "https://www.example.org/socks5_ssl",
+       "socks5/ssl/www.example.org:443",
+       true,
+      },
 
-    {
-      "socks4://socks_proxy:1080",
-      "http://host.with.alternate/direct",
-      "socks4/ssl/host.with.alternate:443",
-      true,
-    },
+      {
+       "socks4://socks_proxy:1080",
+       "http://host.with.alternate/direct",
+       "socks4/ssl/host.with.alternate:443",
+       true,
+      },
   };
 
   session_deps_.use_alternate_protocols = true;
@@ -8076,7 +8161,7 @@
 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   session_deps_.proxy_service.reset(
       ProxyService::CreateFixed("myproxy:70;foobar:80"));
@@ -8106,7 +8191,7 @@
   HttpRequestInfo request;
   request.method = "GET";
   request.load_flags = load_flags;
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   // Select a host resolver that does caching.
   session_deps_.host_resolver.reset(new MockCachingHostResolver);
@@ -8115,16 +8200,12 @@
   scoped_ptr<HttpTransaction> trans(
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
-  // Warm up the host cache so it has an entry for "www.google.com".
+  // Warm up the host cache so it has an entry for "www.example.org".
   AddressList addrlist;
   TestCompletionCallback callback;
   int rv = session_deps_.host_resolver->Resolve(
-      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
-      DEFAULT_PRIORITY,
-      &addrlist,
-      callback.callback(),
-      NULL,
-      BoundNetLog());
+      HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
+      DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
   EXPECT_EQ(ERR_IO_PENDING, rv);
   rv = callback.WaitForResult();
   EXPECT_EQ(OK, rv);
@@ -8132,18 +8213,14 @@
   // Verify that it was added to host cache, by doing a subsequent async lookup
   // and confirming it completes synchronously.
   rv = session_deps_.host_resolver->Resolve(
-      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
-      DEFAULT_PRIORITY,
-      &addrlist,
-      callback.callback(),
-      NULL,
-      BoundNetLog());
+      HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
+      DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
   ASSERT_EQ(OK, rv);
 
-  // Inject a failure the next time that "www.google.com" is resolved. This way
+  // Inject a failure the next time that "www.example.org" is resolved. This way
   // we can tell if the next lookup hit the cache, or the "network".
   // (cache --> success, "network" --> failure).
-  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
+  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
 
   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
   // first read -- this won't be reached as the host resolution will fail first.
@@ -8157,7 +8234,7 @@
   rv = callback.WaitForResult();
 
   // If we bypassed the cache, we would have gotten a failure while resolving
-  // "www.google.com".
+  // "www.example.org".
   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
 }
 
@@ -8246,13 +8323,14 @@
 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -8271,10 +8349,11 @@
   // After calling trans->RestartWithAuth(), this is the request we should
   // be issuing -- the final header line contains the credentials.
   MockWrite data_writes2[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   };
 
   // Lastly, the server responds with the actual content.
@@ -8326,7 +8405,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockRead proxy_reads[] = {
@@ -8358,7 +8437,7 @@
 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -8409,7 +8488,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/upload");
+  request.url = GURL("http://www.example.org/upload");
   request.upload_data_stream = &upload_data_stream;
   request.load_flags = 0;
 
@@ -8466,7 +8545,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/upload");
+  request.url = GURL("http://www.example.org/upload");
   request.upload_data_stream = &upload_data_stream;
   request.load_flags = 0;
 
@@ -8524,7 +8603,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/upload");
+  request.url = GURL("http://www.example.org/upload");
   request.upload_data_stream = &upload_data_stream;
   request.load_flags = 0;
 
@@ -8553,16 +8632,17 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // First transaction will request a resource and receive a Basic challenge
   // with realm="first_realm".
   MockWrite data_writes1[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "\r\n"),
   };
   MockRead data_reads1[] = {
     MockRead("HTTP/1.1 401 Unauthorized\r\n"
@@ -8574,11 +8654,12 @@
   // for first_realm. The server will reject and provide a challenge with
   // second_realm.
   MockWrite data_writes2[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zmlyc3Q6YmF6\r\n"
-              "\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zmlyc3Q6YmF6\r\n"
+          "\r\n"),
   };
   MockRead data_reads2[] = {
     MockRead("HTTP/1.1 401 Unauthorized\r\n"
@@ -8589,11 +8670,12 @@
   // This again fails, and goes back to first_realm. Make sure that the
   // entry is removed from cache.
   MockWrite data_writes3[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
-              "\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
+          "\r\n"),
   };
   MockRead data_reads3[] = {
     MockRead("HTTP/1.1 401 Unauthorized\r\n"
@@ -8603,11 +8685,12 @@
 
   // Try one last time (with the correct password) and get the resource.
   MockWrite data_writes4[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "Authorization: Basic Zmlyc3Q6YmFy\r\n"
-              "\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "Authorization: Basic Zmlyc3Q6YmFy\r\n"
+          "\r\n"),
   };
   MockRead data_reads4[] = {
     MockRead("HTTP/1.1 200 OK\r\n"
@@ -8648,7 +8731,7 @@
   const AuthChallengeInfo* challenge = response->auth_challenge.get();
   ASSERT_FALSE(challenge == NULL);
   EXPECT_FALSE(challenge->is_proxy);
-  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
+  EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
   EXPECT_EQ("first_realm", challenge->realm);
   EXPECT_EQ("basic", challenge->scheme);
 
@@ -8666,7 +8749,7 @@
   challenge = response->auth_challenge.get();
   ASSERT_FALSE(challenge == NULL);
   EXPECT_FALSE(challenge->is_proxy);
-  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
+  EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
   EXPECT_EQ("second_realm", challenge->realm);
   EXPECT_EQ("basic", challenge->scheme);
 
@@ -8685,7 +8768,7 @@
   challenge = response->auth_challenge.get();
   ASSERT_FALSE(challenge == NULL);
   EXPECT_FALSE(challenge->is_proxy);
-  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
+  EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
   EXPECT_EQ("first_realm", challenge->realm);
   EXPECT_EQ("basic", challenge->scheme);
 
@@ -8717,7 +8800,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
@@ -8733,7 +8816,7 @@
   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   EXPECT_EQ(ERR_IO_PENDING, rv);
 
-  HostPortPair http_host_port_pair("www.google.com", 80);
+  HostPortPair http_host_port_pair("www.example.org", 80);
   HttpServerProperties& http_server_properties =
       *session->http_server_properties();
   AlternativeService alternative_service =
@@ -8773,7 +8856,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
@@ -8784,7 +8867,7 @@
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
-  HostPortPair http_host_port_pair("www.google.com", 80);
+  HostPortPair http_host_port_pair("www.example.org", 80);
   HttpServerProperties& http_server_properties =
       *session->http_server_properties();
   AlternativeService alternative_service(QUIC, "", 80);
@@ -8825,7 +8908,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
@@ -8850,7 +8933,7 @@
   // Port must be < 1024, or the header will be ignored (since initial port was
   // port 80 (another restricted port).
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       666); /* port is ignored by MockConnect anyway */
   http_server_properties->SetAlternativeService(host_port_pair,
                                                 alternative_service, 1.0);
@@ -8889,7 +8972,7 @@
 
   HttpRequestInfo restricted_port_request;
   restricted_port_request.method = "GET";
-  restricted_port_request.url = GURL("http://www.google.com:1023/");
+  restricted_port_request.url = GURL("http://www.example.org:1023/");
   restricted_port_request.load_flags = 0;
 
   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
@@ -8912,7 +8995,7 @@
       session->http_server_properties();
   const int kUnrestrictedAlternatePort = 1024;
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       kUnrestrictedAlternatePort);
   http_server_properties->SetAlternativeService(
       HostPortPair::FromURL(restricted_port_request.url), alternative_service,
@@ -8942,7 +9025,7 @@
 
   HttpRequestInfo restricted_port_request;
   restricted_port_request.method = "GET";
-  restricted_port_request.url = GURL("http://www.google.com:1023/");
+  restricted_port_request.url = GURL("http://www.example.org:1023/");
   restricted_port_request.load_flags = 0;
 
   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
@@ -8965,7 +9048,7 @@
       session->http_server_properties();
   const int kUnrestrictedAlternatePort = 1024;
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       kUnrestrictedAlternatePort);
   http_server_properties->SetAlternativeService(
       HostPortPair::FromURL(restricted_port_request.url), alternative_service,
@@ -8992,7 +9075,7 @@
 
   HttpRequestInfo restricted_port_request;
   restricted_port_request.method = "GET";
-  restricted_port_request.url = GURL("http://www.google.com:1023/");
+  restricted_port_request.url = GURL("http://www.example.org:1023/");
   restricted_port_request.load_flags = 0;
 
   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
@@ -9015,7 +9098,7 @@
       session->http_server_properties();
   const int kRestrictedAlternatePort = 80;
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       kRestrictedAlternatePort);
   http_server_properties->SetAlternativeService(
       HostPortPair::FromURL(restricted_port_request.url), alternative_service,
@@ -9043,7 +9126,7 @@
 
   HttpRequestInfo unrestricted_port_request;
   unrestricted_port_request.method = "GET";
-  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
+  unrestricted_port_request.url = GURL("http://www.example.org:1024/");
   unrestricted_port_request.load_flags = 0;
 
   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
@@ -9066,7 +9149,7 @@
       session->http_server_properties();
   const int kRestrictedAlternatePort = 80;
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       kRestrictedAlternatePort);
   http_server_properties->SetAlternativeService(
       HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
@@ -9093,7 +9176,7 @@
 
   HttpRequestInfo unrestricted_port_request;
   unrestricted_port_request.method = "GET";
-  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
+  unrestricted_port_request.url = GURL("http://www.example.org:1024/");
   unrestricted_port_request.load_flags = 0;
 
   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
@@ -9116,7 +9199,7 @@
       session->http_server_properties();
   const int kUnrestrictedAlternatePort = 1024;
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       kUnrestrictedAlternatePort);
   http_server_properties->SetAlternativeService(
       HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
@@ -9141,7 +9224,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   // The alternate protocol request will error out before we attempt to connect,
@@ -9161,7 +9244,7 @@
       session->http_server_properties();
   const int kUnsafePort = 7;
   AlternativeService alternative_service(
-      AlternateProtocolFromNextProto(GetParam()), "www.google.com",
+      AlternateProtocolFromNextProto(GetParam()), "www.example.org",
       kUnsafePort);
   http_server_properties->SetAlternativeService(
       HostPortPair::FromURL(request.url), alternative_service, 1.0);
@@ -9194,7 +9277,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   std::string alternate_protocol_http_header =
@@ -9214,6 +9297,8 @@
 
   SSLSocketDataProvider ssl(ASYNC, OK);
   ssl.SetNextProto(GetParam());
+  ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+  ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> req(
@@ -9284,7 +9369,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   std::string alternate_protocol_http_header =
@@ -9314,6 +9399,8 @@
 
   SSLSocketDataProvider ssl(ASYNC, OK);
   ssl.SetNextProto(GetParam());
+  ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+  ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> req1(
@@ -9401,7 +9488,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   std::string alternate_protocol_http_header =
@@ -9529,7 +9616,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   std::string alternate_protocol_http_header =
@@ -9549,15 +9636,18 @@
 
   SSLSocketDataProvider ssl(ASYNC, OK);
   ssl.SetNextProto(GetParam());
+  ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+  ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> req(
       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   MockWrite spdy_writes[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
-    CreateMockWrite(*req),                              // 3
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
+      CreateMockWrite(*req),                        // 3
   };
 
   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
@@ -9621,9 +9711,9 @@
   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   EXPECT_EQ("hello!", response_data);
   ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
-  EXPECT_EQ("http://www.google.com/",
+  EXPECT_EQ("http://www.example.org/",
             capturing_proxy_resolver.resolved()[0].spec());
-  EXPECT_EQ("https://www.google.com/",
+  EXPECT_EQ("https://www.example.org/",
             capturing_proxy_resolver.resolved()[1].spec());
 
   LoadTimingInfo load_timing_info;
@@ -9639,7 +9729,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   std::string alternate_protocol_http_header =
@@ -9658,6 +9748,8 @@
 
   SSLSocketDataProvider ssl(ASYNC, OK);
   ssl.SetNextProto(GetParam());
+  ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+  ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> req(
@@ -9699,7 +9791,7 @@
   EXPECT_EQ("hello world", response_data);
 
   // Set up an initial SpdySession in the pool to reuse.
-  HostPortPair host_port_pair("www.google.com", 443);
+  HostPortPair host_port_pair("www.example.org", 443);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   base::WeakPtr<SpdySession> spdy_session =
@@ -10329,13 +10421,14 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   std::string alternate_protocol_http_header =
@@ -10392,7 +10485,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   SSLSocketDataProvider ssl(ASYNC, OK);
@@ -10470,15 +10563,16 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com");
+  request.url = GURL("http://www.example.org");
   request.load_flags = 0;
 
   // First round goes unauthenticated through the proxy.
   MockWrite data_writes_1[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "\r\n"),
   };
   MockRead data_reads_1[] = {
     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
@@ -10492,10 +10586,10 @@
   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
                                   data_writes_1, arraysize(data_writes_1));
 
-  // Second round tries to tunnel to www.google.com due to the
+  // Second round tries to tunnel to www.example.org due to the
   // Alternate-Protocol announcement in the first round. It fails due
   // to a proxy authentication challenge.
-  // After the failure, a tunnel is established to www.google.com using
+  // After the failure, a tunnel is established to www.example.org using
   // Proxy-Authorization headers. There is then a SPDY request round.
   //
   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
@@ -10515,21 +10609,23 @@
   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockWrite data_writes_2[] = {
-    // First connection attempt without Proxy-Authorization.
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "\r\n"),
+      // First connection attempt without Proxy-Authorization.
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "\r\n"),
 
-    // Second connection attempt with Proxy-Authorization.
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n"
-              "Proxy-Authorization: auth_token\r\n"
-              "\r\n"),
+      // Second connection attempt with Proxy-Authorization.
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n"
+          "Proxy-Authorization: auth_token\r\n"
+          "\r\n"),
 
-    // SPDY request
-    CreateMockWrite(*req),
+      // SPDY request
+      CreateMockWrite(*req),
   };
   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
                                          "Proxy-Authenticate: Mock\r\n"
@@ -10557,6 +10653,8 @@
 
   SSLSocketDataProvider ssl(ASYNC, OK);
   ssl.SetNextProto(GetParam());
+  ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+  ASSERT_TRUE(ssl.cert.get());
 
   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
@@ -10600,7 +10698,7 @@
   // After all that work, these two lines (or actually, just the scheme) are
   // what this test is all about. Make sure it happens correctly.
   EXPECT_EQ("https", request_url.scheme());
-  EXPECT_EQ("www.google.com", request_url.host());
+  EXPECT_EQ("www.example.org", request_url.host());
 
   LoadTimingInfo load_timing_info;
   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
@@ -10625,7 +10723,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   session_deps_.host_resolver->set_synchronous_mode(true);
@@ -10672,7 +10770,7 @@
   {
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("http://www.google.com/");
+    request.url = GURL("http://www.example.org/");
     request.load_flags = 0;
 
     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
@@ -10707,12 +10805,13 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
 
   MockWrite data_writes1[] = {
-    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET http://www.example.org/ HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -10770,17 +10869,19 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -10845,17 +10946,19 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
 
   // Since we have proxy, should try to establish tunnel.
   MockWrite data_writes1[] = {
-    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Proxy-Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Proxy-Connection: keep-alive\r\n\r\n"),
 
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
 
   MockRead data_reads1[] = {
@@ -10894,7 +10997,7 @@
 // Test for crbug.com/55424.
 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
   scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
+      spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
 
   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -10918,7 +11021,7 @@
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   // Set up an initial SpdySession in the pool to reuse.
-  HostPortPair host_port_pair("www.google.com", 443);
+  HostPortPair host_port_pair("www.example.org", 443);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   base::WeakPtr<SpdySession> spdy_session =
@@ -10926,7 +11029,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
   // This is the important line that marks this as a preconnect.
@@ -11346,7 +11449,7 @@
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> host1_req(
-      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
+      spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
   scoped_ptr<SpdyFrame> host2_req(
       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   MockWrite spdy_writes[] = {
@@ -11382,7 +11485,7 @@
   TestCompletionCallback callback;
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/");
+  request1.url = GURL("https://www.example.org/");
   request1.load_flags = 0;
   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
 
@@ -11449,7 +11552,7 @@
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> host1_req(
-      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
+      spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
   scoped_ptr<SpdyFrame> host2_req(
       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   MockWrite spdy_writes[] = {
@@ -11485,7 +11588,7 @@
   TestCompletionCallback callback;
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/");
+  request1.url = GURL("https://www.example.org/");
   request1.load_flags = 0;
   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
 
@@ -11595,7 +11698,7 @@
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
   scoped_ptr<SpdyFrame> host1_req(
-      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
+      spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
   scoped_ptr<SpdyFrame> host2_req(
       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   MockWrite spdy_writes[] = {
@@ -11631,7 +11734,7 @@
   TestCompletionCallback callback;
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("https://www.google.com/");
+  request1.url = GURL("https://www.example.org/");
   request1.load_flags = 0;
   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
 
@@ -11684,8 +11787,8 @@
 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
 
 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
-  const std::string https_url = "https://www.google.com:8080/";
-  const std::string http_url = "http://www.google.com:8080/";
+  const std::string https_url = "https://www.example.org:8080/";
+  const std::string http_url = "http://www.example.org:8080/";
 
   // SPDY GET for HTTPS URL
   scoped_ptr<SpdyFrame> req1(
@@ -11713,7 +11816,7 @@
   MockWrite writes2[] = {
       MockWrite(ASYNC, 4,
                 "GET / HTTP/1.1\r\n"
-                "Host: www.google.com:8080\r\n"
+                "Host: www.example.org:8080\r\n"
                 "Connection: keep-alive\r\n\r\n"),
   };
 
@@ -11765,11 +11868,11 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
-  const std::string https_url = "https://www.google.com:8080/";
-  const std::string http_url = "http://www.google.com:8080/";
+  const std::string https_url = "https://www.example.org:8080/";
+  const std::string http_url = "http://www.example.org:8080/";
 
   // SPDY GET for HTTPS URL (through CONNECT tunnel)
-  const HostPortPair host_port_pair("www.google.com", 8080);
+  const HostPortPair host_port_pair("www.example.org", 8080);
   scoped_ptr<SpdyFrame> connect(
       spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
   scoped_ptr<SpdyFrame> req1(
@@ -11781,7 +11884,7 @@
   SpdyHeaderBlock req2_block;
   req2_block[spdy_util_.GetMethodKey()] = "GET";
   req2_block[spdy_util_.GetPathKey()] = "/";
-  req2_block[spdy_util_.GetHostKey()] = "www.google.com:8080";
+  req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
   req2_block[spdy_util_.GetSchemeKey()] = "http";
   spdy_util_.MaybeAddVersionHeader(&req2_block);
   scoped_ptr<SpdyFrame> req2(
@@ -11881,13 +11984,13 @@
 // the certificate does not match the new origin.
 // http://crbug.com/134690
 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
-  const std::string url1 = "http://www.google.com/";
-  const std::string url2 = "https://mail.google.com/";
+  const std::string url1 = "http://www.example.org/";
+  const std::string url2 = "https://news.example.org/";
   const std::string ip_addr = "1.2.3.4";
 
   // SPDY GET for HTTP URL (through SPDY proxy)
   scoped_ptr<SpdyHeaderBlock> headers(
-      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
+      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
   scoped_ptr<SpdyFrame> req1(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
 
@@ -11941,18 +12044,14 @@
   session_deps_.proxy_service.reset(new ProxyService(
       new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
 
+  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
+  ssl1.SetNextProto(GetParam());
   // Load a valid cert.  Note, that this does not need to
   // be valid for proxy because the MockSSLClientSocket does
   // not actually verify it.  But SpdySession will use this
   // to see if it is valid for the new origin
-  base::FilePath certs_dir = GetTestCertsDirectory();
-  scoped_refptr<X509Certificate> server_cert(
-      ImportCertFromFile(certs_dir, "ok_cert.pem"));
-  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
-
-  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
-  ssl1.SetNextProto(GetParam());
-  ssl1.cert = server_cert;
+  ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
+  ASSERT_TRUE(ssl1.cert.get());
   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
       data1.get());
@@ -11964,7 +12063,7 @@
       data2.get());
 
   session_deps_.host_resolver.reset(new MockCachingHostResolver());
-  session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
+  session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
 
   scoped_refptr<HttpNetworkSession> session(
@@ -12007,7 +12106,7 @@
 // session. Verify that new url's from the same HttpNetworkSession (and a new
 // SpdySession) do work. http://crbug.com/224701
 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
-  const std::string https_url = "https://www.google.com/";
+  const std::string https_url = "https://www.example.org/";
 
   MockRead reads1[] = {
     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
@@ -12249,7 +12348,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -12279,7 +12378,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -12309,7 +12408,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -12345,7 +12444,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -12381,7 +12480,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -12389,9 +12488,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
   MockRead data_reads[] = {
     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
@@ -12419,7 +12519,7 @@
 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
 
   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -12427,9 +12527,10 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
   MockRead data_reads[] = {
     MockRead(ASYNC, ERR_CONNECTION_RESET),
@@ -12457,7 +12558,7 @@
 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.load_flags = 0;
   request.extra_headers.SetHeader("X-Foo", "bar");
 
@@ -12466,10 +12567,11 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   MockWrite data_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n"
-              "X-Foo: bar\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n"
+          "X-Foo: bar\r\n\r\n"),
   };
   MockRead data_reads[] = {
     MockRead("HTTP/1.1 200 OK\r\n"
@@ -12929,7 +13031,8 @@
   // The same logic needs to be tested for both ws: and wss: schemes, but this
   // test is already parameterised on NextProto, so it uses a loop to verify
   // that the different schemes work.
-  std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
+  std::string test_cases[] = {"ws://www.example.org/",
+                              "wss://www.example.org/"};
   for (size_t i = 0; i < arraysize(test_cases); ++i) {
     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
     HttpNetworkSessionPeer peer(session);
@@ -12970,12 +13073,13 @@
 
   HttpRequestInfo ssl_request;
   ssl_request.method = "GET";
-  ssl_request.url = GURL("https://www.google.com/");
+  ssl_request.url = GURL("https://www.example.org/");
 
   MockWrite ssl_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
   MockRead ssl_reads[] = {
     MockRead("HTTP/1.1 200 OK\r\n"),
@@ -12994,12 +13098,13 @@
 
   HttpRequestInfo http_request;
   http_request.method = "GET";
-  http_request.url = GURL("http://www.google.com/");
+  http_request.url = GURL("http://www.example.org/");
 
   MockWrite http_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
   MockRead http_reads[] = {
     MockRead("HTTP/1.1 200 OK\r\n"),
@@ -13075,12 +13180,13 @@
 
   HttpRequestInfo http_request;
   http_request.method = "GET";
-  http_request.url = GURL("http://www.google.com/");
+  http_request.url = GURL("http://www.example.org/");
 
   MockWrite http_writes[] = {
-    MockWrite("GET / HTTP/1.1\r\n"
-              "Host: www.google.com\r\n"
-              "Connection: keep-alive\r\n\r\n"),
+      MockWrite(
+          "GET / HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
+          "Connection: keep-alive\r\n\r\n"),
   };
   MockRead http_reads[] = {
     MockRead("HTTP/1.1 200 OK\r\n"),
@@ -13610,7 +13716,7 @@
 TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("wss://www.google.com/");
+  request.url = GURL("wss://www.example.org/");
   AddWebSocketHeaders(&request.extra_headers);
 
   // Configure against proxy server "myproxy:70".
@@ -13622,24 +13728,24 @@
   // Since a proxy is configured, try to establish a tunnel.
   MockWrite data_writes[] = {
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n\r\n"),
 
       // After calling trans->RestartWithAuth(), this is the request we should
       // be issuing -- the final header line contains the credentials.
       MockWrite(
-          "CONNECT www.google.com:443 HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "CONNECT www.example.org:443 HTTP/1.1\r\n"
+          "Host: www.example.org\r\n"
           "Proxy-Connection: keep-alive\r\n"
           "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
 
       MockWrite(
           "GET / HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "Host: www.example.org\r\n"
           "Connection: Upgrade\r\n"
           "Upgrade: websocket\r\n"
-          "Origin: http://www.google.com\r\n"
+          "Origin: http://www.example.org\r\n"
           "Sec-WebSocket-Version: 13\r\n"
           "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
   };
@@ -13716,7 +13822,7 @@
 TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("ws://www.google.com/");
+  request.url = GURL("ws://www.example.org/");
   AddWebSocketHeaders(&request.extra_headers);
 
   // Configure against proxy server "myproxy:70".
@@ -13731,17 +13837,17 @@
       // they cannot and will not use the same TCP/IP connection as the
       // preflight HTTP request.
       MockWrite(
-          "CONNECT www.google.com:80 HTTP/1.1\r\n"
-          "Host: www.google.com:80\r\n"
+          "CONNECT www.example.org:80 HTTP/1.1\r\n"
+          "Host: www.example.org:80\r\n"
           "Proxy-Connection: keep-alive\r\n"
           "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
 
       MockWrite(
           "GET / HTTP/1.1\r\n"
-          "Host: www.google.com\r\n"
+          "Host: www.example.org\r\n"
           "Connection: Upgrade\r\n"
           "Upgrade: websocket\r\n"
-          "Origin: http://www.google.com\r\n"
+          "Origin: http://www.example.org\r\n"
           "Sec-WebSocket-Version: 13\r\n"
           "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
   };
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc
index f0b7cfb..eaeec0d 100644
--- a/net/http/http_request_headers.cc
+++ b/net/http/http_request_headers.cc
@@ -190,14 +190,14 @@
 
 base::Value* HttpRequestHeaders::NetLogCallback(
     const std::string* request_line,
-    NetLog::LogLevel log_level) const {
+    NetLogCaptureMode capture_mode) const {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("line", *request_line);
   base::ListValue* headers = new base::ListValue();
   for (HeaderVector::const_iterator it = headers_.begin();
        it != headers_.end(); ++it) {
-    std::string log_value = ElideHeaderValueForNetLog(
-        log_level, it->key, it->value);
+    std::string log_value =
+        ElideHeaderValueForNetLog(capture_mode, it->key, it->value);
     headers->Append(new base::StringValue(
         base::StringPrintf("%s: %s",
                            it->key.c_str(), log_value.c_str())));
diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h
index d8d52a09..d0666de 100644
--- a/net/http/http_request_headers.h
+++ b/net/http/http_request_headers.h
@@ -148,7 +148,7 @@
   // Takes in the request line and returns a Value for use with the NetLog
   // containing both the request line and all headers fields.
   base::Value* NetLogCallback(const std::string* request_line,
-                              NetLog::LogLevel log_level) const;
+                              NetLogCaptureMode capture_mode) const;
 
   // Takes in a Value created by the above function, and attempts to extract the
   // request line and create a copy of the original headers.  Returns true on
diff --git a/net/http/http_request_headers_unittest.cc b/net/http/http_request_headers_unittest.cc
index d33b4731..7c00c6ee 100644
--- a/net/http/http_request_headers_unittest.cc
+++ b/net/http/http_request_headers_unittest.cc
@@ -171,8 +171,8 @@
   headers.SetHeader("A", "a");
   std::string request_line("GET /stuff");
 
-  scoped_ptr<base::Value> event_param(
-      headers.NetLogCallback(&request_line, NetLog::LOG_ALL_BUT_BYTES));
+  scoped_ptr<base::Value> event_param(headers.NetLogCallback(
+      &request_line, NetLogCaptureMode::IncludeCookiesAndCredentials()));
   HttpRequestHeaders headers2;
   std::string request_line2;
 
diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc
index 3aef42a6..69a0aa8 100644
--- a/net/http/http_response_headers.cc
+++ b/net/http/http_response_headers.cc
@@ -1392,7 +1392,7 @@
 }
 
 base::Value* HttpResponseHeaders::NetLogCallback(
-    NetLog::LogLevel log_level) const {
+    NetLogCaptureMode capture_mode) const {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::ListValue* headers = new base::ListValue();
   headers->Append(new base::StringValue(GetStatusLine()));
@@ -1400,7 +1400,8 @@
   std::string name;
   std::string value;
   while (EnumerateHeaderLines(&iterator, &name, &value)) {
-    std::string log_value = ElideHeaderValueForNetLog(log_level, name, value);
+    std::string log_value =
+        ElideHeaderValueForNetLog(capture_mode, name, value);
     std::string escaped_name = EscapeNonASCII(name);
     std::string escaped_value = EscapeNonASCII(log_value);
     headers->Append(
diff --git a/net/http/http_response_headers.h b/net/http/http_response_headers.h
index a87a5f5..dd3d9cb 100644
--- a/net/http/http_response_headers.h
+++ b/net/http/http_response_headers.h
@@ -286,7 +286,7 @@
   bool IsChunkEncoded() const;
 
   // Creates a Value for use with the NetLog containing the response headers.
-  base::Value* NetLogCallback(NetLog::LogLevel log_level) const;
+  base::Value* NetLogCallback(NetLogCaptureMode capture_mode) const;
 
   // Takes in a Value created by the above function, and attempts to create a
   // copy of the original headers.  Returns true on success.  On failure,
diff --git a/net/http/http_response_headers_unittest.cc b/net/http/http_response_headers_unittest.cc
index 3557423..81bd5a3 100644
--- a/net/http/http_response_headers_unittest.cc
+++ b/net/http/http_response_headers_unittest.cc
@@ -2266,8 +2266,8 @@
   scoped_refptr<net::HttpResponseHeaders> parsed(
       new net::HttpResponseHeaders(headers));
 
-  scoped_ptr<base::Value> event_param(
-      parsed->NetLogCallback(net::NetLog::LOG_ALL_BUT_BYTES));
+  scoped_ptr<base::Value> event_param(parsed->NetLogCallback(
+      net::NetLogCaptureMode::IncludeCookiesAndCredentials()));
   scoped_refptr<net::HttpResponseHeaders> recreated;
 
   ASSERT_TRUE(net::HttpResponseHeaders::FromNetLogParam(event_param.get(),
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc
index fb548bc1..55dc7b8 100644
--- a/net/http/http_server_properties_manager_unittest.cc
+++ b/net/http/http_server_properties_manager_unittest.cc
@@ -40,15 +40,14 @@
     InitializeOnNetworkThread();
   }
 
-  virtual ~TestingHttpServerPropertiesManager() {}
+  ~TestingHttpServerPropertiesManager() override {}
 
   // Make these methods public for testing.
   using HttpServerPropertiesManager::ScheduleUpdateCacheOnPrefThread;
   using HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread;
 
   // Post tasks without a delay during tests.
-  virtual void StartPrefsUpdateTimerOnNetworkThread(
-      base::TimeDelta delay) override {
+  void StartPrefsUpdateTimerOnNetworkThread(base::TimeDelta delay) override {
     HttpServerPropertiesManager::StartPrefsUpdateTimerOnNetworkThread(
         base::TimeDelta());
   }
@@ -58,8 +57,7 @@
   }
 
   // Post tasks without a delay during tests.
-  virtual void StartCacheUpdateTimerOnPrefThread(
-      base::TimeDelta delay) override {
+  void StartCacheUpdateTimerOnPrefThread(base::TimeDelta delay) override {
     HttpServerPropertiesManager::StartCacheUpdateTimerOnPrefThread(
         base::TimeDelta());
   }
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index 4ce799e8..5843d4c 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -49,7 +49,7 @@
     const GURL* url,
     const AlternativeService* alternative_service,
     RequestPriority priority,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("original_url", original_url->GetOrigin().spec());
   dict->SetString("url", url->GetOrigin().spec());
@@ -63,7 +63,7 @@
 base::Value* NetLogHttpStreamProtoCallback(
     const SSLClientSocket::NextProtoStatus status,
     const std::string* proto,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
 
   dict->SetString("next_proto_status",
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index 3145408..1c0b982 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -320,51 +320,47 @@
     return last_num_streams_;
   }
 
-  virtual int RequestSocket(const std::string& group_name,
-                            const void* socket_params,
-                            RequestPriority priority,
-                            ClientSocketHandle* handle,
-                            const CompletionCallback& callback,
-                            const BoundNetLog& net_log) override {
+  int RequestSocket(const std::string& group_name,
+                    const void* socket_params,
+                    RequestPriority priority,
+                    ClientSocketHandle* handle,
+                    const CompletionCallback& callback,
+                    const BoundNetLog& net_log) override {
     ADD_FAILURE();
     return ERR_UNEXPECTED;
   }
 
-  virtual void RequestSockets(const std::string& group_name,
-                              const void* socket_params,
-                              int num_sockets,
-                              const BoundNetLog& net_log) override {
+  void RequestSockets(const std::string& group_name,
+                      const void* socket_params,
+                      int num_sockets,
+                      const BoundNetLog& net_log) override {
     last_num_streams_ = num_sockets;
   }
 
-  virtual void CancelRequest(const std::string& group_name,
-                             ClientSocketHandle* handle) override {
+  void CancelRequest(const std::string& group_name,
+                     ClientSocketHandle* handle) override {
     ADD_FAILURE();
   }
-  virtual void ReleaseSocket(const std::string& group_name,
-                             scoped_ptr<StreamSocket> socket,
-                             int id) override {
+  void ReleaseSocket(const std::string& group_name,
+                     scoped_ptr<StreamSocket> socket,
+                     int id) override {
     ADD_FAILURE();
   }
-  virtual void CloseIdleSockets() override {
-    ADD_FAILURE();
-  }
-  virtual int IdleSocketCount() const override {
+  void CloseIdleSockets() override { ADD_FAILURE(); }
+  int IdleSocketCount() const override {
     ADD_FAILURE();
     return 0;
   }
-  virtual int IdleSocketCountInGroup(
-      const std::string& group_name) const override {
+  int IdleSocketCountInGroup(const std::string& group_name) const override {
     ADD_FAILURE();
     return 0;
   }
-  virtual LoadState GetLoadState(
-      const std::string& group_name,
-      const ClientSocketHandle* handle) const override {
+  LoadState GetLoadState(const std::string& group_name,
+                         const ClientSocketHandle* handle) const override {
     ADD_FAILURE();
     return LOAD_STATE_IDLE;
   }
-  virtual base::TimeDelta ConnectionTimeout() const override {
+  base::TimeDelta ConnectionTimeout() const override {
     return base::TimeDelta();
   }
 
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index 5aeafa15..30a63015 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -74,10 +74,11 @@
   return false;
 }
 
-base::Value* NetLogSendRequestBodyCallback(uint64 length,
-                                           bool is_chunked,
-                                           bool did_merge,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* NetLogSendRequestBodyCallback(
+    uint64 length,
+    bool is_chunked,
+    bool did_merge,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("length", static_cast<int>(length));
   dict->SetBoolean("is_chunked", is_chunked);
diff --git a/net/log/net_log.cc b/net/log/net_log.cc
index 7f1d6e9..e112c2c 100644
--- a/net/log/net_log.cc
+++ b/net/log/net_log.cc
@@ -17,22 +17,23 @@
 
 namespace {
 
-// Returns parameters for logging data transferred events. Includes number of
-// bytes transferred and, if the log level indicates bytes should be logged and
-// |byte_count| > 0, the bytes themselves.  The bytes are hex-encoded, since
-// base::StringValue only supports UTF-8.
+// Returns parameters for logging data transferred events. At a minum includes
+// the number of bytes transferred. If the capture mode allows logging byte
+// contents and |byte_count| > 0, then will include the actual bytes. The
+// bytes are hex-encoded, since base::StringValue only supports UTF-8.
 base::Value* BytesTransferredCallback(int byte_count,
                                       const char* bytes,
-                                      NetLog::LogLevel log_level) {
+                                      NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("byte_count", byte_count);
-  if (NetLog::IsLoggingBytes(log_level) && byte_count > 0)
+  if (capture_mode.include_socket_bytes() && byte_count > 0)
     dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
   return dict;
 }
 
-base::Value* SourceEventParametersCallback(const NetLog::Source source,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* SourceEventParametersCallback(
+    const NetLog::Source source,
+    NetLogCaptureMode /* capture_mode */) {
   if (!source.IsValid())
     return NULL;
   base::DictionaryValue* event_params = new base::DictionaryValue();
@@ -42,7 +43,7 @@
 
 base::Value* NetLogIntegerCallback(const char* name,
                                    int value,
-                                   NetLog::LogLevel /* log_level */) {
+                                   NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* event_params = new base::DictionaryValue();
   event_params->SetInteger(name, value);
   return event_params;
@@ -50,7 +51,7 @@
 
 base::Value* NetLogInt64Callback(const char* name,
                                  int64 value,
-                                 NetLog::LogLevel /* log_level */) {
+                                 NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* event_params = new base::DictionaryValue();
   event_params->SetString(name, base::Int64ToString(value));
   return event_params;
@@ -58,7 +59,7 @@
 
 base::Value* NetLogStringCallback(const char* name,
                                   const std::string* value,
-                                  NetLog::LogLevel /* log_level */) {
+                                  NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* event_params = new base::DictionaryValue();
   event_params->SetString(name, *value);
   return event_params;
@@ -66,7 +67,7 @@
 
 base::Value* NetLogString16Callback(const char* name,
                                     const base::string16* value,
-                                    NetLog::LogLevel /* log_level */) {
+                                    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* event_params = new base::DictionaryValue();
   event_params->SetString(name, *value);
   return event_params;
@@ -137,7 +138,7 @@
 
   // Set the event-specific parameters.
   if (data_->parameters_callback) {
-    base::Value* value = data_->parameters_callback->Run(log_level_);
+    base::Value* value = data_->parameters_callback->Run(capture_mode_);
     if (value)
       entry_dict->Set("params", value);
   }
@@ -147,7 +148,7 @@
 
 base::Value* NetLog::Entry::ParametersToValue() const {
   if (data_->parameters_callback)
-    return data_->parameters_callback->Run(log_level_);
+    return data_->parameters_callback->Run(capture_mode_);
   return NULL;
 }
 
@@ -166,15 +167,14 @@
 NetLog::EntryData::~EntryData() {
 }
 
-NetLog::Entry::Entry(const EntryData* data, LogLevel log_level)
-    : data_(data), log_level_(log_level) {
+NetLog::Entry::Entry(const EntryData* data, NetLogCaptureMode capture_mode)
+    : data_(data), capture_mode_(capture_mode) {
 }
 
 NetLog::Entry::~Entry() {
 }
 
-NetLog::ThreadSafeObserver::ThreadSafeObserver()
-    : log_level_(LOG_NONE), net_log_(NULL) {
+NetLog::ThreadSafeObserver::ThreadSafeObserver() : net_log_(NULL) {
 }
 
 NetLog::ThreadSafeObserver::~ThreadSafeObserver() {
@@ -184,9 +184,9 @@
   DCHECK(!net_log_);
 }
 
-NetLog::LogLevel NetLog::ThreadSafeObserver::log_level() const {
+NetLogCaptureMode NetLog::ThreadSafeObserver::capture_mode() const {
   DCHECK(net_log_);
-  return log_level_;
+  return capture_mode_;
 }
 
 NetLog* NetLog::ThreadSafeObserver::net_log() const {
@@ -194,10 +194,13 @@
 }
 
 void NetLog::ThreadSafeObserver::OnAddEntryData(const EntryData& entry_data) {
-  OnAddEntry(Entry(&entry_data, log_level()));
+  OnAddEntry(Entry(&entry_data, capture_mode()));
 }
 
-NetLog::NetLog() : last_id_(0), effective_log_level_(LOG_NONE) {
+NetLog::NetLog()
+    : last_id_(0),
+      effective_capture_mode_int32_(
+          NetLogCaptureMode::None().ToInternalValue()) {
 }
 
 NetLog::~NetLog() {
@@ -219,35 +222,36 @@
   return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
 }
 
-NetLog::LogLevel NetLog::GetLogLevel() const {
-  base::subtle::Atomic32 log_level =
-      base::subtle::NoBarrier_Load(&effective_log_level_);
-  return static_cast<net::NetLog::LogLevel>(log_level);
+NetLogCaptureMode NetLog::GetCaptureMode() const {
+  base::subtle::Atomic32 capture_mode =
+      base::subtle::NoBarrier_Load(&effective_capture_mode_int32_);
+  return NetLogCaptureMode::FromInternalValue(capture_mode);
 }
 
 void NetLog::DeprecatedAddObserver(net::NetLog::ThreadSafeObserver* observer,
-                                   LogLevel log_level) {
-  DCHECK_NE(LOG_NONE, log_level);
+                                   NetLogCaptureMode capture_mode) {
+  DCHECK(capture_mode.enabled());
+
   base::AutoLock lock(lock_);
 
   DCHECK(!observer->net_log_);
-  DCHECK_EQ(LOG_NONE, observer->log_level_);
+  DCHECK(!observer->capture_mode_.enabled());
   observers_.AddObserver(observer);
   observer->net_log_ = this;
-  observer->log_level_ = log_level;
-  UpdateLogLevel();
+  observer->capture_mode_ = capture_mode;
+  UpdateCaptureMode();
 }
 
-void NetLog::SetObserverLogLevel(net::NetLog::ThreadSafeObserver* observer,
-                                 LogLevel log_level) {
-  DCHECK_NE(LOG_NONE, log_level);
+void NetLog::SetObserverCaptureMode(net::NetLog::ThreadSafeObserver* observer,
+                                    NetLogCaptureMode capture_mode) {
+  DCHECK(capture_mode.enabled());
   base::AutoLock lock(lock_);
 
   DCHECK(observers_.HasObserver(observer));
   DCHECK_EQ(this, observer->net_log_);
-  DCHECK_NE(LOG_NONE, observer->log_level_);
-  observer->log_level_ = log_level;
-  UpdateLogLevel();
+  DCHECK(observer->capture_mode_.enabled());
+  observer->capture_mode_ = capture_mode;
+  UpdateCaptureMode();
 }
 
 void NetLog::DeprecatedRemoveObserver(
@@ -256,26 +260,26 @@
 
   DCHECK(observers_.HasObserver(observer));
   DCHECK_EQ(this, observer->net_log_);
-  DCHECK_NE(LOG_NONE, observer->log_level_);
+  DCHECK(observer->capture_mode_.enabled());
   observers_.RemoveObserver(observer);
   observer->net_log_ = NULL;
-  observer->log_level_ = LOG_NONE;
-  UpdateLogLevel();
+  observer->capture_mode_ = NetLogCaptureMode();
+  UpdateCaptureMode();
 }
 
-void NetLog::UpdateLogLevel() {
+void NetLog::UpdateCaptureMode() {
   lock_.AssertAcquired();
 
-  // Look through all the observers and find the finest granularity
-  // log level (higher values of the enum imply *lower* log levels).
-  LogLevel new_effective_log_level = LOG_NONE;
+  // Accumulate the capture mode of all the observers to find the maximum level.
+  NetLogCaptureMode new_capture_mode = NetLogCaptureMode::None();
   ObserverListBase<ThreadSafeObserver>::Iterator it(&observers_);
   ThreadSafeObserver* observer;
   while ((observer = it.GetNext()) != NULL) {
-    new_effective_log_level =
-        std::min(new_effective_log_level, observer->log_level());
+    new_capture_mode =
+        NetLogCaptureMode::Max(new_capture_mode, observer->capture_mode());
   }
-  base::subtle::NoBarrier_Store(&effective_log_level_, new_effective_log_level);
+  base::subtle::NoBarrier_Store(&effective_capture_mode_int32_,
+                                new_capture_mode.ToInternalValue());
 }
 
 // static
@@ -345,16 +349,6 @@
 }
 
 // static
-bool NetLog::IsLoggingBytes(LogLevel log_level) {
-  return log_level == NetLog::LOG_ALL;
-}
-
-// static
-bool NetLog::IsLogging(LogLevel log_level) {
-  return log_level < NetLog::LOG_NONE;
-}
-
-// static
 NetLog::ParametersCallback NetLog::IntegerCallback(const char* name,
                                                    int value) {
   return base::Bind(&NetLogIntegerCallback, name, value);
@@ -384,7 +378,7 @@
                       const Source& source,
                       EventPhase phase,
                       const NetLog::ParametersCallback* parameters_callback) {
-  if (GetLogLevel() == LOG_NONE)
+  if (!GetCaptureMode().enabled())
     return;
   EntryData entry_data(type, source, phase, base::TimeTicks::Now(),
                        parameters_callback);
@@ -474,20 +468,12 @@
   AddEvent(event_type, base::Bind(BytesTransferredCallback, byte_count, bytes));
 }
 
-NetLog::LogLevel BoundNetLog::GetLogLevel() const {
+NetLogCaptureMode BoundNetLog::GetCaptureMode() const {
   CrashIfInvalid();
 
   if (net_log_)
-    return net_log_->GetLogLevel();
-  return NetLog::LOG_NONE;
-}
-
-bool BoundNetLog::IsLoggingBytes() const {
-  return NetLog::IsLoggingBytes(GetLogLevel());
-}
-
-bool BoundNetLog::IsLogging() const {
-  return NetLog::IsLogging(GetLogLevel());
+    return net_log_->GetCaptureMode();
+  return NetLogCaptureMode();
 }
 
 // static
diff --git a/net/log/net_log.h b/net/log/net_log.h
index dd22d5e..7d32e1c9 100644
--- a/net/log/net_log.h
+++ b/net/log/net_log.h
@@ -18,6 +18,7 @@
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "net/base/net_export.h"
+#include "net/log/net_log_capture_mode.h"
 
 namespace base {
 class DictionaryValue;
@@ -66,33 +67,11 @@
     SOURCE_COUNT
   };
 
-  // Specifies the granularity of events that should be emitted to the log.
-  //
-  // Since the LogLevel may be read and set on any thread without locking, it
-  // may be possible for an Observer to receive an event or parameters that
-  // normally wouldn't be logged at the currently active log level.
-  enum LogLevel {
-    // Log everything possible, even if it is slow and memory expensive.
-    // Includes logging of transferred bytes.
-    LOG_ALL,
-
-    // Log all events, but do not include the actual transferred bytes as
-    // parameters for bytes sent/received events.
-    LOG_ALL_BUT_BYTES,
-
-    // Log all events, but do not include the actual transferred bytes and
-    // remove cookies and HTTP credentials.
-    LOG_STRIP_PRIVATE_DATA,
-
-    // Don't log any events.
-    LOG_NONE,
-  };
-
   // A callback function that return a Value representation of the parameters
   // associated with an event.  If called, it will be called synchonously,
   // so it need not have owning references.  May be called more than once, or
   // not at all.  May return NULL.
-  typedef base::Callback<base::Value*(LogLevel)> ParametersCallback;
+  typedef base::Callback<base::Value*(NetLogCaptureMode)> ParametersCallback;
 
   // Identifies the entity that generated this log. The |id| field should
   // uniquely identify the source, and is used by log observers to infer
@@ -137,12 +116,12 @@
     const ParametersCallback* const parameters_callback;
   };
 
-  // An Entry pre-binds EntryData to a LogLevel, so observers will observe the
-  // output of ToValue() and ParametersToValue() at their log level rather than
-  // current maximum.
+  // An Entry pre-binds EntryData to a capture mode, so observers will observe
+  // the output of ToValue() and ParametersToValue() at their log capture mode
+  // rather than the current maximum.
   class NET_EXPORT Entry {
    public:
-    Entry(const EntryData* data, LogLevel log_level);
+    Entry(const EntryData* data, NetLogCaptureMode capture_mode);
     ~Entry();
 
     EventType type() const { return data_->type; }
@@ -161,8 +140,8 @@
    private:
     const EntryData* const data_;
 
-    // Log level when the event occurred.
-    const LogLevel log_level_;
+    // Log capture mode when the event occurred.
+    const NetLogCaptureMode capture_mode_;
 
     // It is not safe to copy this class, since |parameters_callback_| may
     // include pointers that become stale immediately after the event is added,
@@ -185,9 +164,9 @@
     // NetLog is destroyed.
     ThreadSafeObserver();
 
-    // Returns the minimum log level for events this observer wants to
+    // Returns the capture mode for events this observer wants to
     // receive.  Must not be called when not watching a NetLog.
-    LogLevel log_level() const;
+    NetLogCaptureMode capture_mode() const;
 
     // Returns the NetLog we are currently watching, if any.  Returns NULL
     // otherwise.
@@ -210,7 +189,7 @@
     void OnAddEntryData(const EntryData& entry_data);
 
     // Both of these values are only modified by the NetLog.
-    LogLevel log_level_;
+    NetLogCaptureMode capture_mode_;
     NetLog* net_log_;
 
     DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver);
@@ -228,11 +207,11 @@
   // will be unique and greater than 0.
   uint32 NextID();
 
-  // Returns the logging level for this NetLog. This is used to avoid computing
+  // Returns the capture mode for this NetLog. This is used to avoid computing
   // and saving expensive log entries.
-  LogLevel GetLogLevel() const;
+  NetLogCaptureMode GetCaptureMode() const;
 
-  // Adds an observer and sets its log level.  The observer must not be
+  // Adds an observer and sets its log capture mode.  The observer must not be
   // watching any NetLog, including this one, when this is called.
   //
   // NetLog implementations must call NetLog::OnAddObserver to update the
@@ -241,12 +220,14 @@
   // DEPRECATED: The ability to watch the netlog stream is being phased out
   // (crbug.com/472693) as it can be misused in production code. Please consult
   // with a net/log OWNER before introducing a new dependency on this.
-  void DeprecatedAddObserver(ThreadSafeObserver* observer, LogLevel log_level);
+  void DeprecatedAddObserver(ThreadSafeObserver* observer,
+                             NetLogCaptureMode capture_mode);
 
-  // Sets the log level of |observer| to |log_level|.  |observer| must be
-  // watching |this|.  NetLog implementations must call
-  // NetLog::OnSetObserverLogLevel to update the observer's internal state.
-  void SetObserverLogLevel(ThreadSafeObserver* observer, LogLevel log_level);
+  // Sets the log capture mode of |observer| to |capture_mode|.  |observer| must
+  // be watching |this|.  NetLog implementations must call
+  // NetLog::OnSetObserverCaptureMode to update the observer's internal state.
+  void SetObserverCaptureMode(ThreadSafeObserver* observer,
+                              NetLogCaptureMode capture_mode);
 
   // Removes an observer.  NetLog implementations must call
   // NetLog::OnAddObserver to update the observer's internal state.
@@ -280,14 +261,6 @@
   // Returns a C-String symbolic name for |event_phase|.
   static const char* EventPhaseToString(EventPhase event_phase);
 
-  // Returns true if |log_level| indicates the actual bytes transferred should
-  // be logged.  This is only the case when |log_level| is LOG_ALL.
-  static bool IsLoggingBytes(LogLevel log_level);
-
-  // Returns true if |log_level| indicates that events should be logged. This is
-  // the case when |log_level| is anything other than LOG_NONE.
-  static bool IsLogging(LogLevel log_level);
-
   // Creates a ParametersCallback that encapsulates a single integer.
   // Warning: |name| must remain valid for the life of the callback.
   // TODO(mmenke):  Rename this to be consistent with Int64Callback.
@@ -318,9 +291,9 @@
                 EventPhase phase,
                 const NetLog::ParametersCallback* parameters_callback);
 
-  // Called whenever an observer is added or removed, or has its log level
-  // changed.  Must have acquired |lock_| prior to calling.
-  void UpdateLogLevel();
+  // Called whenever an observer is added or removed, or has its log
+  // capture mode changed.  Must have acquired |lock_| prior to calling.
+  void UpdateCaptureMode();
 
   // |lock_| protects access to |observers_|.
   base::Lock lock_;
@@ -328,8 +301,10 @@
   // Last assigned source ID.  Incremented to get the next one.
   base::subtle::Atomic32 last_id_;
 
-  // The current log level.
-  base::subtle::Atomic32 effective_log_level_;
+  // The current capture mode. Note that the capture mode is stored as an
+  // integer rather than a NetLogCaptureMode so that it can be easily
+  // read/written without a lock using Atomic32.
+  base::subtle::Atomic32 effective_capture_mode_int32_;
 
   // |lock_| must be acquired whenever reading or writing to this.
   ObserverList<ThreadSafeObserver, true> observers_;
@@ -384,13 +359,7 @@
                             int byte_count,
                             const char* bytes) const;
 
-  NetLog::LogLevel GetLogLevel() const;
-
-  // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()).
-  bool IsLoggingBytes() const;
-
-  // Shortcut for NetLog::IsLogging(this->GetLogLevel()).
-  bool IsLogging() const;
+  NetLogCaptureMode GetCaptureMode() const;
 
   // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
   // of creating a unique source ID, and handles the case of NULL net_log.
diff --git a/net/log/net_log_capture_mode.cc b/net/log/net_log_capture_mode.cc
new file mode 100644
index 0000000..501911e0
--- /dev/null
+++ b/net/log/net_log_capture_mode.cc
@@ -0,0 +1,95 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/log/net_log_capture_mode.h"
+
+#include <algorithm>
+
+namespace net {
+
+namespace {
+
+// Integer representation for the capture mode. The numeric value is depended on
+// for method of NetLogCaptureMode, which expect that higher values imply more
+// capabilities.
+enum InternalValue {
+  // Don't log any events.
+  NONE,
+
+  // Log all events, but do not include the actual transferred bytes and
+  // remove cookies and HTTP credentials.
+  DEFAULT,
+
+  // Log all events, but do not include the actual transferred bytes as
+  // parameters for bytes sent/received events.
+  INCLUDE_COOKIES_AND_CREDENTIALS,
+
+  // Log everything possible, even if it is slow and memory expensive.
+  // Includes logging of transferred bytes.
+  INCLUDE_SOCKET_BYTES,
+};
+
+}  // namespace
+
+// Default constructor creates an empty capture mode.
+NetLogCaptureMode::NetLogCaptureMode() : NetLogCaptureMode(NONE) {
+}
+
+NetLogCaptureMode NetLogCaptureMode::None() {
+  return NetLogCaptureMode(NONE);
+}
+
+NetLogCaptureMode NetLogCaptureMode::Default() {
+  return NetLogCaptureMode(DEFAULT);
+}
+
+NetLogCaptureMode NetLogCaptureMode::IncludeCookiesAndCredentials() {
+  return NetLogCaptureMode(INCLUDE_COOKIES_AND_CREDENTIALS);
+}
+
+NetLogCaptureMode NetLogCaptureMode::IncludeSocketBytes() {
+  return NetLogCaptureMode(INCLUDE_SOCKET_BYTES);
+}
+
+NetLogCaptureMode NetLogCaptureMode::Max(NetLogCaptureMode mode1,
+                                         NetLogCaptureMode mode2) {
+  return NetLogCaptureMode(std::max(mode1.value_, mode2.value_));
+}
+
+bool NetLogCaptureMode::enabled() const {
+  return value_ != NONE;
+}
+
+bool NetLogCaptureMode::include_cookies_and_credentials() const {
+  return value_ >= INCLUDE_COOKIES_AND_CREDENTIALS;
+}
+
+bool NetLogCaptureMode::include_socket_bytes() const {
+  return value_ >= INCLUDE_SOCKET_BYTES;
+}
+
+bool NetLogCaptureMode::operator==(NetLogCaptureMode mode) const {
+  return value_ == mode.value_;
+}
+
+bool NetLogCaptureMode::operator!=(NetLogCaptureMode mode) const {
+  return !(*this == mode);
+}
+
+int32_t NetLogCaptureMode::ToInternalValueForTesting() const {
+  return ToInternalValue();
+}
+
+NetLogCaptureMode::NetLogCaptureMode(uint32_t value) : value_(value) {
+}
+
+NetLogCaptureMode NetLogCaptureMode::FromInternalValue(int32_t value) {
+  return NetLogCaptureMode(value);
+}
+
+int32_t NetLogCaptureMode::ToInternalValue() const {
+  return value_;
+}
+
+}  // namespace net
diff --git a/net/log/net_log_capture_mode.h b/net/log/net_log_capture_mode.h
new file mode 100644
index 0000000..e4f26a3
--- /dev/null
+++ b/net/log/net_log_capture_mode.h
@@ -0,0 +1,87 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_LOG_NET_LOG_CAPTURE_MODE_H_
+#define NET_LOG_NET_LOG_CAPTURE_MODE_H_
+
+#include <stdint.h>
+#include <string>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+// NetLogCaptureMode specifies the granularity of events that should be emitted
+// to the log. It is a simple wrapper around an integer, so it should be passed
+// to functions by value rather than by reference.
+class NET_EXPORT NetLogCaptureMode {
+ public:
+  // NOTE: Default assignment and copy constructor are OK.
+
+  // The default constructor creates an empty capture mode (equivalent to
+  // None()).
+  NetLogCaptureMode();
+
+  // Constructs a capture mode which logs NOTHING.
+  //    enabled() --> false
+  //    include_cookies_and_credentials() --> false
+  //    include_socket_bytes() --> false
+  static NetLogCaptureMode None();
+
+  // Constructs a capture mode which logs basic events and event parameters.
+  //    enabled() --> true
+  //    include_cookies_and_credentials() --> false
+  //    include_socket_bytes() --> false
+  static NetLogCaptureMode Default();
+
+  // Constructs a capture mode which logs basic events, and additionally makes
+  // no effort to strip cookies and credentials.
+  //    enabled() --> true
+  //    include_cookies_and_credentials() --> true
+  //    include_socket_bytes() --> false
+  static NetLogCaptureMode IncludeCookiesAndCredentials();
+
+  // Constructs a capture mode which logs the data sent/received from sockets.
+  //    enabled() --> true
+  //    include_cookies_and_credentials() --> true
+  //    include_socket_bytes() --> true
+  static NetLogCaptureMode IncludeSocketBytes();
+
+  // Returns a capture mode that contains the maximal set of capabilities
+  // between |mode1| and |mode2|.
+  static NetLogCaptureMode Max(NetLogCaptureMode mode1,
+                               NetLogCaptureMode mode2);
+
+  // If enabled() is true, then _something_ is being captured.
+  bool enabled() const;
+
+  // If include_cookies_and_credentials() is true , then it is OK to log
+  // events which contain cookies, credentials or other privacy sensitive data.
+  bool include_cookies_and_credentials() const;
+
+  // If include_socket_bytes() is true, then it is OK to output the actual
+  // bytes read/written from the network, even if it contains private data.
+  bool include_socket_bytes() const;
+
+  bool operator==(NetLogCaptureMode mode) const;
+  bool operator!=(NetLogCaptureMode mode) const;
+
+  int32_t ToInternalValueForTesting() const;
+
+ private:
+  // NetLog relies on the internal value of NetLogCaptureMode being an integer,
+  // so it can be read/written atomically across thread.
+  friend class NetLog;
+
+  explicit NetLogCaptureMode(uint32_t value);
+
+  static NetLogCaptureMode FromInternalValue(int32_t value);
+  int32_t ToInternalValue() const;
+
+  int32_t value_;
+};
+
+}  // namespace net
+
+#endif  // NET_LOG_NET_LOG_CAPTURE_MODE_H_
diff --git a/net/log/net_log_capture_mode_unittest.cc b/net/log/net_log_capture_mode_unittest.cc
new file mode 100644
index 0000000..b32beb9
--- /dev/null
+++ b/net/log/net_log_capture_mode_unittest.cc
@@ -0,0 +1,93 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/log/net_log_capture_mode.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(NetLogCaptureMode, None) {
+  NetLogCaptureMode mode = NetLogCaptureMode::None();
+
+  EXPECT_FALSE(mode.enabled());
+  EXPECT_FALSE(mode.include_cookies_and_credentials());
+  EXPECT_FALSE(mode.include_socket_bytes());
+
+  EXPECT_EQ(mode, NetLogCaptureMode::None());
+  EXPECT_NE(mode, NetLogCaptureMode::Default());
+  EXPECT_NE(mode, NetLogCaptureMode::IncludeCookiesAndCredentials());
+  EXPECT_NE(mode, NetLogCaptureMode::IncludeSocketBytes());
+  EXPECT_EQ(mode.ToInternalValueForTesting(),
+            NetLogCaptureMode::None().ToInternalValueForTesting());
+}
+
+TEST(NetLogCaptureMode, Default) {
+  NetLogCaptureMode mode = NetLogCaptureMode::Default();
+
+  EXPECT_TRUE(mode.enabled());
+  EXPECT_FALSE(mode.include_cookies_and_credentials());
+  EXPECT_FALSE(mode.include_socket_bytes());
+
+  EXPECT_NE(mode, NetLogCaptureMode::None());
+  EXPECT_EQ(mode, NetLogCaptureMode::Default());
+  EXPECT_NE(mode, NetLogCaptureMode::IncludeCookiesAndCredentials());
+  EXPECT_NE(mode, NetLogCaptureMode::IncludeSocketBytes());
+  EXPECT_EQ(mode.ToInternalValueForTesting(),
+            NetLogCaptureMode::Default().ToInternalValueForTesting());
+}
+
+TEST(NetLogCaptureMode, IncludeCookiesAndCredentials) {
+  NetLogCaptureMode mode = NetLogCaptureMode::IncludeCookiesAndCredentials();
+
+  EXPECT_TRUE(mode.enabled());
+  EXPECT_TRUE(mode.include_cookies_and_credentials());
+  EXPECT_FALSE(mode.include_socket_bytes());
+
+  EXPECT_NE(mode, NetLogCaptureMode::None());
+  EXPECT_NE(mode, NetLogCaptureMode::Default());
+  EXPECT_EQ(mode, NetLogCaptureMode::IncludeCookiesAndCredentials());
+  EXPECT_NE(mode, NetLogCaptureMode::IncludeSocketBytes());
+  EXPECT_EQ(mode.ToInternalValueForTesting(),
+            NetLogCaptureMode::IncludeCookiesAndCredentials()
+                .ToInternalValueForTesting());
+}
+
+TEST(NetLogCaptureMode, IncludeSocketBytes) {
+  NetLogCaptureMode mode = NetLogCaptureMode::IncludeSocketBytes();
+
+  EXPECT_TRUE(mode.enabled());
+  EXPECT_TRUE(mode.include_cookies_and_credentials());
+  EXPECT_TRUE(mode.include_socket_bytes());
+
+  EXPECT_NE(mode, NetLogCaptureMode::None());
+  EXPECT_NE(mode, NetLogCaptureMode::Default());
+  EXPECT_NE(mode, NetLogCaptureMode::IncludeCookiesAndCredentials());
+  EXPECT_EQ(mode, NetLogCaptureMode::IncludeSocketBytes());
+  EXPECT_EQ(
+      mode.ToInternalValueForTesting(),
+      NetLogCaptureMode::IncludeSocketBytes().ToInternalValueForTesting());
+}
+
+TEST(NetLogCaptureMode, Max) {
+  NetLogCaptureMode none = NetLogCaptureMode::None();
+  NetLogCaptureMode all = NetLogCaptureMode::IncludeSocketBytes();
+  NetLogCaptureMode cookies = NetLogCaptureMode::IncludeCookiesAndCredentials();
+  NetLogCaptureMode def = NetLogCaptureMode::Default();
+
+  EXPECT_EQ(all, NetLogCaptureMode::Max(none, all));
+  EXPECT_EQ(all, NetLogCaptureMode::Max(all, none));
+
+  EXPECT_EQ(cookies, NetLogCaptureMode::Max(def, cookies));
+  EXPECT_EQ(cookies, NetLogCaptureMode::Max(cookies, def));
+
+  EXPECT_EQ(all, NetLogCaptureMode::Max(def, all));
+  EXPECT_EQ(all, NetLogCaptureMode::Max(all, def));
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/net/log/net_log_unittest.cc b/net/log/net_log_unittest.cc
index 73e4e30..9fad152 100644
--- a/net/log/net_log_unittest.cc
+++ b/net/log/net_log_unittest.cc
@@ -18,9 +18,13 @@
 const int kThreads = 10;
 const int kEvents = 100;
 
-base::Value* NetLogLevelCallback(NetLog::LogLevel log_level) {
+base::Value* CaptureModeToValue(NetLogCaptureMode capture_mode) {
+  return new base::FundamentalValue(capture_mode.ToInternalValueForTesting());
+}
+
+base::Value* NetCaptureModeCallback(NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
-  dict->SetInteger("log_level", log_level);
+  dict->Set("capture_mode", CaptureModeToValue(capture_mode));
   return dict;
 }
 
@@ -42,16 +46,22 @@
   EXPECT_FALSE(entries[0].params);
 }
 
-// Check that the correct LogLevel is sent to NetLog Value callbacks.
-TEST(NetLogTest, LogLevels) {
+// Check that the correct CaptureMode is sent to NetLog Value callbacks.
+TEST(NetLogTest, CaptureModes) {
+  NetLogCaptureMode kModes[] = {
+      NetLogCaptureMode::Default(),
+      NetLogCaptureMode::IncludeCookiesAndCredentials(),
+      NetLogCaptureMode::IncludeSocketBytes(),
+  };
+
   TestNetLog net_log;
-  for (int log_level = NetLog::LOG_ALL; log_level < NetLog::LOG_NONE;
-       ++log_level) {
-    net_log.SetLogLevel(static_cast<NetLog::LogLevel>(log_level));
-    EXPECT_EQ(log_level, net_log.GetLogLevel());
+
+  for (NetLogCaptureMode mode : kModes) {
+    net_log.SetCaptureMode(mode);
+    EXPECT_EQ(mode, net_log.GetCaptureMode());
 
     net_log.AddGlobalEntry(NetLog::TYPE_SOCKET_ALIVE,
-                           base::Bind(NetLogLevelCallback));
+                           base::Bind(NetCaptureModeCallback));
 
     TestNetLog::CapturedEntryList entries;
     net_log.GetEntries(&entries);
@@ -63,9 +73,10 @@
     EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase);
     EXPECT_GE(base::TimeTicks::Now(), entries[0].time);
 
-    int logged_log_level;
-    ASSERT_TRUE(entries[0].GetIntegerValue("log_level", &logged_log_level));
-    EXPECT_EQ(log_level, logged_log_level);
+    int logged_capture_mode;
+    ASSERT_TRUE(
+        entries[0].GetIntegerValue("capture_mode", &logged_capture_mode));
+    EXPECT_EQ(mode.ToInternalValueForTesting(), logged_capture_mode);
 
     net_log.Clear();
   }
@@ -111,12 +122,9 @@
   ScopedVector<base::DictionaryValue> values_;
 };
 
-base::Value* LogLevelToValue(NetLog::LogLevel log_level) {
-  return new base::FundamentalValue(log_level);
-}
-
 void AddEvent(NetLog* net_log) {
-  net_log->AddGlobalEntry(NetLog::TYPE_CANCELLED, base::Bind(LogLevelToValue));
+  net_log->AddGlobalEntry(NetLog::TYPE_CANCELLED,
+                          base::Bind(CaptureModeToValue));
 }
 
 // A thread that waits until an event has been signalled before calling
@@ -180,15 +188,17 @@
     for (int i = 0; i < kEvents; ++i) {
       ASSERT_FALSE(observer_.net_log());
 
-      net_log_->DeprecatedAddObserver(&observer_, NetLog::LOG_ALL_BUT_BYTES);
+      net_log_->DeprecatedAddObserver(
+          &observer_, NetLogCaptureMode::IncludeCookiesAndCredentials());
       ASSERT_EQ(net_log_, observer_.net_log());
-      ASSERT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer_.log_level());
-      ASSERT_LE(net_log_->GetLogLevel(), NetLog::LOG_ALL_BUT_BYTES);
+      ASSERT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+                observer_.capture_mode());
 
-      net_log_->SetObserverLogLevel(&observer_, NetLog::LOG_ALL);
+      net_log_->SetObserverCaptureMode(&observer_,
+                                       NetLogCaptureMode::IncludeSocketBytes());
       ASSERT_EQ(net_log_, observer_.net_log());
-      ASSERT_EQ(NetLog::LOG_ALL, observer_.log_level());
-      ASSERT_LE(net_log_->GetLogLevel(), NetLog::LOG_ALL);
+      ASSERT_EQ(NetLogCaptureMode::IncludeSocketBytes(),
+                observer_.capture_mode());
 
       net_log_->DeprecatedRemoveObserver(&observer_);
       ASSERT_TRUE(!observer_.net_log());
@@ -225,8 +235,10 @@
   // Attach some observers.  Since they're created after |net_log|, they'll
   // safely detach themselves on destruction.
   CountingObserver observers[3];
-  for (size_t i = 0; i < arraysize(observers); ++i)
-    net_log.DeprecatedAddObserver(&observers[i], NetLog::LOG_ALL);
+  for (size_t i = 0; i < arraysize(observers); ++i) {
+    net_log.DeprecatedAddObserver(&observers[i],
+                                  NetLogCaptureMode::IncludeSocketBytes());
+  }
 
   // Run a bunch of threads to completion, each of which will emit events to
   // |net_log|.
@@ -246,22 +258,26 @@
   AddEvent(&net_log);
   EXPECT_EQ(0, observer.count());
   EXPECT_EQ(NULL, observer.net_log());
-  EXPECT_EQ(NetLog::LOG_NONE, net_log.GetLogLevel());
+  EXPECT_FALSE(net_log.GetCaptureMode().enabled());
 
   // Add the observer and add an event.
-  net_log.DeprecatedAddObserver(&observer, NetLog::LOG_ALL_BUT_BYTES);
+  net_log.DeprecatedAddObserver(
+      &observer, NetLogCaptureMode::IncludeCookiesAndCredentials());
   EXPECT_EQ(&net_log, observer.net_log());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer.log_level());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            observer.capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            net_log.GetCaptureMode());
 
   AddEvent(&net_log);
   EXPECT_EQ(1, observer.count());
 
   // Change the observer's logging level and add an event.
-  net_log.SetObserverLogLevel(&observer, NetLog::LOG_ALL);
+  net_log.SetObserverCaptureMode(&observer,
+                                 NetLogCaptureMode::IncludeSocketBytes());
   EXPECT_EQ(&net_log, observer.net_log());
-  EXPECT_EQ(NetLog::LOG_ALL, observer.log_level());
-  EXPECT_EQ(NetLog::LOG_ALL, net_log.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), observer.capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), net_log.GetCaptureMode());
 
   AddEvent(&net_log);
   EXPECT_EQ(2, observer.count());
@@ -269,16 +285,17 @@
   // Remove observer and add an event.
   net_log.DeprecatedRemoveObserver(&observer);
   EXPECT_EQ(NULL, observer.net_log());
-  EXPECT_EQ(NetLog::LOG_NONE, net_log.GetLogLevel());
+  EXPECT_FALSE(net_log.GetCaptureMode().enabled());
 
   AddEvent(&net_log);
   EXPECT_EQ(2, observer.count());
 
   // Add the observer a final time, and add an event.
-  net_log.DeprecatedAddObserver(&observer, NetLog::LOG_ALL);
+  net_log.DeprecatedAddObserver(&observer,
+                                NetLogCaptureMode::IncludeSocketBytes());
   EXPECT_EQ(&net_log, observer.net_log());
-  EXPECT_EQ(NetLog::LOG_ALL, observer.log_level());
-  EXPECT_EQ(NetLog::LOG_ALL, net_log.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), observer.capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), net_log.GetCaptureMode());
 
   AddEvent(&net_log);
   EXPECT_EQ(3, observer.count());
@@ -290,19 +307,25 @@
   LoggingObserver observer[2];
 
   // Add first observer.
-  net_log.DeprecatedAddObserver(&observer[0], NetLog::LOG_ALL_BUT_BYTES);
+  net_log.DeprecatedAddObserver(
+      &observer[0], NetLogCaptureMode::IncludeCookiesAndCredentials());
   EXPECT_EQ(&net_log, observer[0].net_log());
   EXPECT_EQ(NULL, observer[1].net_log());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            observer[0].capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            net_log.GetCaptureMode());
 
   // Add second observer observer.
-  net_log.DeprecatedAddObserver(&observer[1], NetLog::LOG_ALL);
+  net_log.DeprecatedAddObserver(&observer[1],
+                                NetLogCaptureMode::IncludeSocketBytes());
   EXPECT_EQ(&net_log, observer[0].net_log());
   EXPECT_EQ(&net_log, observer[1].net_log());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
-  EXPECT_EQ(NetLog::LOG_ALL, observer[1].log_level());
-  EXPECT_EQ(NetLog::LOG_ALL, net_log.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            observer[0].capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(),
+            observer[1].capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), net_log.GetCaptureMode());
 
   // Add event and make sure both observers receive it at their respective log
   // levels.
@@ -310,17 +333,19 @@
   AddEvent(&net_log);
   ASSERT_EQ(1U, observer[0].GetNumValues());
   ASSERT_TRUE(observer[0].GetValue(0)->GetInteger("params", &param));
-  EXPECT_EQ(observer[0].log_level(), param);
+  EXPECT_EQ(observer[0].capture_mode().ToInternalValueForTesting(), param);
   ASSERT_EQ(1U, observer[1].GetNumValues());
   ASSERT_TRUE(observer[1].GetValue(0)->GetInteger("params", &param));
-  EXPECT_EQ(observer[1].log_level(), param);
+  EXPECT_EQ(observer[1].capture_mode().ToInternalValueForTesting(), param);
 
   // Remove second observer.
   net_log.DeprecatedRemoveObserver(&observer[1]);
   EXPECT_EQ(&net_log, observer[0].net_log());
   EXPECT_EQ(NULL, observer[1].net_log());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            observer[0].capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            net_log.GetCaptureMode());
 
   // Add event and make sure only second observer gets it.
   AddEvent(&net_log);
@@ -331,7 +356,7 @@
   net_log.DeprecatedRemoveObserver(&observer[0]);
   EXPECT_EQ(NULL, observer[0].net_log());
   EXPECT_EQ(NULL, observer[1].net_log());
-  EXPECT_EQ(NetLog::LOG_NONE, net_log.GetLogLevel());
+  EXPECT_FALSE(net_log.GetCaptureMode().enabled());
 
   // Add event and make sure neither observer gets it.
   AddEvent(&net_log);
diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc
index 3ce6f624..d178a32 100644
--- a/net/log/net_log_util.cc
+++ b/net/log/net_log_util.cc
@@ -129,7 +129,7 @@
 // Returns a Value representing the state of a pre-existing URLRequest when
 // net-internals was opened.
 base::Value* GetRequestStateAsValue(const net::URLRequest* request,
-                                    net::NetLog::LogLevel log_level) {
+                                    net::NetLogCaptureMode capture_mode) {
   return request->GetStateAsValue();
 }
 
@@ -255,18 +255,10 @@
   // their symbolic names.
   constants_dict->Set("logSourceType", net::NetLog::GetSourceTypesAsValue());
 
-  // Information about the relationship between LogLevel enums and their
-  // symbolic names.
-  {
-    base::DictionaryValue* dict = new base::DictionaryValue();
-
-    dict->SetInteger("LOG_ALL", net::NetLog::LOG_ALL);
-    dict->SetInteger("LOG_ALL_BUT_BYTES", net::NetLog::LOG_ALL_BUT_BYTES);
-    dict->SetInteger("LOG_STRIP_PRIVATE_DATA",
-                     net::NetLog::LOG_STRIP_PRIVATE_DATA);
-
-    constants_dict->Set("logLevelType", dict);
-  }
+  // TODO(eroman): This is here for compatibility in loading new log files with
+  // older builds of Chrome. Safe to remove this once M45 is on the stable
+  // channel.
+  constants_dict->Set("logLevelType", new base::DictionaryValue());
 
   // Information about the relationship between address family enums and
   // their symbolic names.
@@ -538,7 +530,7 @@
     net::NetLog::EntryData entry_data(
         net::NetLog::TYPE_REQUEST_ALIVE, request->net_log().source(),
         net::NetLog::PHASE_BEGIN, request->creation_time(), &callback);
-    NetLog::Entry entry(&entry_data, request->net_log().GetLogLevel());
+    NetLog::Entry entry(&entry_data, request->net_log().GetCaptureMode());
     observer->OnAddEntry(entry);
   }
 }
diff --git a/net/log/test_net_log.cc b/net/log/test_net_log.cc
index 695eacc..d98ffc3a 100644
--- a/net/log/test_net_log.cc
+++ b/net/log/test_net_log.cc
@@ -7,15 +7,16 @@
 namespace net {
 
 TestNetLog::TestNetLog() {
-  DeprecatedAddObserver(&capturing_net_log_observer_, LOG_ALL_BUT_BYTES);
+  DeprecatedAddObserver(&capturing_net_log_observer_,
+                        NetLogCaptureMode::IncludeCookiesAndCredentials());
 }
 
 TestNetLog::~TestNetLog() {
   DeprecatedRemoveObserver(&capturing_net_log_observer_);
 }
 
-void TestNetLog::SetLogLevel(NetLog::LogLevel log_level) {
-  SetObserverLogLevel(&capturing_net_log_observer_, log_level);
+void TestNetLog::SetCaptureMode(NetLogCaptureMode capture_mode) {
+  SetObserverCaptureMode(&capturing_net_log_observer_, capture_mode);
 }
 
 void TestNetLog::GetEntries(TestNetLog::CapturedEntryList* entry_list) const {
@@ -62,8 +63,8 @@
   capturing_net_log_.Clear();
 }
 
-void BoundTestNetLog::SetLogLevel(NetLog::LogLevel log_level) {
-  capturing_net_log_.SetLogLevel(log_level);
+void BoundTestNetLog::SetCaptureMode(NetLogCaptureMode capture_mode) {
+  capturing_net_log_.SetCaptureMode(capture_mode);
 }
 
 }  // namespace net
diff --git a/net/log/test_net_log.h b/net/log/test_net_log.h
index 174f715..1526d827 100644
--- a/net/log/test_net_log.h
+++ b/net/log/test_net_log.h
@@ -28,7 +28,7 @@
   TestNetLog();
   ~TestNetLog() override;
 
-  void SetLogLevel(LogLevel log_level);
+  void SetCaptureMode(NetLogCaptureMode capture_mode);
 
   // Below methods are forwarded to capturing_net_log_observer_.
   void GetEntries(CapturedEntryList* entry_list) const;
@@ -67,8 +67,8 @@
 
   void Clear();
 
-  // Sets the log level of the underlying TestNetLog.
-  void SetLogLevel(NetLog::LogLevel log_level);
+  // Sets the capture mode of the underlying TestNetLog.
+  void SetCaptureMode(NetLogCaptureMode capture_mode);
 
  private:
   TestNetLog capturing_net_log_;
diff --git a/net/log/trace_net_log_observer.cc b/net/log/trace_net_log_observer.cc
index a283ea5..2ce8bc0 100644
--- a/net/log/trace_net_log_observer.cc
+++ b/net/log/trace_net_log_observer.cc
@@ -100,8 +100,7 @@
 }
 
 void TraceNetLogObserver::OnTraceLogEnabled() {
-  net_log_to_watch_->DeprecatedAddObserver(this,
-                                           NetLog::LOG_STRIP_PRIVATE_DATA);
+  net_log_to_watch_->DeprecatedAddObserver(this, NetLogCaptureMode::Default());
 }
 
 void TraceNetLogObserver::OnTraceLogDisabled() {
diff --git a/net/log/write_to_file_net_log_observer.cc b/net/log/write_to_file_net_log_observer.cc
index 668b866..9df765eb 100644
--- a/net/log/write_to_file_net_log_observer.cc
+++ b/net/log/write_to_file_net_log_observer.cc
@@ -18,15 +18,16 @@
 namespace net {
 
 WriteToFileNetLogObserver::WriteToFileNetLogObserver()
-    : log_level_(NetLog::LOG_STRIP_PRIVATE_DATA), added_events_(false) {
+    : capture_mode_(NetLogCaptureMode::Default()), added_events_(false) {
 }
 
 WriteToFileNetLogObserver::~WriteToFileNetLogObserver() {
 }
 
-void WriteToFileNetLogObserver::set_log_level(net::NetLog::LogLevel log_level) {
+void WriteToFileNetLogObserver::set_capture_mode(
+    net::NetLogCaptureMode capture_mode) {
   DCHECK(!net_log());
-  log_level_ = log_level;
+  capture_mode_ = capture_mode;
 }
 
 void WriteToFileNetLogObserver::StartObserving(
@@ -62,7 +63,7 @@
     CreateNetLogEntriesForActiveObjects(contexts, this);
   }
 
-  net_log->DeprecatedAddObserver(this, log_level_);
+  net_log->DeprecatedAddObserver(this, capture_mode_);
 }
 
 void WriteToFileNetLogObserver::StopObserving(
diff --git a/net/log/write_to_file_net_log_observer.h b/net/log/write_to_file_net_log_observer.h
index bd147e3..8ef0115 100644
--- a/net/log/write_to_file_net_log_observer.h
+++ b/net/log/write_to_file_net_log_observer.h
@@ -31,8 +31,8 @@
   WriteToFileNetLogObserver();
   ~WriteToFileNetLogObserver() override;
 
-  // Sets the log level to log at. Must be called before StartObserving.
-  void set_log_level(NetLog::LogLevel log_level);
+  // Sets the capture mode to log at. Must be called before StartObserving.
+  void set_capture_mode(NetLogCaptureMode capture_mode);
 
   // Starts observing |net_log| and writes output to |file|.  Must not already
   // be watching a NetLog.  Separate from constructor to enforce thread safety.
@@ -65,8 +65,8 @@
  private:
   base::ScopedFILE file_;
 
-  // The LogLevel to log at.
-  NetLog::LogLevel log_level_;
+  // The capture mode to log at.
+  NetLogCaptureMode capture_mode_;
 
   // True if OnAddEntry() has been called at least once.
   bool added_events_;
diff --git a/net/log/write_to_file_net_log_observer_unittest.cc b/net/log/write_to_file_net_log_observer_unittest.cc
index 4c12cf3d..4cabfe8c 100644
--- a/net/log/write_to_file_net_log_observer_unittest.cc
+++ b/net/log/write_to_file_net_log_observer_unittest.cc
@@ -61,21 +61,23 @@
   ASSERT_TRUE(dict->GetDictionary("constants", &constants));
 }
 
-TEST_F(WriteToFileNetLogObserverTest, LogLevel) {
+TEST_F(WriteToFileNetLogObserverTest, CaptureMode) {
   base::ScopedFILE file(base::OpenFile(log_path_, "w"));
   ASSERT_TRUE(file);
   WriteToFileNetLogObserver logger;
   logger.StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
-  EXPECT_EQ(NetLog::LOG_STRIP_PRIVATE_DATA, logger.log_level());
-  EXPECT_EQ(NetLog::LOG_STRIP_PRIVATE_DATA, net_log_.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::Default(), logger.capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::Default(), net_log_.GetCaptureMode());
   logger.StopObserving(nullptr);
 
   file.reset(base::OpenFile(log_path_, "w"));
   ASSERT_TRUE(file);
-  logger.set_log_level(NetLog::LOG_ALL_BUT_BYTES);
+  logger.set_capture_mode(NetLogCaptureMode::IncludeCookiesAndCredentials());
   logger.StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, logger.log_level());
-  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log_.GetLogLevel());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            logger.capture_mode());
+  EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
+            net_log_.GetCaptureMode());
   logger.StopObserving(nullptr);
 }
 
@@ -90,7 +92,7 @@
   NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE, source,
                                NetLog::PHASE_BEGIN, base::TimeTicks::Now(),
                                NULL);
-  NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
+  NetLog::Entry entry(&entry_data, NetLogCaptureMode::IncludeSocketBytes());
   logger->OnAddEntry(entry);
   logger->StopObserving(nullptr);
   logger.reset();
@@ -120,7 +122,7 @@
   NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE, source,
                                NetLog::PHASE_BEGIN, base::TimeTicks::Now(),
                                NULL);
-  NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
+  NetLog::Entry entry(&entry_data, NetLogCaptureMode::IncludeSocketBytes());
 
   // Add the entry multiple times.
   logger->OnAddEntry(entry);
diff --git a/net/net.gyp b/net/net.gyp
index 5e4ae19..2caae5a 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -103,6 +103,7 @@
       ],
     },
     {
+      # GN version: //net
       'target_name': 'net',
       'dependencies': [
         '../base/base.gyp:base_i18n',
@@ -120,6 +121,7 @@
       'includes': [ 'net_common.gypi' ],
     },
     {
+      # GN version: //net:net_unittests
       'target_name': 'net_unittests',
       'type': '<(gtest_target_type)',
       'dependencies': [
@@ -178,6 +180,9 @@
         }],
         [ 'use_nss_certs != 1', {
           'sources!': [
+            'cert/nss_cert_database_unittest.cc',
+            'cert/nss_cert_database_chromeos_unittest.cc',
+            'cert/nss_profile_filter_chromeos_unittest.cc',
             'ssl/client_cert_store_chromeos_unittest.cc',
             'ssl/client_cert_store_nss_unittest.cc',
           ],
@@ -187,7 +192,8 @@
           'dependencies': [
             '../third_party/boringssl/boringssl.gyp:boringssl',
           ],
-        }, {  # use_openssl == 0
+        }],
+        [ 'use_nss_certs == 1 or OS == "ios" or use_openssl == 0', {
           'conditions': [
             [ 'desktop_linux == 1 or chromeos == 1', {
               'dependencies': [
@@ -199,9 +205,6 @@
                 '../third_party/nss/nss.gyp:nss',
                 'third_party/nss/ssl.gyp:libssl',
               ],
-              'sources!': [
-                'cert/nss_cert_database_unittest.cc',
-              ],
             }],
           ],
         }],
@@ -239,9 +242,6 @@
             # TODO(bulach): Add equivalent tests when the underlying
             #               functionality is ported to OpenSSL.
             'sources!': [
-              'cert/nss_cert_database_chromeos_unittest.cc',
-              'cert/nss_cert_database_unittest.cc',
-              'cert/nss_profile_filter_chromeos_unittest.cc',
               'cert/x509_util_nss_unittest.cc',
               'quic/test_tools/crypto_test_utils_nss.cc',
             ],
@@ -741,7 +741,7 @@
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [4267, ],
     },
-    {
+    { # GN version: //net:balsa
       'target_name': 'balsa',
       'type': 'static_library',
       'dependencies': [
diff --git a/net/net.gypi b/net/net.gypi
index a122009f..e481231 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -93,6 +93,14 @@
       'cert/x509_util.h',
       'cert/x509_util_openssl.cc',
       'cert/x509_util_openssl.h',
+      'der/input.cc',
+      'der/input.h',
+      'der/parse_values.cc',
+      'der/parse_values.h',
+      'der/parser.cc',
+      'der/parser.h',
+      'der/tag.cc',
+      'der/tag.h',
       'http/http_auth_challenge_tokenizer.cc',
       'http/http_auth_challenge_tokenizer.h',
       'http/http_byte_range.cc',
@@ -116,6 +124,8 @@
       'http/transport_security_state.h',
       'log/net_log.cc',
       'log/net_log.h',
+      'log/net_log_capture_mode.cc',
+      'log/net_log_capture_mode.h',
       'log/net_log_event_type_list.h',
       'log/net_log_source_type_list.h',
       'socket/client_socket_handle.cc',
@@ -140,6 +150,7 @@
       'ssl/openssl_client_key_store.h',
       'ssl/openssl_platform_key.h',
       'ssl/openssl_platform_key_mac.cc',
+      'ssl/openssl_platform_key_nss.cc',
       'ssl/openssl_platform_key_win.cc',
       'ssl/openssl_ssl_util.cc',
       'ssl/openssl_ssl_util.h',
@@ -378,6 +389,7 @@
       'cert/x509_util_mac.h',
       'cert/x509_util_nss.cc',
       'cert/x509_util_nss.h',
+      'cert/x509_util_nss_certs.cc',
       'cert_net/cert_net_fetcher_impl.cc',
       'cert_net/cert_net_fetcher_impl.h',
       'cookies/canonical_cookie.cc',
@@ -1328,6 +1340,9 @@
       'cookies/cookie_store_unittest.h',
       'cookies/cookie_util_unittest.cc',
       'cookies/parsed_cookie_unittest.cc',
+      'der/input_unittest.cc',
+      'der/parser_unittest.cc',
+      'der/parse_values_unittest.cc',
       'disk_cache/backend_unittest.cc',
       'disk_cache/blockfile/addr_unittest.cc',
       'disk_cache/blockfile/bitmap_unittest.cc',
@@ -1434,8 +1449,9 @@
       'http/transport_security_persister_unittest.cc',
       'http/transport_security_state_unittest.cc',
       'http/url_security_manager_unittest.cc',
-      'log/write_to_file_net_log_observer_unittest.cc',
+      'log/net_log_capture_mode_unittest.cc',
       'log/net_log_unittest.cc',
+      'log/write_to_file_net_log_observer_unittest.cc',
       'log/net_log_unittest.h',
       'log/net_log_util_unittest.cc',
       'log/trace_net_log_observer_unittest.cc',
@@ -1604,6 +1620,7 @@
       'socket/deterministic_socket_data_unittest.cc',
       'socket/mock_client_socket_pool_manager.cc',
       'socket/mock_client_socket_pool_manager.h',
+      'socket/sequenced_socket_data_unittest.cc',
       'socket/socks5_client_socket_unittest.cc',
       'socket/socks_client_socket_pool_unittest.cc',
       'socket/socks_client_socket_unittest.cc',
diff --git a/net/net_common.gypi b/net/net_common.gypi
index 4bb8235..77134f5 100644
--- a/net/net_common.gypi
+++ b/net/net_common.gypi
@@ -125,30 +125,14 @@
     }],
     ['use_openssl==1', {
         'sources!': [
-          'base/crypto_module_nss.cc',
-          'base/keygen_handler_nss.cc',
           'base/nss_memio.c',
           'base/nss_memio.h',
-          'cert/cert_database_nss.cc',
-          'cert/cert_verify_proc_nss.cc',
-          'cert/cert_verify_proc_nss.h',
           'cert/ct_log_verifier_nss.cc',
           'cert/ct_objects_extractor_nss.cc',
           'cert/jwk_serializer_nss.cc',
-          'cert/nss_cert_database.cc',
-          'cert/nss_cert_database.h',
-          'cert/nss_cert_database_chromeos.cc',
-          'cert/nss_cert_database_chromeos.h',
-          'cert/nss_profile_filter_chromeos.cc',
-          'cert/nss_profile_filter_chromeos.h',
           'cert/scoped_nss_types.h',
           'cert/sha256_legacy_support_nss_win.cc',
-          'cert/test_root_certs_nss.cc',
-          'cert/x509_certificate_nss.cc',
           'cert/x509_util_nss.cc',
-          'cert/x509_util_nss.h',
-          'cert_net/nss_ocsp.cc',
-          'cert_net/nss_ocsp.h',
           'quic/crypto/aead_base_decrypter_nss.cc',
           'quic/crypto/aead_base_encrypter_nss.cc',
           'quic/crypto/aes_128_gcm_12_decrypter_nss.cc',
@@ -163,12 +147,6 @@
           'socket/ssl_client_socket_nss.h',
           'socket/ssl_server_socket_nss.cc',
           'socket/ssl_server_socket_nss.h',
-          'third_party/mozilla_security_manager/nsKeygenHandler.cpp',
-          'third_party/mozilla_security_manager/nsKeygenHandler.h',
-          'third_party/mozilla_security_manager/nsNSSCertificateDB.cpp',
-          'third_party/mozilla_security_manager/nsNSSCertificateDB.h',
-          'third_party/mozilla_security_manager/nsPKCS12Blob.cpp',
-          'third_party/mozilla_security_manager/nsPKCS12Blob.h',
         ],
         'dependencies': [
           '../third_party/boringssl/boringssl.gyp:boringssl',
@@ -176,7 +154,6 @@
       },
       {  # else !use_openssl: remove the unneeded files and depend on NSS.
         'sources!': [
-          'base/crypto_module_openssl.cc',
           'cert/ct_log_verifier_openssl.cc',
           'cert/ct_objects_extractor_openssl.cc',
           'cert/jwk_serializer_openssl.cc',
@@ -199,12 +176,16 @@
           'socket/ssl_server_socket_openssl.h',
           'ssl/openssl_platform_key.h',
           'ssl/openssl_platform_key_mac.cc',
+          'ssl/openssl_platform_key_nss.cc',
           'ssl/openssl_platform_key_win.cc',
           'ssl/openssl_ssl_util.cc',
           'ssl/openssl_ssl_util.h',
           'ssl/ssl_client_session_cache_openssl.cc',
           'ssl/ssl_client_session_cache_openssl.h',
         ],
+      },
+    ],
+    [ 'use_nss_certs == 1 or OS == "ios" or use_openssl == 0', {
         'conditions': [
           # Pull in the bundled or system NSS as appropriate.
           [ 'desktop_linux == 1 or chromeos == 1', {
@@ -219,10 +200,15 @@
             ],
           }]
         ],
+      }, {
+        'sources!': [
+          'cert/x509_util_nss.h',
+        ],
       },
     ],
     [ 'use_openssl_certs == 0', {
         'sources!': [
+          'base/crypto_module_openssl.cc',
           'base/keygen_handler_openssl.cc',
           'base/openssl_private_key_store.h',
           'base/openssl_private_key_store_android.cc',
@@ -264,17 +250,30 @@
           }],
         ],
       },
-      {  # else: OS is not in the above list
+    ],
+    [ 'use_nss_certs != 1', {
         'sources!': [
           'base/crypto_module_nss.cc',
           'base/keygen_handler_nss.cc',
           'cert/cert_database_nss.cc',
+          'cert/cert_verify_proc_nss.cc',
+          'cert/cert_verify_proc_nss.h',
           'cert/nss_cert_database.cc',
           'cert/nss_cert_database.h',
+          'cert/nss_cert_database_chromeos.cc',
+          'cert/nss_cert_database_chromeos.h',
+          'cert/nss_profile_filter_chromeos.cc',
+          'cert/nss_profile_filter_chromeos.h',
           'cert/test_root_certs_nss.cc',
           'cert/x509_certificate_nss.cc',
+          'cert/x509_util_nss_certs.cc',
           'cert_net/nss_ocsp.cc',
           'cert_net/nss_ocsp.h',
+          'ssl/client_cert_store_chromeos.cc',
+          'ssl/client_cert_store_chromeos.h',
+          'ssl/client_cert_store_nss.cc',
+          'ssl/client_cert_store_nss.h',
+          'ssl/openssl_platform_key_nss.cc',
           'third_party/mozilla_security_manager/nsKeygenHandler.cpp',
           'third_party/mozilla_security_manager/nsKeygenHandler.h',
           'third_party/mozilla_security_manager/nsNSSCertificateDB.cpp',
@@ -284,14 +283,12 @@
         ],
       },
     ],
-    [ 'use_nss_certs != 1', {
-        'sources!': [
-          'cert/cert_verify_proc_nss.cc',
-          'cert/cert_verify_proc_nss.h',
-          'ssl/client_cert_store_chromeos.cc',
-          'ssl/client_cert_store_chromeos.h',
-          'ssl/client_cert_store_nss.cc',
-          'ssl/client_cert_store_nss.h',
+    # client_cert_store_nss.c requires NSS_CmpCertChainWCANames from NSS's
+    # libssl, but our bundled copy is not built in OpenSSL ports. Pull that
+    # file in directly.
+    [ 'use_nss_certs == 1 and use_openssl == 1', {
+        'sources': [
+          'third_party/nss/ssl/cmpcert.c',
         ],
     }],
     [ 'enable_websockets != 1', {
@@ -416,8 +413,7 @@
         ['include', '^cert/cert_verify_proc_nss\\.cc$'],
         ['include', '^cert/cert_verify_proc_nss\\.h$'],
         ['include', '^cert/test_root_certs_nss\\.cc$'],
-        ['include', '^cert/x509_util_nss\\.cc$'],
-        ['include', '^cert/x509_util_nss\\.h$'],
+        ['include', '^cert/x509_util_nss_certs\\.cc$'],
         ['include', '^cert_net/nss_ocsp\\.cc$'],
         ['include', '^cert_net/nss_ocsp\\.h$'],
         ['include', '^proxy/proxy_resolver_mac\\.cc$'],
diff --git a/net/net_nacl.gyp b/net/net_nacl.gyp
index 2753c21..14c345c 100644
--- a/net/net_nacl.gyp
+++ b/net/net_nacl.gyp
@@ -23,7 +23,6 @@
       },
       'dependencies': [
         '../crypto/crypto_nacl.gyp:crypto_nacl',
-        '../native_client/tools.gyp:prep_toolchain',
         '../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
         '../third_party/boringssl/boringssl_nacl.gyp:boringssl_nacl',
         '../third_party/protobuf/protobuf.gyp:protobuf_lite',
diff --git a/net/proxy/proxy_resolver_v8_tracing.cc b/net/proxy/proxy_resolver_v8_tracing.cc
index 230b7caf..3970589 100644
--- a/net/proxy/proxy_resolver_v8_tracing.cc
+++ b/net/proxy/proxy_resolver_v8_tracing.cc
@@ -56,7 +56,7 @@
 // Returns event parameters for a PAC error message (line number + message).
 base::Value* NetLogErrorCallback(int line_number,
                                  const base::string16* message,
-                                 NetLog::LogLevel /* log_level */) {
+                                 NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("line_number", line_number);
   dict->SetString("message", *message);
diff --git a/net/proxy/proxy_script_decider.cc b/net/proxy/proxy_script_decider.cc
index 27e7afb..e7d8b17 100644
--- a/net/proxy/proxy_script_decider.cc
+++ b/net/proxy/proxy_script_decider.cc
@@ -10,6 +10,7 @@
 #include "base/format_macros.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
+#include "base/profiler/scoped_tracker.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -55,7 +56,7 @@
 
 base::Value* ProxyScriptDecider::PacSource::NetLogCallback(
     const GURL* effective_pac_url,
-    NetLog::LogLevel /* log_level */) const {
+    NetLogCaptureMode /* capture_mode */) const {
   base::DictionaryValue* dict = new base::DictionaryValue();
   std::string source;
   switch (type) {
@@ -103,6 +104,10 @@
 int ProxyScriptDecider::Start(
     const ProxyConfig& config, const base::TimeDelta wait_delay,
     bool fetch_pac_bytes, const CompletionCallback& callback) {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION("455942 ProxyScriptDecider::Start"));
+
   DCHECK_EQ(STATE_NONE, next_state_);
   DCHECK(!callback.is_null());
   DCHECK(config.HasAutomaticSettings());
@@ -221,6 +226,10 @@
 }
 
 int ProxyScriptDecider::DoWait() {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION("455942 ProxyScriptDecider::DoWait"));
+
   next_state_ = STATE_WAIT_COMPLETE;
 
   // If no waiting is required, continue on to the next state.
@@ -235,6 +244,11 @@
 }
 
 int ProxyScriptDecider::DoWaitComplete(int result) {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "455942 ProxyScriptDecider::DoWaitComplete"));
+
   DCHECK_EQ(OK, result);
   if (wait_delay_.ToInternalValue() != 0) {
     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT,
@@ -248,6 +262,11 @@
 }
 
 int ProxyScriptDecider::DoQuickCheck() {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "455942 ProxyScriptDecider::DoQuickCheck"));
+
   DCHECK(quick_check_enabled_);
   if (host_resolver_.get() == NULL) {
     // If we have no resolver, skip QuickCheck altogether.
@@ -275,6 +294,11 @@
 }
 
 int ProxyScriptDecider::DoQuickCheckComplete(int result) {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "455942 ProxyScriptDecider::DoQuickCheckComplete"));
+
   DCHECK(quick_check_enabled_);
   base::TimeDelta delta = base::Time::Now() - quick_check_start_time_;
   if (result == OK)
@@ -290,6 +314,11 @@
 }
 
 int ProxyScriptDecider::DoFetchPacScript() {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "455942 ProxyScriptDecider::DoFetchPacScript"));
+
   DCHECK(fetch_pac_bytes_);
 
   next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE;
@@ -338,6 +367,11 @@
 }
 
 int ProxyScriptDecider::DoVerifyPacScript() {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "455942 ProxyScriptDecider::DoVerifyPacScript"));
+
   next_state_ = STATE_VERIFY_PAC_SCRIPT_COMPLETE;
 
   // This is just a heuristic. Ideally we would try to parse the script.
@@ -348,6 +382,11 @@
 }
 
 int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) {
+  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "455942 ProxyScriptDecider::DoVerifyPacScriptComplete"));
+
   if (result != OK)
     return TryToFallbackPacSource(result);
 
diff --git a/net/proxy/proxy_script_decider.h b/net/proxy/proxy_script_decider.h
index 271e43ae..aa37c88 100644
--- a/net/proxy/proxy_script_decider.h
+++ b/net/proxy/proxy_script_decider.h
@@ -102,7 +102,7 @@
     // be non-NULL and point to the URL derived from information contained in
     // |this|, if Type is not WPAD_DHCP.
     base::Value* NetLogCallback(const GURL* effective_pac_url,
-                                NetLog::LogLevel log_level) const;
+                                NetLogCaptureMode capture_mode) const;
 
     Type type;
     GURL url;  // Empty unless |type == PAC_SOURCE_CUSTOM|.
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index f912d2e..7de5449 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -316,7 +316,7 @@
 base::Value* NetLogProxyConfigChangedCallback(
     const ProxyConfig* old_config,
     const ProxyConfig* new_config,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   // The "old_config" is optional -- the first notification will not have
   // any "previous" configuration.
@@ -327,7 +327,7 @@
 }
 
 base::Value* NetLogBadProxyListCallback(const ProxyRetryInfoMap* retry_info,
-                                        NetLog::LogLevel /* log_level */) {
+                                        NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::ListValue* list = new base::ListValue();
 
@@ -342,7 +342,7 @@
 // Returns NetLog parameters on a successfuly proxy resolution.
 base::Value* NetLogFinishedResolvingProxyCallback(
     const ProxyInfo* result,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("pac_string", result->ToPacString());
   return dict;
@@ -1389,7 +1389,7 @@
       network_delegate->NotifyResolveProxy(url, load_flags, *this, result);
 
     // When logging all events is enabled, dump the proxy list.
-    if (net_log.IsLogging()) {
+    if (net_log.GetCaptureMode().enabled()) {
       net_log.AddEvent(
           NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
           base::Bind(&NetLogFinishedResolvingProxyCallback, result));
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index 0dfee92..b5f1d98 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -99,7 +99,7 @@
 base::Value* NetLogQuicClientSessionCallback(
     const QuicServerId* server_id,
     bool require_confirmation,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("host", server_id->host());
   dict->SetInteger("port", server_id->port());
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index 408eb57b..fd60d8e8 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -38,7 +38,7 @@
 base::Value* NetLogQuicPacketCallback(const IPEndPoint* self_address,
                                       const IPEndPoint* peer_address,
                                       size_t packet_size,
-                                      NetLog::LogLevel /* log_level */) {
+                                      NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("self_address", self_address->ToString());
   dict->SetString("peer_address", peer_address->ToString());
@@ -52,7 +52,7 @@
     TransmissionType transmission_type,
     size_t packet_size,
     QuicTime sent_time,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("encryption_level", level);
   dict->SetInteger("transmission_type", transmission_type);
@@ -67,7 +67,7 @@
 base::Value* NetLogQuicPacketRetransmittedCallback(
     QuicPacketSequenceNumber old_sequence_number,
     QuicPacketSequenceNumber new_sequence_number,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("old_packet_sequence_number",
                   base::Uint64ToString(old_sequence_number));
@@ -76,8 +76,9 @@
   return dict;
 }
 
-base::Value* NetLogQuicPacketHeaderCallback(const QuicPacketHeader* header,
-                                            NetLog::LogLevel /* log_level */) {
+base::Value* NetLogQuicPacketHeaderCallback(
+    const QuicPacketHeader* header,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("connection_id",
                   base::Uint64ToString(header->public_header.connection_id));
@@ -91,8 +92,9 @@
   return dict;
 }
 
-base::Value* NetLogQuicStreamFrameCallback(const QuicStreamFrame* frame,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* NetLogQuicStreamFrameCallback(
+    const QuicStreamFrame* frame,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", frame->stream_id);
   dict->SetBoolean("fin", frame->fin);
@@ -102,7 +104,7 @@
 }
 
 base::Value* NetLogQuicAckFrameCallback(const QuicAckFrame* frame,
-                                        NetLog::LogLevel /* log_level */) {
+                                        NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("largest_observed",
                   base::Uint64ToString(frame->largest_observed));
@@ -146,7 +148,7 @@
 
 base::Value* NetLogQuicRstStreamFrameCallback(
     const QuicRstStreamFrame* frame,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", frame->stream_id);
   dict->SetInteger("quic_rst_stream_error", frame->error_code);
@@ -156,7 +158,7 @@
 
 base::Value* NetLogQuicConnectionCloseFrameCallback(
     const QuicConnectionCloseFrame* frame,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("quic_error", frame->error_code);
   dict->SetString("details", frame->error_details);
@@ -165,7 +167,7 @@
 
 base::Value* NetLogQuicWindowUpdateFrameCallback(
     const QuicWindowUpdateFrame* frame,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", frame->stream_id);
   dict->SetString("byte_offset", base::Uint64ToString(frame->byte_offset));
@@ -174,7 +176,7 @@
 
 base::Value* NetLogQuicBlockedFrameCallback(
     const QuicBlockedFrame* frame,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", frame->stream_id);
   return dict;
@@ -182,7 +184,7 @@
 
 base::Value* NetLogQuicGoAwayFrameCallback(
     const QuicGoAwayFrame* frame,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("quic_error", frame->error_code);
   dict->SetInteger("last_good_stream_id", frame->last_good_stream_id);
@@ -192,7 +194,7 @@
 
 base::Value* NetLogQuicStopWaitingFrameCallback(
     const QuicStopWaitingFrame* frame,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::DictionaryValue* sent_info = new base::DictionaryValue();
   dict->Set("sent_info", sent_info);
@@ -203,7 +205,7 @@
 
 base::Value* NetLogQuicVersionNegotiationPacketCallback(
     const QuicVersionNegotiationPacket* packet,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::ListValue* versions = new base::ListValue();
   dict->Set("versions", versions);
@@ -216,7 +218,7 @@
 
 base::Value* NetLogQuicCryptoHandshakeMessageCallback(
     const CryptoHandshakeMessage* message,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("quic_crypto_handshake_message", message->DebugString());
   return dict;
@@ -225,7 +227,7 @@
 base::Value* NetLogQuicOnConnectionClosedCallback(
     QuicErrorCode error,
     bool from_peer,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("quic_error", error);
   dict->SetBoolean("from_peer", from_peer);
@@ -234,7 +236,7 @@
 
 base::Value* NetLogQuicCertificateVerifiedCallback(
     scoped_refptr<X509Certificate> cert,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   // Only the subjects are logged so that we can investigate connection pooling.
   // More fields could be logged in the future.
   std::vector<std::string> dns_names;
diff --git a/net/quic/quic_http_utils.cc b/net/quic/quic_http_utils.cc
index 2bad8a6a..9a1c6bb 100644
--- a/net/quic/quic_http_utils.cc
+++ b/net/quic/quic_http_utils.cc
@@ -20,13 +20,12 @@
       IDLE : static_cast<RequestPriority>(HIGHEST - priority);
 }
 
-base::Value* QuicRequestNetLogCallback(
-    QuicStreamId stream_id,
-    const SpdyHeaderBlock* headers,
-    QuicPriority priority,
-    NetLog::LogLevel log_level) {
+base::Value* QuicRequestNetLogCallback(QuicStreamId stream_id,
+                                       const SpdyHeaderBlock* headers,
+                                       QuicPriority priority,
+                                       NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(
-      SpdyHeaderBlockNetLogCallback(headers, log_level));
+      SpdyHeaderBlockNetLogCallback(headers, capture_mode));
   dict->SetInteger("quic_priority", static_cast<int>(priority));
   dict->SetInteger("quic_stream_id", static_cast<int>(stream_id));
   return dict;
diff --git a/net/quic/quic_http_utils.h b/net/quic/quic_http_utils.h
index 862b7c61..6eafbc0 100644
--- a/net/quic/quic_http_utils.h
+++ b/net/quic/quic_http_utils.h
@@ -25,7 +25,7 @@
     QuicStreamId stream_id,
     const SpdyHeaderBlock* headers,
     QuicPriority priority,
-    NetLog::LogLevel log_level);
+    NetLogCaptureMode capture_mode);
 
 }  // namespace net
 
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 0fcb77b..67428f72d 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -67,18 +67,26 @@
 // Simplify ownership issues and the interaction with the MockSocketFactory.
 class MockQuicData {
  public:
+  MockQuicData() : sequence_number_(0) {}
+
   ~MockQuicData() {
     STLDeleteElements(&packets_);
   }
 
-  void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
+  void AddSynchronousRead(scoped_ptr<QuicEncryptedPacket> packet) {
     reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
                               sequence_number_++));
     packets_.push_back(packet.release());
   }
 
+  void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
+    reads_.push_back(
+        MockRead(ASYNC, packet->data(), packet->length(), sequence_number_++));
+    packets_.push_back(packet.release());
+  }
+
   void AddRead(IoMode mode, int rv) {
-    reads_.push_back(MockRead(mode, rv));
+    reads_.push_back(MockRead(mode, rv, sequence_number_++));
   }
 
   void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
@@ -87,12 +95,11 @@
     packets_.push_back(packet.release());
   }
 
-  void AddDelayedSocketDataToFactory(MockClientSocketFactory* factory,
-                                     size_t delay) {
+  void AddSocketDataToFactory(MockClientSocketFactory* factory) {
     MockRead* reads = reads_.empty() ? nullptr  : &reads_[0];
     MockWrite* writes = writes_.empty() ? nullptr  : &writes_[0];
-    socket_data_.reset(new DelayedSocketData(
-        delay, reads, reads_.size(), writes, writes_.size()));
+    socket_data_.reset(
+        new SequencedSocketData(reads, reads_.size(), writes, writes_.size()));
     factory->AddSocketDataProvider(socket_data_.get());
   }
 
@@ -394,7 +401,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -457,7 +464,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // There is no need to set up an alternate protocol job, because
   // no attempt will be made to speak to the proxy over TCP.
@@ -474,7 +481,7 @@
   MockQuicData mock_quic_data;
   mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   CreateSession();
 
@@ -533,7 +540,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -568,7 +575,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -603,7 +610,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -652,7 +659,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -736,7 +743,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -819,7 +826,7 @@
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
 
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -842,7 +849,7 @@
       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // In order for a new QUIC session to be established via alternate-protocol
   // without racing an HTTP connection, we need the host resolution to happen
@@ -916,7 +923,7 @@
       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // The non-alternate protocol job needs to hang in order to guarantee that
   // the alternate-protocol job will "win".
@@ -1133,12 +1140,12 @@
 
 TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
   MockQuicData mock_quic_data;
-  mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
+  mock_quic_data.AddSynchronousRead(ConstructConnectionClosePacket(1));
   mock_quic_data.AddWrite(
       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
                                     GetRequestHeaders("GET", "http", "/")));
   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
-  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   // When the QUIC connection fails, we will try the request again over HTTP.
   MockRead http_reads[] = {
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index f6e9671..3d0ff567 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -4,6 +4,8 @@
 
 #include "net/socket/client_socket_pool_base.h"
 
+#include <algorithm>
+
 #include "base/compiler_specific.h"
 #include "base/format_macros.h"
 #include "base/logging.h"
@@ -573,13 +575,8 @@
 
   const Group& group = *group_it->second;
   if (group.HasConnectJobForHandle(handle)) {
-    // Just return the state of the farthest along ConnectJob for the first
-    // group.jobs().size() pending requests.
-    LoadState max_state = LOAD_STATE_IDLE;
-    for (const auto& job : group.jobs()) {
-      max_state = std::max(max_state, job->GetLoadState());
-    }
-    return max_state;
+    // Just return the state of the oldest ConnectJob.
+    return (*group.jobs().begin())->GetLoadState();
   }
 
   if (group.CanUseAdditionalSocketSlot(max_sockets_per_group_))
@@ -629,7 +626,7 @@
     group_dict->Set("idle_sockets", idle_socket_list);
 
     base::ListValue* connect_jobs_list = new base::ListValue();
-    std::set<ConnectJob*>::const_iterator job = group->jobs().begin();
+    std::list<ConnectJob*>::const_iterator job = group->jobs().begin();
     for (job = group->jobs().begin(); job != group->jobs().end(); job++) {
       int source_id = (*job)->net_log().source().id;
       connect_jobs_list->Append(new base::FundamentalValue(source_id));
@@ -1197,19 +1194,16 @@
 
   if (is_preconnect)
     ++unassigned_job_count_;
-  jobs_.insert(job.release());
+  jobs_.push_back(job.release());
 }
 
 void ClientSocketPoolBaseHelper::Group::RemoveJob(ConnectJob* job) {
   scoped_ptr<ConnectJob> owned_job(job);
   SanityCheck();
 
-  std::set<ConnectJob*>::iterator it = jobs_.find(job);
-  if (it != jobs_.end()) {
-    jobs_.erase(it);
-  } else {
-    NOTREACHED();
-  }
+  // Check that |job| is in the list.
+  DCHECK_EQ(*std::find(jobs_.begin(), jobs_.end(), job), job);
+  jobs_.remove(job);
   size_t job_count = jobs_.size();
   if (job_count < unassigned_job_count_)
     unassigned_job_count_ = job_count;
diff --git a/net/socket/client_socket_pool_base.h b/net/socket/client_socket_pool_base.h
index 4892780..6997e1d 100644
--- a/net/socket/client_socket_pool_base.h
+++ b/net/socket/client_socket_pool_base.h
@@ -450,7 +450,7 @@
     void DecrementActiveSocketCount() { active_socket_count_--; }
 
     int unassigned_job_count() const { return unassigned_job_count_; }
-    const std::set<ConnectJob*>& jobs() const { return jobs_; }
+    const std::list<ConnectJob*>& jobs() const { return jobs_; }
     const std::list<IdleSocket>& idle_sockets() const { return idle_sockets_; }
     int active_socket_count() const { return active_socket_count_; }
     std::list<IdleSocket>* mutable_idle_sockets() { return &idle_sockets_; }
@@ -479,7 +479,7 @@
     size_t unassigned_job_count_;
 
     std::list<IdleSocket> idle_sockets_;
-    std::set<ConnectJob*> jobs_;
+    std::list<ConnectJob*> jobs_;
     RequestQueue pending_requests_;
     int active_socket_count_;  // number of active sockets used by clients
     // A timer for when to start the backup job.
@@ -846,9 +846,9 @@
 
     explicit ConnectJobFactoryAdaptor(ConnectJobFactory* connect_job_factory)
         : connect_job_factory_(connect_job_factory) {}
-    virtual ~ConnectJobFactoryAdaptor() {}
+    ~ConnectJobFactoryAdaptor() override {}
 
-    virtual scoped_ptr<ConnectJob> NewConnectJob(
+    scoped_ptr<ConnectJob> NewConnectJob(
         const std::string& group_name,
         const internal::ClientSocketPoolBaseHelper::Request& request,
         ConnectJob::Delegate* delegate) const override {
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index e54259d..2de67bd 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -1955,48 +1955,63 @@
 }
 
 // Test GetLoadState in the case there are two socket requests.
+// Only the first connection in the pool should affect the pool's load status.
 TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
   CreatePool(2, 2);
   connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
 
   ClientSocketHandle handle;
   TestCompletionCallback callback;
-  int rv = handle.Init("a",
-                       params_,
-                       DEFAULT_PRIORITY,
-                       callback.callback(),
-                       pool_.get(),
-                       BoundNetLog());
+  int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
+                       pool_.get(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
+
+  ClientSocketHandle handle2;
+  TestCompletionCallback callback2;
+  rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
+                    pool_.get(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
+
+  // Check that both handles report the state of the first job.
+  EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
+  EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
+
+  client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
+
+  // Check that both handles change to LOAD_STATE_CONNECTING.
+  EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
+  EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
+}
+
+// Test that the second connection request does not affect the pool's load
+// status.
+TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
+  CreatePool(2, 2);
+  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
+
+  ClientSocketHandle handle;
+  TestCompletionCallback callback;
+  int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
+                       pool_.get(), BoundNetLog());
   EXPECT_EQ(ERR_IO_PENDING, rv);
 
   ClientSocketHandle handle2;
   TestCompletionCallback callback2;
-  rv = handle2.Init("a",
-                    params_,
-                    DEFAULT_PRIORITY,
-                    callback2.callback(),
-                    pool_.get(),
-                    BoundNetLog());
+  rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
+                    pool_.get(), BoundNetLog());
   EXPECT_EQ(ERR_IO_PENDING, rv);
+  client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
 
-  // If the first Job is in an earlier state than the second, the state of
-  // the second job should be used for both handles.
-  client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
   EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
   EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
 
-  // If the second Job is in an earlier state than the second, the state of
-  // the first job should be used for both handles.
-  client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
-  // One request is farther
-  EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
-  EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
-
-  // Farthest along job connects and the first request gets the socket.  The
+  // First job connects and the first request gets the socket.  The
   // second handle switches to the state of the remaining ConnectJob.
   client_socket_factory_.SignalJob(0);
   EXPECT_EQ(OK, callback.WaitForResult());
-  EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
+  EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
 }
 
 // Test GetLoadState in the case the per-group limit is reached.
diff --git a/net/socket/nss_ssl_util.cc b/net/socket/nss_ssl_util.cc
index e0a22571..e98193b5 100644
--- a/net/socket/nss_ssl_util.cc
+++ b/net/socket/nss_ssl_util.cc
@@ -81,7 +81,7 @@
 
 base::Value* NetLogSSLErrorCallback(int net_error,
                                     int ssl_lib_error,
-                                    NetLog::LogLevel /* log_level */) {
+                                    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("net_error", net_error);
   if (ssl_lib_error)
@@ -385,7 +385,7 @@
     const char* function,
     const char* param,
     int ssl_lib_error,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("function", function);
   if (param[0] != '\0')
diff --git a/net/socket/sequenced_socket_data_unittest.cc b/net/socket/sequenced_socket_data_unittest.cc
new file mode 100644
index 0000000..e234b993
--- /dev/null
+++ b/net/socket/sequenced_socket_data_unittest.cc
@@ -0,0 +1,1057 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "net/base/io_buffer.h"
+#include "net/base/test_completion_callback.h"
+#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_test_util.h"
+#include "net/socket/transport_client_socket_pool.h"
+#include "testing/gtest/include/gtest/gtest-spi.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+//-----------------------------------------------------------------------------
+
+namespace net {
+
+namespace {
+
+const char kMsg1[] = "\0hello!\xff";
+const int kLen1 = arraysize(kMsg1);
+const char kMsg2[] = "\0a2345678\0";
+const int kLen2 = arraysize(kMsg2);
+const char kMsg3[] = "bye!";
+const int kLen3 = arraysize(kMsg3);
+const char kMsg4[] = "supercalifragilisticexpialidocious";
+const int kLen4 = arraysize(kMsg4);
+
+// Helper class for starting the next operation operation reentrantly after the
+// previous operation completed asynchronously. When OnIOComplete is called,
+// it will first verify that the previous operation behaved as expected. This is
+// specified by either SetExpectedRead or SetExpectedWrite. It will then invoke
+// a read or write operation specified by SetInvokeRead or SetInvokeWrite.
+class ReentrantHelper {
+ public:
+  ReentrantHelper(StreamSocket* socket)
+      : socket_(socket),
+        verify_read_(false),
+        first_read_data_(nullptr),
+        first_len_(-1),
+        second_read_(false),
+        second_write_data_(nullptr),
+        second_len_(-1) {}
+
+  // Expect that the previous operation will return |first_len| and will fill
+  // |first_read_data_| with |first_read_data|.
+  void SetExpectedRead(const char* first_read_data, int first_len) {
+    verify_read_ = true;
+    first_read_buf_ = new IOBuffer(first_len);
+    first_read_data_ = first_read_data;
+    first_len_ = first_len;
+  }
+
+  // Expect that the previous operation will return |first_len|.
+  void SetExpectedWrite(int first_len) {
+    verify_read_ = false;
+    first_len_ = first_len;
+  }
+
+  // After verifying expectations, invoke a read of |read_len| bytes into
+  // |read_buf|, notifying |callback| when complete.
+  void SetInvokeRead(scoped_refptr<IOBuffer> read_buf,
+                     int read_len,
+                     int second_rv,
+                     CompletionCallback callback) {
+    second_read_ = true;
+    second_read_buf_ = read_buf;
+    second_rv_ = second_rv;
+    second_callback_ = callback;
+    second_len_ = read_len;
+  }
+
+  // After verifying expectations, invoke a write of |write_len| bytes from
+  // |write_data|, notifying |callback| when complete.
+  void SetInvokeWrite(const char* write_data,
+                      int write_len,
+                      int second_rv,
+                      CompletionCallback callback) {
+    second_read_ = false;
+    second_rv_ = second_rv;
+    second_write_data_ = write_data;
+    second_callback_ = callback;
+    second_len_ = write_len;
+  }
+
+  // Returns the OnIOComplete callback for this helper.
+  CompletionCallback callback() {
+    return base::Bind(&ReentrantHelper::OnIOComplete, base::Unretained(this));
+  }
+
+  // Retuns the buffer where data is expected to have been written,
+  // when checked by SetExpectRead()
+  scoped_refptr<IOBuffer> read_buf() { return first_read_buf_; }
+
+ private:
+  void OnIOComplete(int rv) {
+    CHECK_NE(-1, first_len_) << "Expectation not set.";
+    CHECK_NE(-1, second_len_) << "Invocation not set.";
+    ASSERT_EQ(first_len_, rv);
+    if (verify_read_) {
+      ASSERT_EQ(std::string(first_read_data_, first_len_),
+                std::string(first_read_buf_->data(), rv));
+    }
+
+    if (second_read_) {
+      ASSERT_EQ(second_rv_, socket_->Read(second_read_buf_.get(), second_len_,
+                                          second_callback_));
+    } else {
+      scoped_refptr<IOBuffer> write_buf = new IOBuffer(second_len_);
+      memcpy(write_buf->data(), second_write_data_, second_len_);
+      ASSERT_EQ(second_rv_,
+                socket_->Write(write_buf.get(), second_len_, second_callback_));
+    }
+  }
+
+  StreamSocket* socket_;
+
+  bool verify_read_;
+  scoped_refptr<IOBuffer> first_read_buf_;
+  const char* first_read_data_;
+  int first_len_;
+
+  CompletionCallback second_callback_;
+  bool second_read_;
+  int second_rv_;
+  scoped_refptr<IOBuffer> second_read_buf_;
+  const char* second_write_data_;
+  int second_len_;
+
+  DISALLOW_COPY_AND_ASSIGN(ReentrantHelper);
+};
+
+class SequencedSocketDataTest : public testing::Test {
+ public:
+  SequencedSocketDataTest();
+  ~SequencedSocketDataTest() override;
+
+  // This method is used as the completion callback for an async read
+  // operation and when invoked, it verifies that the correct data was read,
+  // then reads from the socket and verifies that that it returns the correct
+  // value.
+  void ReentrantReadCallback(const char* data,
+                             int len1,
+                             int len2,
+                             int expected_rv2,
+                             int rv);
+
+  // This method is used at the completion callback for an async operation.
+  // When executed, verifies that |rv| equals |expected_rv| and then
+  // attempts an aync read from the socket into |read_buf_| (initialized
+  // to |read_buf_len|) using |callback|.
+  void ReentrantAsyncReadCallback(int len1, int len2, int rv);
+
+  // This method is used as the completion callback for an async write
+  // operation and when invoked, it verifies that the write returned correctly,
+  // then
+  // attempts to write to the socket and verifies that that it returns the
+  // correct value.
+  void ReentrantWriteCallback(int expected_rv1,
+                              const char* data,
+                              int len,
+                              int expected_rv2,
+                              int rv);
+
+  // This method is used at the completion callback for an async operation.
+  // When executed, verifies that |rv| equals |expected_rv| and then
+  // attempts an aync write of |data| with |callback|
+  void ReentrantAsyncWriteCallback(const char* data,
+                                   int len,
+                                   CompletionCallback callback,
+                                   int expected_rv,
+                                   int rv);
+
+  // Callback which adds a failure if it's ever called.
+  void FailingCompletionCallback(int rv);
+
+ protected:
+  void Initialize(MockRead* reads,
+                  size_t reads_count,
+                  MockWrite* writes,
+                  size_t writes_count);
+
+  void AssertSyncReadEquals(const char* data, int len);
+  void AssertAsyncReadEquals(const char* data, int len);
+  void AssertReadReturns(int len, int rv);
+  void AssertReadBufferEquals(const char* data, int len);
+
+  void AssertSyncWriteEquals(const char* data, int len);
+  void AssertAsyncWriteEquals(const char* data, int len);
+  void AssertWriteReturns(const char* data, int len, int rv);
+
+  // When a given test completes, data_.at_eof() is expected to
+  // match the value specified here. Most test should consume all
+  // reads and writes, but some tests verify error handling behavior
+  // do not consume all data.
+  void set_expect_eof(bool expect_eof) { expect_eof_ = expect_eof; }
+
+  TestCompletionCallback read_callback_;
+  scoped_refptr<IOBuffer> read_buf_;
+  TestCompletionCallback write_callback_;
+  CompletionCallback failing_callback_;
+  StreamSocket* sock_;
+
+ private:
+  MockConnect connect_data_;
+  scoped_ptr<SequencedSocketData> data_;
+
+  const HostPortPair endpoint_;
+  scoped_refptr<TransportSocketParams> tcp_params_;
+  MockClientSocketFactory socket_factory_;
+  MockTransportClientSocketPool socket_pool_;
+  ClientSocketHandle connection_;
+  bool expect_eof_;
+
+  DISALLOW_COPY_AND_ASSIGN(SequencedSocketDataTest);
+};
+
+SequencedSocketDataTest::SequencedSocketDataTest()
+    : failing_callback_(
+          base::Bind(&SequencedSocketDataTest::FailingCompletionCallback,
+                     base::Unretained(this))),
+      sock_(nullptr),
+      connect_data_(SYNCHRONOUS, OK),
+      endpoint_("www.google.com", 443),
+      tcp_params_(new TransportSocketParams(
+          endpoint_,
+          false,
+          false,
+          OnHostResolutionCallback(),
+          TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
+      socket_pool_(10, 10, &socket_factory_),
+      expect_eof_(true) {
+}
+
+SequencedSocketDataTest::~SequencedSocketDataTest() {
+  // Make sure no unexpected pending tasks will cause a failure.
+  base::RunLoop().RunUntilIdle();
+  if (expect_eof_) {
+    EXPECT_EQ(expect_eof_, data_->at_read_eof());
+    EXPECT_EQ(expect_eof_, data_->at_write_eof());
+  }
+}
+
+void SequencedSocketDataTest::Initialize(MockRead* reads,
+                                         size_t reads_count,
+                                         MockWrite* writes,
+                                         size_t writes_count) {
+  data_.reset(
+      new SequencedSocketData(reads, reads_count, writes, writes_count));
+  data_->set_connect_data(connect_data_);
+  socket_factory_.AddSocketDataProvider(data_.get());
+
+  EXPECT_EQ(OK,
+            connection_.Init(
+                endpoint_.ToString(), tcp_params_, LOWEST, CompletionCallback(),
+                reinterpret_cast<TransportClientSocketPool*>(&socket_pool_),
+                BoundNetLog()));
+  sock_ = connection_.socket();
+}
+
+void SequencedSocketDataTest::AssertSyncReadEquals(const char* data, int len) {
+  // Issue the read, which will complete immediately.
+  AssertReadReturns(len, len);
+  AssertReadBufferEquals(data, len);
+}
+
+void SequencedSocketDataTest::AssertAsyncReadEquals(const char* data, int len) {
+  // Issue the read, which will be completed asynchronously.
+  AssertReadReturns(len, ERR_IO_PENDING);
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  // Now the read should complete.
+  ASSERT_EQ(len, read_callback_.WaitForResult());
+  AssertReadBufferEquals(data, len);
+}
+
+void SequencedSocketDataTest::AssertReadReturns(int len, int rv) {
+  read_buf_ = new IOBuffer(len);
+  if (rv == ERR_IO_PENDING) {
+    ASSERT_EQ(rv, sock_->Read(read_buf_.get(), len, read_callback_.callback()));
+    ASSERT_FALSE(read_callback_.have_result());
+  } else {
+    ASSERT_EQ(rv, sock_->Read(read_buf_.get(), len, failing_callback_));
+  }
+}
+
+void SequencedSocketDataTest::AssertReadBufferEquals(const char* data,
+                                                     int len) {
+  ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
+}
+
+void SequencedSocketDataTest::AssertSyncWriteEquals(const char* data, int len) {
+  // Issue the write, which should be complete immediately.
+  AssertWriteReturns(data, len, len);
+  ASSERT_FALSE(write_callback_.have_result());
+}
+
+void SequencedSocketDataTest::AssertAsyncWriteEquals(const char* data,
+                                                     int len) {
+  // Issue the read, which should be completed asynchronously.
+  AssertWriteReturns(data, len, ERR_IO_PENDING);
+
+  EXPECT_FALSE(read_callback_.have_result());
+  EXPECT_TRUE(sock_->IsConnected());
+
+  ASSERT_EQ(len, write_callback_.WaitForResult());
+}
+
+void SequencedSocketDataTest::AssertWriteReturns(const char* data,
+                                                 int len,
+                                                 int rv) {
+  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
+  memcpy(buf->data(), data, len);
+
+  if (rv == ERR_IO_PENDING) {
+    ASSERT_EQ(rv, sock_->Write(buf.get(), len, write_callback_.callback()));
+    ASSERT_FALSE(write_callback_.have_result());
+  } else {
+    ASSERT_EQ(rv, sock_->Write(buf.get(), len, failing_callback_));
+  }
+}
+
+void SequencedSocketDataTest::ReentrantReadCallback(const char* data,
+                                                    int len1,
+                                                    int len2,
+                                                    int expected_rv2,
+                                                    int rv) {
+  ASSERT_EQ(len1, rv);
+  AssertReadBufferEquals(data, len1);
+
+  AssertReadReturns(len2, expected_rv2);
+}
+
+void SequencedSocketDataTest::ReentrantAsyncReadCallback(int expected_rv,
+                                                         int len,
+                                                         int rv) {
+  ASSERT_EQ(expected_rv, rv);
+
+  AssertReadReturns(len, ERR_IO_PENDING);
+}
+
+void SequencedSocketDataTest::ReentrantWriteCallback(int expected_rv1,
+                                                     const char* data,
+                                                     int len,
+                                                     int expected_rv2,
+                                                     int rv) {
+  ASSERT_EQ(expected_rv1, rv);
+
+  AssertWriteReturns(data, len, expected_rv2);
+}
+
+void SequencedSocketDataTest::ReentrantAsyncWriteCallback(
+    const char* data,
+    int len,
+    CompletionCallback callback,
+    int expected_rv,
+    int rv) {
+  EXPECT_EQ(expected_rv, rv);
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(len));
+  memcpy(write_buf->data(), data, len);
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf.get(), len, callback));
+}
+
+void SequencedSocketDataTest::FailingCompletionCallback(int rv) {
+  ADD_FAILURE() << "Callback should not have been invoked";
+}
+
+// ----------- Read
+
+TEST_F(SequencedSocketDataTest, SingleSyncRead) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+  AssertSyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, MultipleSyncReads) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+      MockRead(SYNCHRONOUS, kMsg2, kLen2, 1),
+      MockRead(SYNCHRONOUS, kMsg3, kLen3, 2),
+      MockRead(SYNCHRONOUS, kMsg3, kLen3, 3),
+      MockRead(SYNCHRONOUS, kMsg2, kLen2, 4),
+      MockRead(SYNCHRONOUS, kMsg3, kLen3, 5),
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 6),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertSyncReadEquals(kMsg2, kLen2);
+  AssertSyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg2, kLen2);
+  AssertSyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, SingleAsyncRead) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  AssertAsyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, MultipleAsyncReads) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0),
+      MockRead(ASYNC, kMsg2, kLen2, 1),
+      MockRead(ASYNC, kMsg3, kLen3, 2),
+      MockRead(ASYNC, kMsg3, kLen3, 3),
+      MockRead(ASYNC, kMsg2, kLen2, 4),
+      MockRead(ASYNC, kMsg3, kLen3, 5),
+      MockRead(ASYNC, kMsg1, kLen1, 6),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  AssertAsyncReadEquals(kMsg1, kLen1);
+  AssertAsyncReadEquals(kMsg2, kLen2);
+  AssertAsyncReadEquals(kMsg3, kLen3);
+  AssertAsyncReadEquals(kMsg3, kLen3);
+  AssertAsyncReadEquals(kMsg2, kLen2);
+  AssertAsyncReadEquals(kMsg3, kLen3);
+  AssertAsyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, MixedReads) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+      MockRead(ASYNC, kMsg2, kLen2, 1),
+      MockRead(SYNCHRONOUS, kMsg3, kLen3, 2),
+      MockRead(ASYNC, kMsg3, kLen3, 3),
+      MockRead(SYNCHRONOUS, kMsg2, kLen2, 4),
+      MockRead(ASYNC, kMsg3, kLen3, 5),
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 6),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertAsyncReadEquals(kMsg2, kLen2);
+  AssertSyncReadEquals(kMsg3, kLen3);
+  AssertAsyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg2, kLen2);
+  AssertAsyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, SyncReadFromCompletionCallback) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(SYNCHRONOUS, kMsg2, kLen2, 1),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  read_buf_ = new IOBuffer(kLen1);
+  ASSERT_EQ(
+      ERR_IO_PENDING,
+      sock_->Read(
+          read_buf_.get(), kLen1,
+          base::Bind(&SequencedSocketDataTest::ReentrantReadCallback,
+                     base::Unretained(this), kMsg1, kLen1, kLen2, kLen2)));
+
+  base::MessageLoop::current()->RunUntilIdle();
+  AssertReadBufferEquals(kMsg2, kLen2);
+}
+
+TEST_F(SequencedSocketDataTest, ManyReentrantReads) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0),
+      MockRead(ASYNC, kMsg2, kLen2, 1),
+      MockRead(ASYNC, kMsg3, kLen3, 2),
+      MockRead(ASYNC, kMsg4, kLen4, 3),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  read_buf_ = new IOBuffer(kLen4);
+
+  ReentrantHelper helper3(sock_);
+  helper3.SetExpectedRead(kMsg3, kLen3);
+  helper3.SetInvokeRead(read_buf_, kLen4, ERR_IO_PENDING,
+                        read_callback_.callback());
+
+  ReentrantHelper helper2(sock_);
+  helper2.SetExpectedRead(kMsg2, kLen2);
+  helper2.SetInvokeRead(helper3.read_buf(), kLen3, ERR_IO_PENDING,
+                        helper3.callback());
+
+  ReentrantHelper helper(sock_);
+  helper.SetExpectedRead(kMsg1, kLen1);
+  helper.SetInvokeRead(helper2.read_buf(), kLen2, ERR_IO_PENDING,
+                       helper2.callback());
+
+  sock_->Read(helper.read_buf().get(), kLen1, helper.callback());
+
+  ASSERT_EQ(kLen4, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg4, kLen4);
+}
+
+TEST_F(SequencedSocketDataTest, AsyncReadFromCompletionCallback) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg2, kLen2, 1),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  read_buf_ = new IOBuffer(kLen1);
+  ASSERT_EQ(
+      ERR_IO_PENDING,
+      sock_->Read(read_buf_.get(), kLen1,
+                  base::Bind(&SequencedSocketDataTest::ReentrantReadCallback,
+                             base::Unretained(this), kMsg1, kLen1, kLen2,
+                             ERR_IO_PENDING)));
+
+  ASSERT_FALSE(read_callback_.have_result());
+  ASSERT_EQ(kLen2, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg2, kLen2);
+}
+
+TEST_F(SequencedSocketDataTest, SingleSyncReadTooEarly) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 1),
+  };
+
+  MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, 0)};
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  EXPECT_NONFATAL_FAILURE(AssertReadReturns(kLen1, ERR_UNEXPECTED),
+                          "Unable to perform synchronous IO while stopped");
+  set_expect_eof(false);
+}
+
+TEST_F(SequencedSocketDataTest, SingleSyncReadSmallBuffer) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  // Read the first chunk.
+  AssertReadReturns(kLen1 - 1, kLen1 - 1);
+  AssertReadBufferEquals(kMsg1, kLen1 - 1);
+  // Then read the second chunk.
+  AssertReadReturns(1, 1);
+  AssertReadBufferEquals(kMsg1 + kLen1 - 1, 1);
+}
+
+TEST_F(SequencedSocketDataTest, SingleSyncReadLargeBuffer) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(2 * kLen1));
+  ASSERT_EQ(kLen1, sock_->Read(read_buf.get(), 2 * kLen1, failing_callback_));
+  ASSERT_EQ(std::string(kMsg1, kLen1), std::string(read_buf->data(), kLen1));
+}
+
+TEST_F(SequencedSocketDataTest, SingleAsyncReadLargeBuffer) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0),
+  };
+
+  Initialize(reads, arraysize(reads), nullptr, 0);
+
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(2 * kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf.get(), 2 * kLen1, read_callback_.callback()));
+  ASSERT_EQ(kLen1, read_callback_.WaitForResult());
+  ASSERT_EQ(std::string(kMsg1, kLen1), std::string(read_buf->data(), kLen1));
+}
+
+// ----------- Write
+
+TEST_F(SequencedSocketDataTest, SingleSyncWriteTooEarly) {
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 1),
+  };
+
+  MockRead reads[] = {MockRead(SYNCHRONOUS, 0, 0)};
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  EXPECT_NONFATAL_FAILURE(AssertWriteReturns(kMsg1, kLen1, ERR_UNEXPECTED),
+                          "Unable to perform synchronous IO while stopped");
+
+  set_expect_eof(false);
+}
+
+TEST_F(SequencedSocketDataTest, DISABLED_SingleSyncWriteTooSmall) {
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  // Attempt to write all of the message, but only some will be written.
+  EXPECT_NONFATAL_FAILURE(AssertSyncWriteEquals(kMsg1, kLen1 - 1), "");
+}
+
+TEST_F(SequencedSocketDataTest, SingleSyncPartialWrite) {
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1 - 1, 0),
+      MockWrite(SYNCHRONOUS, kMsg1 + kLen1 - 1, 1, 1),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  // Attempt to write all of the message, but only some will be written.
+  AssertSyncWriteEquals(kMsg1, kLen1 - 1);
+  // Write the rest of the message.
+  AssertSyncWriteEquals(kMsg1 + kLen1 - 1, 1);
+}
+
+TEST_F(SequencedSocketDataTest, SingleSyncWrite) {
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  AssertSyncWriteEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, MultipleSyncWrites) {
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
+      MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1),
+      MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
+      MockWrite(SYNCHRONOUS, kMsg3, kLen3, 3),
+      MockWrite(SYNCHRONOUS, kMsg2, kLen2, 4),
+      MockWrite(SYNCHRONOUS, kMsg3, kLen3, 5),
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 6),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  AssertSyncWriteEquals(kMsg1, kLen1);
+  AssertSyncWriteEquals(kMsg2, kLen2);
+  AssertSyncWriteEquals(kMsg3, kLen3);
+  AssertSyncWriteEquals(kMsg3, kLen3);
+  AssertSyncWriteEquals(kMsg2, kLen2);
+  AssertSyncWriteEquals(kMsg3, kLen3);
+  AssertSyncWriteEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, SingleAsyncWrite) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  AssertAsyncWriteEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, MultipleAsyncWrites) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0),
+      MockWrite(ASYNC, kMsg2, kLen2, 1),
+      MockWrite(ASYNC, kMsg3, kLen3, 2),
+      MockWrite(ASYNC, kMsg3, kLen3, 3),
+      MockWrite(ASYNC, kMsg2, kLen2, 4),
+      MockWrite(ASYNC, kMsg3, kLen3, 5),
+      MockWrite(ASYNC, kMsg1, kLen1, 6),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  AssertAsyncWriteEquals(kMsg1, kLen1);
+  AssertAsyncWriteEquals(kMsg2, kLen2);
+  AssertAsyncWriteEquals(kMsg3, kLen3);
+  AssertAsyncWriteEquals(kMsg3, kLen3);
+  AssertAsyncWriteEquals(kMsg2, kLen2);
+  AssertAsyncWriteEquals(kMsg3, kLen3);
+  AssertAsyncWriteEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, MixedWrites) {
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
+      MockWrite(ASYNC, kMsg2, kLen2, 1),
+      MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
+      MockWrite(ASYNC, kMsg3, kLen3, 3),
+      MockWrite(SYNCHRONOUS, kMsg2, kLen2, 4),
+      MockWrite(ASYNC, kMsg3, kLen3, 5),
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 6),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  AssertSyncWriteEquals(kMsg1, kLen1);
+  AssertAsyncWriteEquals(kMsg2, kLen2);
+  AssertSyncWriteEquals(kMsg3, kLen3);
+  AssertAsyncWriteEquals(kMsg3, kLen3);
+  AssertSyncWriteEquals(kMsg2, kLen2);
+  AssertAsyncWriteEquals(kMsg3, kLen3);
+  AssertSyncWriteEquals(kMsg1, kLen1);
+}
+
+TEST_F(SequencedSocketDataTest, SyncWriteFromCompletionCallback) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0),
+      MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+  memcpy(write_buf->data(), kMsg1, kLen1);
+  ASSERT_EQ(
+      ERR_IO_PENDING,
+      sock_->Write(
+          write_buf.get(), kLen1,
+          base::Bind(&SequencedSocketDataTest::ReentrantWriteCallback,
+                     base::Unretained(this), kLen1, kMsg2, kLen2, kLen2)));
+
+  base::MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SequencedSocketDataTest, AsyncWriteFromCompletionCallback) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0), MockWrite(ASYNC, kMsg2, kLen2, 1),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+  memcpy(write_buf->data(), kMsg1, kLen1);
+  ASSERT_EQ(
+      ERR_IO_PENDING,
+      sock_->Write(write_buf.get(), kLen1,
+                   base::Bind(&SequencedSocketDataTest::ReentrantWriteCallback,
+                              base::Unretained(this), kLen1, kMsg2, kLen2,
+                              ERR_IO_PENDING)));
+
+  ASSERT_FALSE(write_callback_.have_result());
+  ASSERT_EQ(kLen2, write_callback_.WaitForResult());
+}
+
+TEST_F(SequencedSocketDataTest, ManyReentrantWrites) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0),
+      MockWrite(ASYNC, kMsg2, kLen2, 1),
+      MockWrite(ASYNC, kMsg3, kLen3, 2),
+      MockWrite(ASYNC, kMsg4, kLen4, 3),
+  };
+
+  Initialize(nullptr, 0, writes, arraysize(writes));
+
+  ReentrantHelper helper3(sock_);
+  helper3.SetExpectedWrite(kLen3);
+  helper3.SetInvokeWrite(kMsg4, kLen4, ERR_IO_PENDING,
+                         write_callback_.callback());
+
+  ReentrantHelper helper2(sock_);
+  helper2.SetExpectedWrite(kLen2);
+  helper2.SetInvokeWrite(kMsg3, kLen3, ERR_IO_PENDING, helper3.callback());
+
+  ReentrantHelper helper(sock_);
+  helper.SetExpectedWrite(kLen1);
+  helper.SetInvokeWrite(kMsg2, kLen2, ERR_IO_PENDING, helper2.callback());
+
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+  memcpy(write_buf->data(), kMsg1, kLen1);
+  sock_->Write(write_buf.get(), kLen1, helper.callback());
+
+  ASSERT_EQ(kLen4, write_callback_.WaitForResult());
+}
+
+// ----------- Mixed Reads and Writes
+
+TEST_F(SequencedSocketDataTest, MixedSyncOperations) {
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+      MockRead(SYNCHRONOUS, kMsg2, kLen2, 3),
+  };
+
+  MockWrite writes[] = {
+      MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1),
+      MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertSyncWriteEquals(kMsg2, kLen2);
+  AssertSyncWriteEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SequencedSocketDataTest, MixedAsyncOperations) {
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg2, kLen2, 3),
+  };
+
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg2, kLen2, 1), MockWrite(ASYNC, kMsg3, kLen3, 2),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertAsyncReadEquals(kMsg1, kLen1);
+  AssertAsyncWriteEquals(kMsg2, kLen2);
+  AssertAsyncWriteEquals(kMsg3, kLen3);
+  AssertAsyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SequencedSocketDataTest, InterleavedAsyncOperations) {
+  // Order of completion is read, write, write, read.
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg2, kLen2, 3),
+  };
+
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg2, kLen2, 1), MockWrite(ASYNC, kMsg3, kLen3, 2),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  // Issue the write, which will block until the read completes.
+  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
+
+  // Issue the read which will return first.
+  AssertReadReturns(kLen1, ERR_IO_PENDING);
+
+  ASSERT_EQ(kLen1, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg1, kLen1);
+
+  ASSERT_TRUE(write_callback_.have_result());
+  ASSERT_EQ(kLen2, write_callback_.WaitForResult());
+
+  // Issue the read, which will block until the write completes.
+  AssertReadReturns(kLen2, ERR_IO_PENDING);
+
+  // Issue the writes which will return first.
+  AssertWriteReturns(kMsg3, kLen3, ERR_IO_PENDING);
+  ASSERT_EQ(kLen3, write_callback_.WaitForResult());
+
+  ASSERT_EQ(kLen2, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg2, kLen2);
+}
+
+TEST_F(SequencedSocketDataTest, InterleavedMixedOperations) {
+  // Order of completion is read, write, write, read.
+  MockRead reads[] = {
+      MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+      MockRead(ASYNC, kMsg2, kLen2, 3),
+      MockRead(ASYNC, kMsg3, kLen3, 5),
+  };
+
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg2, kLen2, 1),
+      MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
+      MockWrite(SYNCHRONOUS, kMsg1, kLen1, 4),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  // Issue the write, which will block until the read completes.
+  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
+
+  // Issue the writes which will complete immediately.
+  AssertSyncReadEquals(kMsg1, kLen1);
+
+  ASSERT_FALSE(write_callback_.have_result());
+  ASSERT_EQ(kLen2, write_callback_.WaitForResult());
+
+  // Issue the read, which will block until the write completes.
+  AssertReadReturns(kLen2, ERR_IO_PENDING);
+
+  // Issue the writes which will complete immediately.
+  AssertSyncWriteEquals(kMsg3, kLen3);
+
+  ASSERT_FALSE(read_callback_.have_result());
+  ASSERT_EQ(kLen2, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg2, kLen2);
+
+  // Issue the read, which will block until the write completes.
+  AssertReadReturns(kLen2, ERR_IO_PENDING);
+
+  // Issue the writes which will complete immediately.
+  AssertSyncWriteEquals(kMsg1, kLen1);
+
+  ASSERT_FALSE(read_callback_.have_result());
+  ASSERT_EQ(kLen3, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg3, kLen3);
+}
+
+TEST_F(SequencedSocketDataTest, AsyncReadFromWriteCompletionCallback) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0),
+  };
+
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg2, kLen2, 1),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+  memcpy(write_buf->data(), kMsg1, kLen1);
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Write(
+                write_buf.get(), kLen1,
+                base::Bind(&SequencedSocketDataTest::ReentrantAsyncReadCallback,
+                           base::Unretained(this), kLen1, kLen2)));
+
+  ASSERT_FALSE(read_callback_.have_result());
+  ASSERT_EQ(kLen2, read_callback_.WaitForResult());
+  AssertReadBufferEquals(kMsg2, kLen2);
+}
+
+TEST_F(SequencedSocketDataTest, AsyncWriteFromReadCompletionCallback) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg2, kLen2, 1),
+  };
+
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
+  ASSERT_EQ(
+      ERR_IO_PENDING,
+      sock_->Read(
+          read_buf.get(), kLen1,
+          base::Bind(&SequencedSocketDataTest::ReentrantAsyncWriteCallback,
+                     base::Unretained(this), kMsg2, kLen2,
+                     write_callback_.callback(), kLen1)));
+
+  ASSERT_FALSE(write_callback_.have_result());
+  ASSERT_EQ(kLen2, write_callback_.WaitForResult());
+}
+
+TEST_F(SequencedSocketDataTest, MixedReentrantOperations) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0), MockWrite(ASYNC, kMsg3, kLen3, 2),
+  };
+
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg2, kLen2, 1), MockRead(ASYNC, kMsg4, kLen4, 3),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  read_buf_ = new IOBuffer(kLen4);
+
+  ReentrantHelper helper3(sock_);
+  helper3.SetExpectedWrite(kLen3);
+  helper3.SetInvokeRead(read_buf_, kLen4, ERR_IO_PENDING,
+                        read_callback_.callback());
+
+  ReentrantHelper helper2(sock_);
+  helper2.SetExpectedRead(kMsg2, kLen2);
+  helper2.SetInvokeWrite(kMsg3, kLen3, ERR_IO_PENDING, helper3.callback());
+
+  ReentrantHelper helper(sock_);
+  helper.SetExpectedWrite(kLen1);
+  helper.SetInvokeRead(helper2.read_buf(), kLen2, ERR_IO_PENDING,
+                       helper2.callback());
+
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+  memcpy(write_buf->data(), kMsg1, kLen1);
+  sock_->Write(write_buf.get(), kLen1, helper.callback());
+
+  ASSERT_EQ(kLen4, read_callback_.WaitForResult());
+}
+
+TEST_F(SequencedSocketDataTest, MixedReentrantOperationsThenSynchronousRead) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg1, kLen1, 0), MockWrite(ASYNC, kMsg3, kLen3, 2),
+  };
+
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg2, kLen2, 1), MockRead(SYNCHRONOUS, kMsg4, kLen4, 3),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  read_buf_ = new IOBuffer(kLen4);
+
+  ReentrantHelper helper3(sock_);
+  helper3.SetExpectedWrite(kLen3);
+  helper3.SetInvokeRead(read_buf_, kLen4, kLen4, failing_callback_);
+
+  ReentrantHelper helper2(sock_);
+  helper2.SetExpectedRead(kMsg2, kLen2);
+  helper2.SetInvokeWrite(kMsg3, kLen3, ERR_IO_PENDING, helper3.callback());
+
+  ReentrantHelper helper(sock_);
+  helper.SetExpectedWrite(kLen1);
+  helper.SetInvokeRead(helper2.read_buf(), kLen2, ERR_IO_PENDING,
+                       helper2.callback());
+
+  scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+  memcpy(write_buf->data(), kMsg1, kLen1);
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Write(write_buf.get(), kLen1, helper.callback()));
+
+  base::MessageLoop::current()->RunUntilIdle();
+  AssertReadBufferEquals(kMsg4, kLen4);
+}
+
+TEST_F(SequencedSocketDataTest, MixedReentrantOperationsThenSynchronousWrite) {
+  MockWrite writes[] = {
+      MockWrite(ASYNC, kMsg2, kLen2, 1),
+      MockWrite(SYNCHRONOUS, kMsg4, kLen4, 3),
+  };
+
+  MockRead reads[] = {
+      MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg3, kLen3, 2),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  read_buf_ = new IOBuffer(kLen4);
+
+  ReentrantHelper helper3(sock_);
+  helper3.SetExpectedRead(kMsg3, kLen3);
+  helper3.SetInvokeWrite(kMsg4, kLen4, kLen4, failing_callback_);
+
+  ReentrantHelper helper2(sock_);
+  helper2.SetExpectedWrite(kLen2);
+  helper2.SetInvokeRead(helper3.read_buf(), kLen3, ERR_IO_PENDING,
+                        helper3.callback());
+
+  ReentrantHelper helper(sock_);
+  helper.SetExpectedRead(kMsg1, kLen1);
+  helper.SetInvokeWrite(kMsg2, kLen2, ERR_IO_PENDING, helper2.callback());
+
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(helper.read_buf().get(), kLen1, helper.callback()));
+
+  base::MessageLoop::current()->RunUntilIdle();
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/net/socket/socket_net_log_params.cc b/net/socket/socket_net_log_params.cc
index bcc12c8..3dd6595 100644
--- a/net/socket/socket_net_log_params.cc
+++ b/net/socket/socket_net_log_params.cc
@@ -16,7 +16,7 @@
 
 base::Value* NetLogSocketErrorCallback(int net_error,
                                        int os_error,
-                                       NetLog::LogLevel /* log_level */) {
+                                       NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("net_error", net_error);
   dict->SetInteger("os_error", os_error);
@@ -24,14 +24,14 @@
 }
 
 base::Value* NetLogHostPortPairCallback(const HostPortPair* host_and_port,
-                                        NetLog::LogLevel /* log_level */) {
+                                        NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("host_and_port", host_and_port->ToString());
   return dict;
 }
 
 base::Value* NetLogIPEndPointCallback(const IPEndPoint* address,
-                                      NetLog::LogLevel /* log_level */) {
+                                      NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("address", address->ToString());
   return dict;
@@ -39,7 +39,7 @@
 
 base::Value* NetLogSourceAddressCallback(const struct sockaddr* net_address,
                                          socklen_t address_len,
-                                         NetLog::LogLevel /* log_level */) {
+                                         NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("source_address",
                   NetAddressToStringWithPort(net_address, address_len));
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index b905597..b3f5040e 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -11,6 +11,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
+#include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/time/time.h"
@@ -174,6 +175,26 @@
   return writes_[write_index_++];
 }
 
+bool StaticSocketDataHelper::VerifyWriteData(const std::string& data) {
+  CHECK(!at_write_eof());
+  // Check that what the actual data matches the expectations.
+  const MockWrite& next_write = PeekWrite();
+  if (!next_write.data)
+    return true;
+
+  // Note: Partial writes are supported here.  If the expected data
+  // is a match, but shorter than the write actually written, that is legal.
+  // Example:
+  //   Application writes "foobarbaz" (9 bytes)
+  //   Expected write was "foo" (3 bytes)
+  //   This is a success, and the function returns true.
+  std::string expected_data(next_write.data, next_write.data_len);
+  std::string actual_data(data.substr(0, next_write.data_len));
+  EXPECT_GE(data.length(), expected_data.length());
+  EXPECT_EQ(expected_data, actual_data);
+  return expected_data == actual_data;
+}
+
 void StaticSocketDataHelper::Reset() {
   read_index_ = 0;
   write_index_ = 0;
@@ -212,25 +233,15 @@
 
   // Check that what we are writing matches the expectation.
   // Then give the mocked return value.
-  const MockWrite& w = helper_.AdvanceWrite();
-  int result = w.result;
-  if (w.data) {
-    // Note - we can simulate a partial write here.  If the expected data
-    // is a match, but shorter than the write actually written, that is legal.
-    // Example:
-    //   Application writes "foobarbaz" (9 bytes)
-    //   Expected write was "foo" (3 bytes)
-    //   This is a success, and we return 3 to the application.
-    std::string expected_data(w.data, w.data_len);
-    EXPECT_GE(data.length(), expected_data.length());
-    std::string actual_data(data.substr(0, w.data_len));
-    EXPECT_EQ(expected_data, actual_data);
-    if (expected_data != actual_data)
-      return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
-    if (result == OK)
-      result = w.data_len;
-  }
-  return MockWriteResult(w.mode, result);
+  if (!helper_.VerifyWriteData(data))
+    return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
+
+  const MockWrite& next_write = helper_.AdvanceWrite();
+  // In the case that the write was successful, return the number of bytes
+  // written. Otherwise return the error code.
+  int result =
+      next_write.result == OK ? next_write.data_len : next_write.result;
+  return MockWriteResult(next_write.mode, result);
 }
 
 void StaticSocketDataProvider::Reset() {
@@ -454,6 +465,235 @@
 
 OrderedSocketData::~OrderedSocketData() {}
 
+SequencedSocketData::SequencedSocketData(MockRead* reads,
+                                         size_t reads_count,
+                                         MockWrite* writes,
+                                         size_t writes_count)
+    : helper_(reads, reads_count, writes, writes_count),
+      sequence_number_(0),
+      read_state_(IDLE),
+      write_state_(IDLE),
+      weak_factory_(this) {
+  // Check that reads and writes have a contiguous set of sequence numbers
+  // starting from 0 and working their way up, with no repeats and skipping
+  // no values.
+  size_t next_read = 0;
+  size_t next_write = 0;
+  int next_sequence_number = 0;
+  while (next_read < reads_count || next_write < writes_count) {
+    if (next_read < reads_count &&
+        reads[next_read].sequence_number == next_sequence_number) {
+      ++next_read;
+      ++next_sequence_number;
+      continue;
+    }
+    if (next_write < writes_count &&
+        writes[next_write].sequence_number == next_sequence_number) {
+      ++next_write;
+      ++next_sequence_number;
+      continue;
+    }
+    CHECK(false) << "Sequence number not found where expected: "
+                 << next_sequence_number;
+    return;
+  }
+  CHECK_EQ(next_read, reads_count);
+  CHECK_EQ(next_write, writes_count);
+}
+
+SequencedSocketData::SequencedSocketData(const MockConnect& connect,
+                                         MockRead* reads,
+                                         size_t reads_count,
+                                         MockWrite* writes,
+                                         size_t writes_count)
+    : SequencedSocketData(reads, reads_count, writes, writes_count) {
+  set_connect_data(connect);
+}
+
+MockRead SequencedSocketData::OnRead() {
+  CHECK_EQ(IDLE, read_state_);
+  CHECK(!helper_.at_read_eof());
+
+  NET_TRACE(1, " *** ") << "sequence_number: " << sequence_number_;
+  const MockRead& next_read = helper_.PeekRead();
+  NET_TRACE(1, " *** ") << "next_read: " << next_read.sequence_number;
+  CHECK_GE(next_read.sequence_number, sequence_number_);
+
+  if (next_read.sequence_number <= sequence_number_) {
+    if (next_read.mode == SYNCHRONOUS) {
+      NET_TRACE(1, " *** ") << "Returning synchronously";
+      DumpMockReadWrite(next_read);
+      helper_.AdvanceRead();
+      ++sequence_number_;
+      MaybePostWriteCompleteTask();
+      return next_read;
+    }
+
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(&SequencedSocketData::OnReadComplete,
+                              weak_factory_.GetWeakPtr()));
+    CHECK_NE(COMPLETING, write_state_);
+    read_state_ = COMPLETING;
+  } else if (next_read.mode == SYNCHRONOUS) {
+    ADD_FAILURE() << "Unable to perform synchronous IO while stopped";
+    return MockRead(SYNCHRONOUS, ERR_UNEXPECTED);
+  } else {
+    NET_TRACE(1, " *** ") << "Waiting for write to trigger read";
+    read_state_ = PENDING;
+  }
+
+  return MockRead(SYNCHRONOUS, ERR_IO_PENDING);
+}
+
+MockWriteResult SequencedSocketData::OnWrite(const std::string& data) {
+  CHECK_EQ(IDLE, write_state_);
+  CHECK(!helper_.at_write_eof());
+
+  NET_TRACE(1, " *** ") << "sequence_number: " << sequence_number_;
+  const MockWrite& next_write = helper_.PeekWrite();
+  NET_TRACE(1, " *** ") << "next_write: " << next_write.sequence_number;
+  CHECK_GE(next_write.sequence_number, sequence_number_);
+
+  if (!helper_.VerifyWriteData(data))
+    return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
+
+  if (next_write.sequence_number <= sequence_number_) {
+    if (next_write.mode == SYNCHRONOUS) {
+      helper_.AdvanceWrite();
+      ++sequence_number_;
+      MaybePostReadCompleteTask();
+      // In the case that the write was successful, return the number of bytes
+      // written. Otherwise return the error code.
+      int rv =
+          next_write.result != OK ? next_write.result : next_write.data_len;
+      NET_TRACE(1, " *** ") << "Returning synchronously";
+      return MockWriteResult(SYNCHRONOUS, rv);
+    }
+
+    NET_TRACE(1, " *** ") << "Posting task to complete write";
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(&SequencedSocketData::OnWriteComplete,
+                              weak_factory_.GetWeakPtr()));
+    CHECK_NE(COMPLETING, read_state_);
+    write_state_ = COMPLETING;
+  } else if (next_write.mode == SYNCHRONOUS) {
+    ADD_FAILURE() << "Unable to perform synchronous IO while stopped";
+    return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
+  } else {
+    NET_TRACE(1, " *** ") << "Waiting for read to trigger write";
+    write_state_ = PENDING;
+  }
+
+  return MockWriteResult(SYNCHRONOUS, ERR_IO_PENDING);
+}
+
+void SequencedSocketData::Reset() {
+  helper_.Reset();
+  sequence_number_ = 0;
+  read_state_ = IDLE;
+  write_state_ = IDLE;
+  weak_factory_.InvalidateWeakPtrs();
+}
+
+bool SequencedSocketData::at_read_eof() {
+  return helper_.at_read_eof();
+}
+
+bool SequencedSocketData::at_write_eof() {
+  return helper_.at_read_eof();
+}
+
+void SequencedSocketData::MaybePostReadCompleteTask() {
+  NET_TRACE(1, " ****** ") << " current: " << sequence_number_;
+  // Only trigger the next read to complete if there is already a read pending
+  // which should complete at the current sequence number.
+  if (read_state_ != PENDING ||
+      helper_.PeekRead().sequence_number != sequence_number_) {
+    return;
+  }
+
+  NET_TRACE(1, " ****** ") << "Posting task to complete read: "
+                           << sequence_number_;
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE, base::Bind(&SequencedSocketData::OnReadComplete,
+                            weak_factory_.GetWeakPtr()));
+  CHECK_NE(COMPLETING, write_state_);
+  read_state_ = COMPLETING;
+}
+
+void SequencedSocketData::MaybePostWriteCompleteTask() {
+  NET_TRACE(1, " ****** ") << " current: " << sequence_number_;
+  // Only trigger the next write to complete if there is already a write pending
+  // which should complete at the current sequence number.
+  if (write_state_ != PENDING ||
+      helper_.PeekWrite().sequence_number != sequence_number_) {
+    return;
+  }
+
+  NET_TRACE(1, " ****** ") << "Posting task to complete write: "
+                           << sequence_number_;
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE, base::Bind(&SequencedSocketData::OnWriteComplete,
+                            weak_factory_.GetWeakPtr()));
+  CHECK_NE(COMPLETING, read_state_);
+  write_state_ = COMPLETING;
+}
+
+void SequencedSocketData::OnReadComplete() {
+  CHECK_EQ(COMPLETING, read_state_);
+  NET_TRACE(1, " *** ") << "Completing read for: " << sequence_number_;
+  if (!socket()) {
+    NET_TRACE(1, " *** ") << "No socket available to complete read";
+    return;
+  }
+
+  MockRead data = helper_.AdvanceRead();
+  DCHECK_EQ(sequence_number_, data.sequence_number);
+  sequence_number_++;
+  read_state_ = IDLE;
+
+  // The result of this read completing might trigger the completion
+  // of a pending write. If so, post a task to complete the write later.
+  // Since the socket may call back into the SequencedSocketData
+  // from socket()->OnReadComplete(), trigger the write task to be posted
+  // before calling that.
+  MaybePostWriteCompleteTask();
+
+  NET_TRACE(1, " *** ") << "Completing socket read for: " << sequence_number_;
+  DumpMockReadWrite(data);
+  socket()->OnReadComplete(data);
+  NET_TRACE(1, " *** ") << "Done";
+}
+
+void SequencedSocketData::OnWriteComplete() {
+  CHECK_EQ(COMPLETING, write_state_);
+  NET_TRACE(1, " *** ") << " Completing write for: " << sequence_number_;
+  if (!socket()) {
+    NET_TRACE(1, " *** ") << "No socket available to complete write.";
+    return;
+  }
+
+  const MockWrite& data = helper_.AdvanceWrite();
+  DCHECK_EQ(sequence_number_, data.sequence_number);
+  sequence_number_++;
+  write_state_ = IDLE;
+  int rv = data.result == OK ? data.data_len : data.result;
+
+  // The result of this write completing might trigger the completion
+  // of a pending read. If so, post a task to complete the read later.
+  // Since the socket may call back into the SequencedSocketData
+  // from socket()->OnWriteComplete(), trigger the write task to be posted
+  // before calling that.
+  MaybePostReadCompleteTask();
+
+  NET_TRACE(1, " *** ") << " Completing socket write for: " << sequence_number_;
+  socket()->OnWriteComplete(rv);
+  NET_TRACE(1, " *** ") << "Done";
+}
+
+SequencedSocketData::~SequencedSocketData() {
+}
+
 DeterministicSocketData::DeterministicSocketData(MockRead* reads,
     size_t reads_count, MockWrite* writes, size_t writes_count)
     : StaticSocketDataProvider(reads, reads_count, writes, writes_count),
@@ -824,8 +1064,8 @@
       read_data_(SYNCHRONOUS, ERR_UNEXPECTED),
       need_read_data_(true),
       peer_closed_connection_(false),
-      pending_buf_(NULL),
-      pending_buf_len_(0),
+      pending_read_buf_(NULL),
+      pending_read_buf_len_(0),
       was_used_to_convey_data_(false) {
   DCHECK(data_);
   peer_addr_ = data->connect_data().peer_addr;
@@ -840,12 +1080,12 @@
     return ERR_UNEXPECTED;
 
   // If the buffer is already in use, a read is already in progress!
-  DCHECK(pending_buf_.get() == NULL);
+  DCHECK(pending_read_buf_.get() == NULL);
 
   // Store our async IO data.
-  pending_buf_ = buf;
-  pending_buf_len_ = buf_len;
-  pending_callback_ = callback;
+  pending_read_buf_ = buf;
+  pending_read_buf_len_ = buf_len;
+  pending_read_callback_ = callback;
 
   if (need_read_data_) {
     read_data_ = data_->OnRead();
@@ -886,6 +1126,15 @@
 
   was_used_to_convey_data_ = true;
 
+  // ERR_IO_PENDING is a signal that the socket data will call back
+  // asynchronously later.
+  if (write_result.result == ERR_IO_PENDING) {
+    pending_write_callback_ = callback;
+    return ERR_IO_PENDING;
+  }
+
+  // TODO(rch): remove this once OrderedSocketData and DelayedSocketData
+  // have been removed.
   if (write_result.mode == ASYNC) {
     RunCallbackAsync(callback, write_result.result);
     return ERR_IO_PENDING;
@@ -901,7 +1150,7 @@
   peer_closed_connection_ = false;
   if (data_->connect_data().mode == ASYNC) {
     if (data_->connect_data().result == ERR_IO_PENDING)
-      pending_callback_ = callback;
+      pending_read_callback_ = callback;
     else
       RunCallbackAsync(callback, data_->connect_data().result);
     return ERR_IO_PENDING;
@@ -911,7 +1160,7 @@
 
 void MockTCPClientSocket::Disconnect() {
   MockClientSocket::Disconnect();
-  pending_callback_.Reset();
+  pending_read_callback_.Reset();
 }
 
 bool MockTCPClientSocket::IsConnected() const {
@@ -948,7 +1197,7 @@
 
 void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
   // There must be a read pending.
-  DCHECK(pending_buf_.get());
+  DCHECK(pending_read_buf_.get());
   // You can't complete a read with another ERR_IO_PENDING status code.
   DCHECK_NE(ERR_IO_PENDING, data.result);
   // Since we've been waiting for data, need_read_data_ should be true.
@@ -961,29 +1210,36 @@
   // let CompleteRead() schedule a callback.
   read_data_.mode = SYNCHRONOUS;
 
-  CompletionCallback callback = pending_callback_;
+  CompletionCallback callback = pending_read_callback_;
   int rv = CompleteRead();
   RunCallback(callback, rv);
 }
 
+void MockTCPClientSocket::OnWriteComplete(int rv) {
+  // There must be a read pending.
+  DCHECK(!pending_write_callback_.is_null());
+  CompletionCallback callback = pending_write_callback_;
+  RunCallback(callback, rv);
+}
+
 void MockTCPClientSocket::OnConnectComplete(const MockConnect& data) {
-  CompletionCallback callback = pending_callback_;
+  CompletionCallback callback = pending_read_callback_;
   RunCallback(callback, data.result);
 }
 
 int MockTCPClientSocket::CompleteRead() {
-  DCHECK(pending_buf_.get());
-  DCHECK(pending_buf_len_ > 0);
+  DCHECK(pending_read_buf_.get());
+  DCHECK(pending_read_buf_len_ > 0);
 
   was_used_to_convey_data_ = true;
 
   // Save the pending async IO data and reset our |pending_| state.
-  scoped_refptr<IOBuffer> buf = pending_buf_;
-  int buf_len = pending_buf_len_;
-  CompletionCallback callback = pending_callback_;
-  pending_buf_ = NULL;
-  pending_buf_len_ = 0;
-  pending_callback_.Reset();
+  scoped_refptr<IOBuffer> buf = pending_read_buf_;
+  int buf_len = pending_read_buf_len_;
+  CompletionCallback callback = pending_read_callback_;
+  pending_read_buf_ = NULL;
+  pending_read_buf_len_ = 0;
+  pending_read_callback_.Reset();
 
   int result = read_data_.result;
   DCHECK(result != ERR_IO_PENDING);
@@ -1202,6 +1458,9 @@
 
 void DeterministicMockUDPClientSocket::OnReadComplete(const MockRead& data) {}
 
+void DeterministicMockUDPClientSocket::OnWriteComplete(int rv) {
+}
+
 void DeterministicMockUDPClientSocket::OnConnectComplete(
     const MockConnect& data) {
   NOTIMPLEMENTED();
@@ -1296,6 +1555,9 @@
 
 void DeterministicMockTCPClientSocket::OnReadComplete(const MockRead& data) {}
 
+void DeterministicMockTCPClientSocket::OnWriteComplete(int rv) {
+}
+
 void DeterministicMockTCPClientSocket::OnConnectComplete(
     const MockConnect& data) {}
 
@@ -1445,6 +1707,10 @@
   NOTIMPLEMENTED();
 }
 
+void MockSSLClientSocket::OnWriteComplete(int rv) {
+  NOTIMPLEMENTED();
+}
+
 void MockSSLClientSocket::OnConnectComplete(const MockConnect& data) {
   NOTIMPLEMENTED();
 }
@@ -1457,8 +1723,8 @@
       read_data_(SYNCHRONOUS, ERR_UNEXPECTED),
       need_read_data_(true),
       source_port_(123),
-      pending_buf_(NULL),
-      pending_buf_len_(0),
+      pending_read_buf_(NULL),
+      pending_read_buf_len_(0),
       net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)),
       weak_factory_(this) {
   DCHECK(data_);
@@ -1475,12 +1741,12 @@
     return ERR_UNEXPECTED;
 
   // If the buffer is already in use, a read is already in progress!
-  DCHECK(pending_buf_.get() == NULL);
+  DCHECK(pending_read_buf_.get() == NULL);
 
   // Store our async IO data.
-  pending_buf_ = buf;
-  pending_buf_len_ = buf_len;
-  pending_callback_ = callback;
+  pending_read_buf_ = buf;
+  pending_read_buf_len_ = buf_len;
+  pending_read_callback_ = callback;
 
   if (need_read_data_) {
     read_data_ = data_->OnRead();
@@ -1508,6 +1774,12 @@
   std::string data(buf->data(), buf_len);
   MockWriteResult write_result = data_->OnWrite(data);
 
+  // ERR_IO_PENDING is a signal that the socket data will call back
+  // asynchronously.
+  if (write_result.result == ERR_IO_PENDING) {
+    pending_write_callback_ = callback;
+    return ERR_IO_PENDING;
+  }
   if (write_result.mode == ASYNC) {
     RunCallbackAsync(callback, write_result.result);
     return ERR_IO_PENDING;
@@ -1552,7 +1824,7 @@
 
 void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
   // There must be a read pending.
-  DCHECK(pending_buf_.get());
+  DCHECK(pending_read_buf_.get());
   // You can't complete a read with another ERR_IO_PENDING status code.
   DCHECK_NE(ERR_IO_PENDING, data.result);
   // Since we've been waiting for data, need_read_data_ should be true.
@@ -1565,26 +1837,33 @@
   // let CompleteRead() schedule a callback.
   read_data_.mode = SYNCHRONOUS;
 
-  net::CompletionCallback callback = pending_callback_;
+  net::CompletionCallback callback = pending_read_callback_;
   int rv = CompleteRead();
   RunCallback(callback, rv);
 }
 
+void MockUDPClientSocket::OnWriteComplete(int rv) {
+  // There must be a read pending.
+  DCHECK(!pending_write_callback_.is_null());
+  CompletionCallback callback = pending_write_callback_;
+  RunCallback(callback, rv);
+}
+
 void MockUDPClientSocket::OnConnectComplete(const MockConnect& data) {
   NOTIMPLEMENTED();
 }
 
 int MockUDPClientSocket::CompleteRead() {
-  DCHECK(pending_buf_.get());
-  DCHECK(pending_buf_len_ > 0);
+  DCHECK(pending_read_buf_.get());
+  DCHECK(pending_read_buf_len_ > 0);
 
   // Save the pending async IO data and reset our |pending_| state.
-  scoped_refptr<IOBuffer> buf = pending_buf_;
-  int buf_len = pending_buf_len_;
-  CompletionCallback callback = pending_callback_;
-  pending_buf_ = NULL;
-  pending_buf_len_ = 0;
-  pending_callback_.Reset();
+  scoped_refptr<IOBuffer> buf = pending_read_buf_;
+  int buf_len = pending_read_buf_len_;
+  CompletionCallback callback = pending_read_callback_;
+  pending_read_buf_ = NULL;
+  pending_read_buf_len_ = 0;
+  pending_read_callback_.Reset();
 
   int result = read_data_.result;
   DCHECK(result != ERR_IO_PENDING);
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 1d99619..4dad762 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -222,7 +222,13 @@
   // is called to complete the asynchronous read operation.
   // data.async is ignored, and this read is completed synchronously as
   // part of this call.
+  // TODO(rch): this should take a StringPiece since most of the fields
+  // are ignored.
   virtual void OnReadComplete(const MockRead& data) = 0;
+  // If an async IO is pending because the SocketDataProvider returned
+  // ERR_IO_PENDING, then the AsyncSocket waits until this OnReadComplete
+  // is called to complete the asynchronous read operation.
+  virtual void OnWriteComplete(int rv) = 0;
   virtual void OnConnectComplete(const MockConnect& data) = 0;
 };
 
@@ -247,6 +253,11 @@
   // Resets the read and write indexes to 0.
   void Reset();
 
+  // Returns true if |data| is valid data for the next write. In order
+  // to support short writes, the next write may be longer than |data|
+  // in which case this method will still return true.
+  bool VerifyWriteData(const std::string& data);
+
   size_t read_index() const { return read_index_; }
   size_t write_index() const { return write_index_; }
   size_t read_count() const { return read_count_; }
@@ -464,6 +475,63 @@
   DISALLOW_COPY_AND_ASSIGN(OrderedSocketData);
 };
 
+// Uses the sequence_number field in the mock reads and writes to
+// complete the operations in a specified order.
+class SequencedSocketData : public SocketDataProvider {
+ public:
+  // |reads| is the list of MockRead completions.
+  // |writes| is the list of MockWrite completions.
+  SequencedSocketData(MockRead* reads,
+                      size_t reads_count,
+                      MockWrite* writes,
+                      size_t writes_count);
+
+  // |connect| is the result for the connect phase.
+  // |reads| is the list of MockRead completions.
+  // |writes| is the list of MockWrite completions.
+  SequencedSocketData(const MockConnect& connect,
+                      MockRead* reads,
+                      size_t reads_count,
+                      MockWrite* writes,
+                      size_t writes_count);
+
+  ~SequencedSocketData() override;
+
+  // SocketDataProviderBase implementation.
+  MockRead OnRead() override;
+  MockWriteResult OnWrite(const std::string& data) override;
+  void Reset() override;
+
+  // Returns true if all data has been read.
+  bool at_read_eof();
+
+  // Returns true if all data has been written.
+  bool at_write_eof();
+
+ private:
+  // Defines the state for the read or write path.
+  enum IoState {
+    IDLE,        // No async operation is in progress.
+    PENDING,     // An async operation in waiting for another opteration to
+                 // complete.
+    COMPLETING,  // A task has been posted to complet an async operation.
+  };
+  void OnReadComplete();
+  void OnWriteComplete();
+
+  void MaybePostReadCompleteTask();
+  void MaybePostWriteCompleteTask();
+
+  StaticSocketDataHelper helper_;
+  int sequence_number_;
+  IoState read_state_;
+  IoState write_state_;
+
+  base::WeakPtrFactory<SequencedSocketData> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(SequencedSocketData);
+};
+
 class DeterministicMockTCPClientSocket;
 
 // This class gives the user full control over the network activity,
@@ -778,6 +846,7 @@
 
   // AsyncSocket:
   void OnReadComplete(const MockRead& data) override;
+  void OnWriteComplete(int rv) override;
   void OnConnectComplete(const MockConnect& data) override;
 
  private:
@@ -795,10 +864,11 @@
   // TCPClientSocket.
   bool peer_closed_connection_;
 
-  // While an asynchronous IO is pending, we save our user-buffer state.
-  scoped_refptr<IOBuffer> pending_buf_;
-  int pending_buf_len_;
-  CompletionCallback pending_callback_;
+  // While an asynchronous read is pending, we save our user-buffer state.
+  scoped_refptr<IOBuffer> pending_read_buf_;
+  int pending_read_buf_len_;
+  CompletionCallback pending_read_callback_;
+  CompletionCallback pending_write_callback_;
   bool was_used_to_convey_data_;
 
   DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocket);
@@ -888,6 +958,7 @@
 
   // AsyncSocket implementation.
   void OnReadComplete(const MockRead& data) override;
+  void OnWriteComplete(int rv) override;
   void OnConnectComplete(const MockConnect& data) override;
 
   void set_source_port(uint16 port) { source_port_ = port; }
@@ -938,6 +1009,7 @@
 
   // AsyncSocket:
   void OnReadComplete(const MockRead& data) override;
+  void OnWriteComplete(int rv) override;
   void OnConnectComplete(const MockConnect& data) override;
 
  private:
@@ -981,6 +1053,7 @@
 
   // This MockSocket does not implement the manual async IO feature.
   void OnReadComplete(const MockRead& data) override;
+  void OnWriteComplete(int rv) override;
   void OnConnectComplete(const MockConnect& data) override;
 
   bool WasChannelIDSent() const override;
@@ -1028,6 +1101,7 @@
 
   // AsyncSocket implementation.
   void OnReadComplete(const MockRead& data) override;
+  void OnWriteComplete(int rv) override;
   void OnConnectComplete(const MockConnect& data) override;
 
   void set_source_port(uint16 port) { source_port_ = port;}
@@ -1049,9 +1123,10 @@
   IPEndPoint peer_addr_;
 
   // While an asynchronous IO is pending, we save our user-buffer state.
-  scoped_refptr<IOBuffer> pending_buf_;
-  int pending_buf_len_;
-  CompletionCallback pending_callback_;
+  scoped_refptr<IOBuffer> pending_read_buf_;
+  int pending_read_buf_len_;
+  CompletionCallback pending_read_callback_;
+  CompletionCallback pending_write_callback_;
 
   BoundNetLog net_log_;
 
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index e36534c..7b11ddc 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -1196,6 +1196,8 @@
                 << GetLastError();
       }
 #else
+      // TODO(davidben): Support OCSP stapling when NSS is the system
+      // certificate verifier. https://crbug.com/479034.
       NOTREACHED();
 #endif
     }
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index a41903e..9267abd5 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -2106,7 +2106,7 @@
 
   TestCompletionCallback callback;
   TestNetLog log;
-  log.SetLogLevel(NetLog::LOG_ALL);
+  log.SetCaptureMode(NetLogCaptureMode::IncludeSocketBytes());
   scoped_ptr<StreamSocket> transport(
       new TCPClientSocket(addr, &log, NetLog::Source()));
   int rv = transport->Connect(callback.callback());
diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc
index 2620eba..a7cc7d8 100644
--- a/net/socket/tcp_socket_win.cc
+++ b/net/socket/tcp_socket_win.cc
@@ -801,30 +801,25 @@
     result = connect(socket_, storage.addr, storage.addr_len);
   }
 
-  if (!result) {
-    // Connected without waiting!
-    //
-    // The MSDN page for connect says:
-    //   With a nonblocking socket, the connection attempt cannot be completed
-    //   immediately. In this case, connect will return SOCKET_ERROR, and
-    //   WSAGetLastError will return WSAEWOULDBLOCK.
-    // which implies that for a nonblocking socket, connect never returns 0.
-    // It's not documented whether the event object will be signaled or not
-    // if connect does return 0.  So the code below is essentially dead code
-    // and we don't know if it's correct.
-    NOTREACHED();
+  // The MSDN page for connect says:
+  //   With a nonblocking socket, the connection attempt cannot be completed
+  //   immediately. In this case, connect will return SOCKET_ERROR, and
+  //   WSAGetLastError will return WSAEWOULDBLOCK.
+  // which implies that for a nonblocking socket, connect never returns 0.
+  // It's not clear what the correct thing to do is if connect()
+  // returns 0. It's not clear whether this ever happens in practice.
+  // This CHECK() is here to verify that it doesn't.
+  // TODO(ricea): If the CHECK() fires in canary or dev, revert this
+  // CL. If it doesn't, reconsider what we want to do here long-term.
+  CHECK(result);
 
-    if (ResetEventIfSignaled(core_->read_overlapped_.hEvent))
-      return OK;
-  } else {
-    int os_error = WSAGetLastError();
-    if (os_error != WSAEWOULDBLOCK) {
-      LOG(ERROR) << "connect failed: " << os_error;
-      connect_os_error_ = os_error;
-      int rv = MapConnectError(os_error);
-      CHECK_NE(ERR_IO_PENDING, rv);
-      return rv;
-    }
+  int os_error = WSAGetLastError();
+  if (os_error != WSAEWOULDBLOCK) {
+    LOG(ERROR) << "connect failed: " << os_error;
+    connect_os_error_ = os_error;
+    int rv = MapConnectError(os_error);
+    CHECK_NE(ERR_IO_PENDING, rv);
+    return rv;
   }
 
   // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed.
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index eac2868..5263e70 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -481,7 +481,7 @@
 void TransportClientSocketPool::NetLogTcpClientSocketPoolRequestedSocket(
     const BoundNetLog& net_log,
     const scoped_refptr<TransportSocketParams>* casted_params) {
-  if (net_log.IsLogging()) {
+  if (net_log.GetCaptureMode().enabled()) {
     // TODO(eroman): Split out the host and port parameters.
     net_log.AddEvent(
         NetLog::TYPE_TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
@@ -498,7 +498,7 @@
   const scoped_refptr<TransportSocketParams>* casted_params =
       static_cast<const scoped_refptr<TransportSocketParams>*>(params);
 
-  if (net_log.IsLogging()) {
+  if (net_log.GetCaptureMode().enabled()) {
     // TODO(eroman): Split out the host and port parameters.
     net_log.AddEvent(
         NetLog::TYPE_TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKETS,
diff --git a/net/spdy/spdy_header_block.cc b/net/spdy/spdy_header_block.cc
index bbe9c716..92c6234b 100644
--- a/net/spdy/spdy_header_block.cc
+++ b/net/spdy/spdy_header_block.cc
@@ -9,17 +9,15 @@
 
 namespace net {
 
-base::Value* SpdyHeaderBlockNetLogCallback(
-    const SpdyHeaderBlock* headers,
-    NetLog::LogLevel log_level) {
+base::Value* SpdyHeaderBlockNetLogCallback(const SpdyHeaderBlock* headers,
+                                           NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::DictionaryValue* headers_dict = new base::DictionaryValue();
   for (SpdyHeaderBlock::const_iterator it = headers->begin();
        it != headers->end(); ++it) {
     headers_dict->SetWithoutPathExpansion(
-        it->first,
-        new base::StringValue(
-            ElideHeaderValueForNetLog(log_level, it->first, it->second)));
+        it->first, new base::StringValue(ElideHeaderValueForNetLog(
+                       capture_mode, it->first, it->second)));
   }
   dict->Set("headers", headers_dict);
   return dict;
diff --git a/net/spdy/spdy_header_block.h b/net/spdy/spdy_header_block.h
index 7d2a075..b496642 100644
--- a/net/spdy/spdy_header_block.h
+++ b/net/spdy/spdy_header_block.h
@@ -21,7 +21,7 @@
 // ownership of returned value.
 NET_EXPORT base::Value* SpdyHeaderBlockNetLogCallback(
     const SpdyHeaderBlock* headers,
-    NetLog::LogLevel log_level);
+    NetLogCaptureMode capture_mode);
 
 // Converts NetLog event parameters into a SPDY header block and writes them
 // to |headers|.  |event_param| must have been created by
diff --git a/net/spdy/spdy_header_block_unittest.cc b/net/spdy/spdy_header_block_unittest.cc
index b69f37c..99e9ac21 100644
--- a/net/spdy/spdy_header_block_unittest.cc
+++ b/net/spdy/spdy_header_block_unittest.cc
@@ -18,8 +18,8 @@
   headers["A"] = "a";
   headers["B"] = "b";
 
-  scoped_ptr<base::Value> event_param(
-      SpdyHeaderBlockNetLogCallback(&headers, NetLog::LOG_ALL_BUT_BYTES));
+  scoped_ptr<base::Value> event_param(SpdyHeaderBlockNetLogCallback(
+      &headers, NetLogCaptureMode::IncludeCookiesAndCredentials()));
 
   SpdyHeaderBlock headers2;
   ASSERT_TRUE(SpdyHeaderBlockFromNetLogParam(event_param.get(), &headers2));
diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc
index 55f5b36..6fecf457 100644
--- a/net/spdy/spdy_http_stream_unittest.cc
+++ b/net/spdy/spdy_http_stream_unittest.cc
@@ -126,7 +126,7 @@
     MockRead(ASYNC, 0, 0)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), NULL, 0, key);
@@ -151,14 +151,14 @@
       CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   TestCompletionCallback callback;
   HttpResponseInfo response;
   HttpRequestHeaders headers;
@@ -224,14 +224,14 @@
     MockRead(ASYNC, 0, 6)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
 
   HttpRequestInfo request1;
   request1.method = "GET";
-  request1.url = GURL("http://www.google.com/");
+  request1.url = GURL("http://www.example.org/");
   TestCompletionCallback callback1;
   HttpResponseInfo response1;
   HttpRequestHeaders headers1;
@@ -239,7 +239,7 @@
 
   HttpRequestInfo request2;
   request2.method = "GET";
-  request2.url = GURL("http://www.google.com/");
+  request2.url = GURL("http://www.example.org/");
   TestCompletionCallback callback2;
   HttpResponseInfo response2;
   HttpRequestHeaders headers2;
@@ -311,7 +311,7 @@
   reads.push_back(CreateMockRead(*body, seq++));
   reads.push_back(MockRead(SYNCHRONOUS, 0, seq++));  // EOF
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(vector_as_array(&reads), reads.size(), vector_as_array(&writes),
@@ -326,7 +326,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.upload_data_stream = &upload_stream;
 
   ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
@@ -381,7 +381,7 @@
     MockRead(ASYNC, 0, 8)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
@@ -390,7 +390,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.upload_data_stream = &upload_stream;
 
   ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
@@ -478,7 +478,7 @@
     MockRead(ASYNC, 0, 6)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
@@ -487,7 +487,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.upload_data_stream = &upload_stream;
 
   ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
@@ -561,7 +561,7 @@
     MockRead(ASYNC, 0, 4)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
@@ -570,7 +570,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.upload_data_stream = &upload_stream;
 
   ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
@@ -616,8 +616,8 @@
 
 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
 TEST_P(SpdyHttpStreamTest, SpdyURLTest) {
-  const char * const full_url = "http://www.google.com/foo?query=what#anchor";
-  const char * const base_url = "http://www.google.com/foo?query=what";
+  const char* const full_url = "http://www.example.org/foo?query=what#anchor";
+  const char* const base_url = "http://www.example.org/foo?query=what";
   scoped_ptr<SpdyFrame> req(
       spdy_util_.ConstructSpdyGet(base_url, false, 1, LOWEST));
   MockWrite writes[] = {
@@ -628,7 +628,7 @@
       CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
   InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
@@ -681,7 +681,7 @@
     MockRead(ASYNC, 0, 5)  // EOF
   };
 
-  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortPair host_port_pair("www.example.org", 80);
   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
                      PRIVACY_MODE_DISABLED);
 
@@ -691,7 +691,7 @@
 
   HttpRequestInfo request;
   request.method = "POST";
-  request.url = GURL("http://www.google.com/");
+  request.url = GURL("http://www.example.org/");
   request.upload_data_stream = &upload_stream;
 
   ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index e8d8e0b5..aad489b 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -18,6 +18,7 @@
 #include "net/base/chunked_upload_data_stream.h"
 #include "net/base/elements_upload_data_stream.h"
 #include "net/base/request_priority.h"
+#include "net/base/test_data_directory.h"
 #include "net/base/upload_bytes_element_reader.h"
 #include "net/base/upload_file_element_reader.h"
 #include "net/http/http_network_session_peer.h"
@@ -35,6 +36,7 @@
 #include "net/spdy/spdy_test_util_common.h"
 #include "net/spdy/spdy_test_utils.h"
 #include "net/ssl/ssl_connection_status_flags.h"
+#include "net/test/cert_test_util.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/platform_test.h"
@@ -92,9 +94,9 @@
   session_deps->next_protos = SpdyNextProtos();
   if (test_params.ssl_type == HTTP_SPDY_VIA_ALT_SVC) {
     session_deps->http_server_properties.SetAlternativeService(
-        HostPortPair("www.google.com", 80),
+        HostPortPair("www.example.org", 80),
         AlternativeService(AlternateProtocolFromNextProto(test_params.protocol),
-                           "www.google.com", 443),
+                           "www.example.org", 443),
         1);
   }
 }
@@ -133,9 +135,9 @@
   }
 
   void SetUp() override {
-    google_get_request_initialized_ = false;
-    google_post_request_initialized_ = false;
-    google_chunked_post_request_initialized_ = false;
+    get_request_initialized_ = false;
+    post_request_initialized_ = false;
+    chunked_post_request_initialized_ = false;
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
   }
 
@@ -313,6 +315,8 @@
     void AddData(StaticSocketDataProvider* data) {
       scoped_ptr<SSLSocketDataProvider> ssl_provider(
           new SSLSocketDataProvider(ASYNC, OK));
+      ssl_provider->cert =
+          ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
       AddDataWithSSLSocketDataProvider(data, ssl_provider.Pass());
     }
 
@@ -348,6 +352,8 @@
       SSLSocketDataProvider* ssl_provider =
           new SSLSocketDataProvider(ASYNC, OK);
       ssl_provider->SetNextProto(test_params_.protocol);
+      ssl_provider->cert =
+          ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
       ssl_vector_.push_back(ssl_provider);
       session_deps_->deterministic_socket_factory->AddSSLSocketDataProvider(
           ssl_provider);
@@ -413,51 +419,51 @@
   void ConnectStatusHelper(const MockRead& status);
 
   const HttpRequestInfo& CreateGetPushRequest() {
-    google_get_push_request_.method = "GET";
-    google_get_push_request_.url = GURL(GetDefaultUrlWithPath("/foo.dat"));
-    google_get_push_request_.load_flags = 0;
-    return google_get_push_request_;
+    get_push_request_.method = "GET";
+    get_push_request_.url = GURL(GetDefaultUrlWithPath("/foo.dat"));
+    get_push_request_.load_flags = 0;
+    return get_push_request_;
   }
 
   const HttpRequestInfo& CreateGetRequest() {
-    if (!google_get_request_initialized_) {
-      google_get_request_.method = "GET";
-      google_get_request_.url = GURL(GetDefaultUrl());
-      google_get_request_.load_flags = 0;
-      google_get_request_initialized_ = true;
+    if (!get_request_initialized_) {
+      get_request_.method = "GET";
+      get_request_.url = GURL(GetDefaultUrl());
+      get_request_.load_flags = 0;
+      get_request_initialized_ = true;
     }
-    return google_get_request_;
+    return get_request_;
   }
 
   const HttpRequestInfo& CreateGetRequestWithUserAgent() {
-    if (!google_get_request_initialized_) {
-      google_get_request_.method = "GET";
-      google_get_request_.url = GURL(GetDefaultUrl());
-      google_get_request_.load_flags = 0;
-      google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
-      google_get_request_initialized_ = true;
+    if (!get_request_initialized_) {
+      get_request_.method = "GET";
+      get_request_.url = GURL(GetDefaultUrl());
+      get_request_.load_flags = 0;
+      get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
+      get_request_initialized_ = true;
     }
-    return google_get_request_;
+    return get_request_;
   }
 
   const HttpRequestInfo& CreatePostRequest() {
-    if (!google_post_request_initialized_) {
+    if (!post_request_initialized_) {
       ScopedVector<UploadElementReader> element_readers;
       element_readers.push_back(
           new UploadBytesElementReader(kUploadData, kUploadDataSize));
       upload_data_stream_.reset(
           new ElementsUploadDataStream(element_readers.Pass(), 0));
 
-      google_post_request_.method = "POST";
-      google_post_request_.url = GURL(GetDefaultUrl());
-      google_post_request_.upload_data_stream = upload_data_stream_.get();
-      google_post_request_initialized_ = true;
+      post_request_.method = "POST";
+      post_request_.url = GURL(GetDefaultUrl());
+      post_request_.upload_data_stream = upload_data_stream_.get();
+      post_request_initialized_ = true;
     }
-    return google_post_request_;
+    return post_request_;
   }
 
   const HttpRequestInfo& CreateFilePostRequest() {
-    if (!google_post_request_initialized_) {
+    if (!post_request_initialized_) {
       base::FilePath file_path;
       CHECK(base::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
       CHECK_EQ(static_cast<int>(kUploadDataSize),
@@ -473,17 +479,17 @@
       upload_data_stream_.reset(
           new ElementsUploadDataStream(element_readers.Pass(), 0));
 
-      google_post_request_.method = "POST";
-      google_post_request_.url = GURL(GetDefaultUrl());
-      google_post_request_.upload_data_stream = upload_data_stream_.get();
-      google_post_request_initialized_ = true;
+      post_request_.method = "POST";
+      post_request_.url = GURL(GetDefaultUrl());
+      post_request_.upload_data_stream = upload_data_stream_.get();
+      post_request_initialized_ = true;
     }
-    return google_post_request_;
+    return post_request_;
   }
 
   const HttpRequestInfo& CreateUnreadableFilePostRequest() {
-    if (google_post_request_initialized_)
-      return google_post_request_;
+    if (post_request_initialized_)
+      return post_request_;
 
     base::FilePath file_path;
     CHECK(base::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
@@ -501,15 +507,15 @@
     upload_data_stream_.reset(
         new ElementsUploadDataStream(element_readers.Pass(), 0));
 
-    google_post_request_.method = "POST";
-    google_post_request_.url = GURL(GetDefaultUrl());
-    google_post_request_.upload_data_stream = upload_data_stream_.get();
-    google_post_request_initialized_ = true;
-    return google_post_request_;
+    post_request_.method = "POST";
+    post_request_.url = GURL(GetDefaultUrl());
+    post_request_.upload_data_stream = upload_data_stream_.get();
+    post_request_initialized_ = true;
+    return post_request_;
   }
 
   const HttpRequestInfo& CreateComplexPostRequest() {
-    if (!google_post_request_initialized_) {
+    if (!post_request_initialized_) {
       const int kFileRangeOffset = 1;
       const int kFileRangeLength = 3;
       CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
@@ -534,24 +540,24 @@
       upload_data_stream_.reset(
           new ElementsUploadDataStream(element_readers.Pass(), 0));
 
-      google_post_request_.method = "POST";
-      google_post_request_.url = GURL(GetDefaultUrl());
-      google_post_request_.upload_data_stream = upload_data_stream_.get();
-      google_post_request_initialized_ = true;
+      post_request_.method = "POST";
+      post_request_.url = GURL(GetDefaultUrl());
+      post_request_.upload_data_stream = upload_data_stream_.get();
+      post_request_initialized_ = true;
     }
-    return google_post_request_;
+    return post_request_;
   }
 
   const HttpRequestInfo& CreateChunkedPostRequest() {
-    if (!google_chunked_post_request_initialized_) {
+    if (!chunked_post_request_initialized_) {
       upload_chunked_data_stream_.reset(new ChunkedUploadDataStream(0));
-      google_chunked_post_request_.method = "POST";
-      google_chunked_post_request_.url = GURL(GetDefaultUrl());
-      google_chunked_post_request_.upload_data_stream =
+      chunked_post_request_.method = "POST";
+      chunked_post_request_.url = GURL(GetDefaultUrl());
+      chunked_post_request_.upload_data_stream =
           upload_chunked_data_stream_.get();
-      google_chunked_post_request_initialized_ = true;
+      chunked_post_request_initialized_ = true;
     }
-    return google_chunked_post_request_;
+    return chunked_post_request_;
   }
 
   // Read the result of a particular transaction, knowing that we've got
@@ -684,9 +690,9 @@
   const char* GetDefaultUrl() {
     switch (GetParam().ssl_type) {
       case HTTP_SPDY_VIA_ALT_SVC:
-        return "http://www.google.com";
+        return "http://www.example.org";
       case HTTPS_SPDY_VIA_NPN:
-        return "https://www.google.com";
+        return "https://www.example.org";
       default:
         NOTREACHED();
         return "";
@@ -702,13 +708,13 @@
  private:
   scoped_ptr<ChunkedUploadDataStream> upload_chunked_data_stream_;
   scoped_ptr<UploadDataStream> upload_data_stream_;
-  bool google_get_request_initialized_;
-  bool google_post_request_initialized_;
-  bool google_chunked_post_request_initialized_;
-  HttpRequestInfo google_get_request_;
-  HttpRequestInfo google_post_request_;
-  HttpRequestInfo google_chunked_post_request_;
-  HttpRequestInfo google_get_push_request_;
+  bool get_request_initialized_;
+  bool post_request_initialized_;
+  bool chunked_post_request_initialized_;
+  HttpRequestInfo get_request_;
+  HttpRequestInfo post_request_;
+  HttpRequestInfo chunked_post_request_;
+  HttpRequestInfo get_push_request_;
   base::ScopedTempDir temp_dir_;
 };
 
@@ -2414,7 +2420,7 @@
   helper.VerifyDataConsumed();
 }
 
-// Send a spdy request to www.google.com that gets redirected to www.foo.com.
+// Send a spdy request to www.example.org that gets redirected to www.foo.com.
 TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) {
   scoped_ptr<SpdyHeaderBlock> headers(
       spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl()));
@@ -2425,7 +2431,7 @@
   (*headers2)["user-agent"] = "";
   (*headers2)["accept-encoding"] = "gzip, deflate";
 
-  // Setup writes/reads to www.google.com
+  // Setup writes/reads to www.example.org
   scoped_ptr<SpdyFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
   scoped_ptr<SpdyFrame> req2(
@@ -2486,7 +2492,7 @@
   EXPECT_TRUE(data2.at_write_eof());
 }
 
-// Send a spdy request to www.google.com. Get a pushed stream that redirects to
+// Send a spdy request to www.example.org. Get a pushed stream that redirects to
 // www.foo.com.
 TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) {
   scoped_ptr<SpdyHeaderBlock> headers(
@@ -2494,7 +2500,7 @@
   (*headers)["user-agent"] = "";
   (*headers)["accept-encoding"] = "gzip, deflate";
 
-  // Setup writes/reads to www.google.com
+  // Setup writes/reads to www.example.org
   scoped_ptr<SpdyFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -3705,7 +3711,8 @@
   ASSERT_TRUE(entries[pos].params->GetList("headers", &header_list));
 
   std::vector<std::string> expected;
-  expected.push_back(std::string(spdy_util_.GetHostKey()) + ": www.google.com");
+  expected.push_back(std::string(spdy_util_.GetHostKey()) +
+                     ": www.example.org");
   expected.push_back(std::string(spdy_util_.GetPathKey()) + ": /");
   expected.push_back(std::string(spdy_util_.GetSchemeKey()) + ": " +
                      spdy_util_.default_url().scheme());
@@ -4189,7 +4196,7 @@
   helper.RunPreTestSetup();
 
   // Verify that no settings exist initially.
-  HostPortPair host_port_pair("www.google.com", helper.port());
+  HostPortPair host_port_pair("www.example.org", helper.port());
   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
   EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
       host_port_pair).empty());
@@ -4302,7 +4309,7 @@
   pool_peer.SetEnableSendingInitialData(true);
 
   // Verify that no settings exist initially.
-  HostPortPair host_port_pair("www.google.com", helper.port());
+  HostPortPair host_port_pair("www.example.org", helper.port());
   EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
       host_port_pair).empty());
 
@@ -4498,7 +4505,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL(GetDefaultUrl());
+  request.url = GURL("https://www.example.org/");
   scoped_ptr<SpdySessionDependencies> session_deps(
       CreateSpdySessionDependencies(GetParam()));
   // Do not force SPDY so that second socket can negotiate HTTP/1.1.
@@ -4532,7 +4539,7 @@
   // Second socket: falling back to HTTP/1.1.
   MockWrite writes1[] = {MockWrite(
       "GET / HTTP/1.1\r\n"
-      "Host: www.google.com\r\n"
+      "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n")};
   MockRead reads1[] = {MockRead(
       "HTTP/1.1 200 OK\r\n"
@@ -4589,7 +4596,7 @@
 
   HttpRequestInfo request;
   request.method = "GET";
-  request.url = GURL("https://www.google.com/");
+  request.url = GURL("https://www.example.org/");
   scoped_ptr<SpdySessionDependencies> session_deps(
       CreateSpdySessionDependencies(
           GetParam(),
@@ -4601,7 +4608,7 @@
 
   // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
-      nullptr, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+      nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   MockWrite writes0[] = {CreateMockWrite(*req)};
   scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please."));
@@ -4623,12 +4630,12 @@
   // Second socket: retry using HTTP/1.1.
   MockWrite writes1[] = {
       MockWrite(ASYNC, 1,
-                "CONNECT www.google.com:443 HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
+                "CONNECT www.example.org:443 HTTP/1.1\r\n"
+                "Host: www.example.org\r\n"
                 "Proxy-Connection: keep-alive\r\n\r\n"),
       MockWrite(ASYNC, 3,
                 "GET / HTTP/1.1\r\n"
-                "Host: www.google.com\r\n"
+                "Host: www.example.org\r\n"
                 "Connection: keep-alive\r\n\r\n"),
   };
 
@@ -4695,8 +4702,8 @@
   HttpNetworkTransaction* trans = helper.trans();
 
   const char kConnect443[] = {
-      "CONNECT www.google.com:443 HTTP/1.1\r\n"
-      "Host: www.google.com\r\n"
+      "CONNECT www.example.org:443 HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
       "Proxy-Connection: keep-alive\r\n\r\n"};
   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
   scoped_ptr<SpdyFrame> req(
@@ -4738,9 +4745,9 @@
   helper.VerifyDataConsumed();
 }
 
-// Test to make sure we can correctly connect through a proxy to www.google.com,
-// if there already exists a direct spdy connection to www.google.com. See
-// http://crbug.com/49874
+// Test to make sure we can correctly connect through a proxy to
+// www.example.org, if there already exists a direct spdy connection to
+// www.example.org. See https://crbug.com/49874.
 TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
   // When setting up the first transaction, we store the SpdySessionPool so that
   // we can use the same pool in the second transaction.
@@ -4799,7 +4806,7 @@
   EXPECT_EQ("hello!", out.response_data);
 
   // Check that the SpdySession is still in the SpdySessionPool.
-  HostPortPair host_port_pair("www.google.com", helper.port());
+  HostPortPair host_port_pair("www.example.org", helper.port());
   SpdySessionKey session_pool_key_direct(
       host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct));
@@ -4810,9 +4817,10 @@
   EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy));
 
   // Set up data for the proxy connection.
-  const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
-                           "Host: www.google.com\r\n"
-                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kConnect443[] = {
+      "CONNECT www.example.org:443 HTTP/1.1\r\n"
+      "Host: www.example.org\r\n"
+      "Proxy-Connection: keep-alive\r\n\r\n"};
   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyGet(
       GetDefaultUrlWithPath("/foo.dat").c_str(), false, 1, LOWEST));
@@ -4833,7 +4841,7 @@
   scoped_ptr<OrderedSocketData> data_proxy(new OrderedSocketData(
       reads2, arraysize(reads2), writes2, arraysize(writes2)));
 
-  // Create another request to www.google.com, but this time through a proxy.
+  // Create another request to www.example.org, but this time through a proxy.
   HttpRequestInfo request_proxy;
   request_proxy.method = "GET";
   request_proxy.url = GURL(GetDefaultUrlWithPath("/foo.dat"));
@@ -5616,19 +5624,19 @@
 
   // A list of the URL to fetch, followed by the URL being pushed.
   static const char* const kTestCases[] = {
-      "https://www.google.com/foo.html",
-      "https://www.google.com:81/foo.js",  // Bad port
+      "https://www.example.org/foo.html",
+      "https://www.example.org:81/foo.js",  // Bad port
 
-      "https://www.google.com/foo.html",
-      "http://www.google.com/foo.js",  // Bad protocol
+      "https://www.example.org/foo.html",
+      "http://www.example.org/foo.js",  // Bad protocol
 
-      "https://www.google.com/foo.html",
-      "ftp://www.google.com/foo.js",  // Invalid Protocol
+      "https://www.example.org/foo.html",
+      "ftp://www.example.org/foo.js",  // Invalid Protocol
 
-      "https://www.google.com/foo.html",
-      "https://blat.www.google.com/foo.js",  // Cross subdomain
+      "https://www.example.org/foo.html",
+      "https://blat.www.example.org/foo.js",  // Cross subdomain
 
-      "https://www.google.com/foo.html",
+      "https://www.example.org/foo.html",
       "https://www.foo.com/foo.js",  // Cross domain
   };
 
@@ -6536,7 +6544,7 @@
     return;
 
   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
-  spdy_util_.AddUrlToHeaderBlock("http://www.google.com/a.dat",
+  spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat",
                                  push_headers.get());
   scoped_ptr<SpdyFrame> push(
       spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 3, 1));
@@ -6612,7 +6620,7 @@
         1, reads, arraysize(reads), writes, arraysize(writes));
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("https://www.google.com/");
+    request.url = GURL("https://www.example.org/");
     NormalSpdyTransactionHelper helper(
         request, DEFAULT_PRIORITY, BoundNetLog(), GetParam(), NULL);
     helper.RunToCompletionWithSSLData(&data, ssl_provider.Pass());
@@ -6664,7 +6672,7 @@
     DelayedSocketData data(1, NULL, 0, writes, arraysize(writes));
     HttpRequestInfo request;
     request.method = "GET";
-    request.url = GURL("https://www.google.com/");
+    request.url = GURL("https://www.example.org/");
     NormalSpdyTransactionHelper helper(
         request, DEFAULT_PRIORITY, BoundNetLog(), GetParam(), NULL);
     helper.RunToCompletionWithSSLData(&data, ssl_provider.Pass());
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 2f8af1e..e25a88c 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -59,13 +59,13 @@
 
 scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue(
     const SpdyHeaderBlock& headers,
-    net::NetLog::LogLevel log_level) {
+    net::NetLogCaptureMode capture_mode) {
   scoped_ptr<base::ListValue> headers_list(new base::ListValue());
   for (SpdyHeaderBlock::const_iterator it = headers.begin();
        it != headers.end(); ++it) {
     headers_list->AppendString(
         it->first + ": " +
-        ElideHeaderValueForNetLog(log_level, it->first, it->second));
+        ElideHeaderValueForNetLog(capture_mode, it->first, it->second));
   }
   return headers_list.Pass();
 }
@@ -75,10 +75,10 @@
                                              bool unidirectional,
                                              SpdyPriority spdy_priority,
                                              SpdyStreamId stream_id,
-                                             NetLog::LogLevel log_level) {
+                                             NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->Set("headers",
-            SpdyHeaderBlockToListValue(*headers, log_level).release());
+            SpdyHeaderBlockToListValue(*headers, capture_mode).release());
   dict->SetBoolean("fin", fin);
   dict->SetBoolean("unidirectional", unidirectional);
   dict->SetInteger("priority", static_cast<int>(spdy_priority));
@@ -93,10 +93,10 @@
     SpdyPriority spdy_priority,
     SpdyStreamId stream_id,
     SpdyStreamId associated_stream,
-    NetLog::LogLevel log_level) {
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->Set("headers",
-            SpdyHeaderBlockToListValue(*headers, log_level).release());
+            SpdyHeaderBlockToListValue(*headers, capture_mode).release());
   dict->SetBoolean("fin", fin);
   dict->SetBoolean("unidirectional", unidirectional);
   dict->SetInteger("priority", static_cast<int>(spdy_priority));
@@ -109,18 +109,19 @@
     const SpdyHeaderBlock* headers,
     bool fin,
     SpdyStreamId stream_id,
-    NetLog::LogLevel log_level) {
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->Set("headers",
-            SpdyHeaderBlockToListValue(*headers, log_level).release());
+            SpdyHeaderBlockToListValue(*headers, capture_mode).release());
   dict->SetBoolean("fin", fin);
   dict->SetInteger("stream_id", stream_id);
   return dict;
 }
 
-base::Value* NetLogSpdySessionCloseCallback(int net_error,
-                                            const std::string* description,
-                                            NetLog::LogLevel /* log_level */) {
+base::Value* NetLogSpdySessionCloseCallback(
+    int net_error,
+    const std::string* description,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("net_error", net_error);
   dict->SetString("description", *description);
@@ -128,16 +129,17 @@
 }
 
 base::Value* NetLogSpdySessionCallback(const HostPortProxyPair* host_pair,
-                                       NetLog::LogLevel /* log_level */) {
+                                       NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("host", host_pair->first.ToString());
   dict->SetString("proxy", host_pair->second.ToPacString());
   return dict;
 }
 
-base::Value* NetLogSpdyInitializedCallback(NetLog::Source source,
-                                           const NextProto protocol_version,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* NetLogSpdyInitializedCallback(
+    NetLog::Source source,
+    const NextProto protocol_version,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   if (source.IsValid()) {
     source.AddToEventParameters(dict);
@@ -149,7 +151,7 @@
 
 base::Value* NetLogSpdySettingsCallback(const HostPortPair& host_port_pair,
                                         bool clear_persisted,
-                                        NetLog::LogLevel /* log_level */) {
+                                        NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("host", host_port_pair.ToString());
   dict->SetBoolean("clear_persisted", clear_persisted);
@@ -160,7 +162,7 @@
                                        const SpdyMajorVersion protocol_version,
                                        SpdySettingsFlags flags,
                                        uint32 value,
-                                       NetLog::LogLevel /* log_level */) {
+                                       NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("id",
                    SpdyConstants::SerializeSettingId(protocol_version, id));
@@ -172,7 +174,7 @@
 base::Value* NetLogSpdySendSettingsCallback(
     const SettingsMap* settings,
     const SpdyMajorVersion protocol_version,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   base::ListValue* settings_list = new base::ListValue();
   for (SettingsMap::const_iterator it = settings->begin();
@@ -193,7 +195,7 @@
 base::Value* NetLogSpdyWindowUpdateFrameCallback(
     SpdyStreamId stream_id,
     uint32 delta,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", static_cast<int>(stream_id));
   dict->SetInteger("delta", delta);
@@ -203,7 +205,7 @@
 base::Value* NetLogSpdySessionWindowUpdateCallback(
     int32 delta,
     int32 window_size,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("delta", delta);
   dict->SetInteger("window_size", window_size);
@@ -213,7 +215,7 @@
 base::Value* NetLogSpdyDataCallback(SpdyStreamId stream_id,
                                     int size,
                                     bool fin,
-                                    NetLog::LogLevel /* log_level */) {
+                                    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", static_cast<int>(stream_id));
   dict->SetInteger("size", size);
@@ -224,7 +226,7 @@
 base::Value* NetLogSpdyRstCallback(SpdyStreamId stream_id,
                                    int status,
                                    const std::string* description,
-                                   NetLog::LogLevel /* log_level */) {
+                                   NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", static_cast<int>(stream_id));
   dict->SetInteger("status", status);
@@ -235,7 +237,7 @@
 base::Value* NetLogSpdyPingCallback(SpdyPingId unique_id,
                                     bool is_ack,
                                     const char* type,
-                                    NetLog::LogLevel /* log_level */) {
+                                    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("unique_id", static_cast<int>(unique_id));
   dict->SetString("type", type);
@@ -247,7 +249,7 @@
                                       int active_streams,
                                       int unclaimed_streams,
                                       SpdyGoAwayStatus status,
-                                      NetLog::LogLevel /* log_level */) {
+                                      NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("last_accepted_stream_id",
                    static_cast<int>(last_stream_id));
@@ -261,17 +263,19 @@
     const SpdyHeaderBlock* headers,
     SpdyStreamId stream_id,
     SpdyStreamId promised_stream_id,
-    NetLog::LogLevel log_level) {
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->Set("headers",
-            SpdyHeaderBlockToListValue(*headers, log_level).release());
+            SpdyHeaderBlockToListValue(*headers, capture_mode).release());
   dict->SetInteger("id", stream_id);
   dict->SetInteger("promised_stream_id", promised_stream_id);
   return dict;
 }
 
 base::Value* NetLogSpdyAdoptedPushStreamCallback(
-    SpdyStreamId stream_id, const GURL* url, NetLog::LogLevel log_level) {
+    SpdyStreamId stream_id,
+    const GURL* url,
+    NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", stream_id);
   dict->SetString("url", url->spec());
@@ -1078,7 +1082,7 @@
 
   streams_initiated_count_++;
 
-  if (net_log().IsLogging()) {
+  if (net_log().GetCaptureMode().enabled()) {
     const NetLog::EventType type =
         (GetProtocolVersion() <= SPDY3)
             ? NetLog::TYPE_HTTP2_SESSION_SYN_STREAM
@@ -1188,7 +1192,7 @@
   if (effective_len < len)
     flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
 
-  if (net_log().IsLogging()) {
+  if (net_log().GetCaptureMode().enabled()) {
     net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_DATA,
                        base::Bind(&NetLogSpdyDataCallback, stream_id,
                                   effective_len, (flags & DATA_FLAG_FIN) != 0));
@@ -2042,7 +2046,7 @@
                                     bool fin) {
   CHECK(in_io_loop_);
   DCHECK_LT(len, 1u << 24);
-  if (net_log().IsLogging()) {
+  if (net_log().GetCaptureMode().enabled()) {
     net_log().AddEvent(
         NetLog::TYPE_HTTP2_SESSION_RECV_DATA,
         base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin));
@@ -2115,7 +2119,7 @@
   if (clear_persisted)
     http_server_properties_->ClearSpdySettings(host_port_pair());
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS,
                       base::Bind(&NetLogSpdySettingsCallback, host_port_pair(),
                                  clear_persisted));
@@ -2228,7 +2232,7 @@
   base::Time response_time = base::Time::Now();
   base::TimeTicks recv_first_byte_time = time_func_();
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         NetLog::TYPE_HTTP2_SESSION_PUSHED_SYN_STREAM,
         base::Bind(&NetLogSpdySynStreamReceivedCallback, &headers, fin,
@@ -2300,7 +2304,7 @@
   base::Time response_time = base::Time::Now();
   base::TimeTicks recv_first_byte_time = time_func_();
 
-  if (net_log().IsLogging()) {
+  if (net_log().GetCaptureMode().enabled()) {
     net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_REPLY,
                        base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
                                   &headers, fin, stream_id));
@@ -2345,7 +2349,7 @@
                             const SpdyHeaderBlock& headers) {
   CHECK(in_io_loop_);
 
-  if (net_log().IsLogging()) {
+  if (net_log().GetCaptureMode().enabled()) {
     net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_HEADERS,
                        base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
                                   &headers, fin, stream_id));
@@ -2728,7 +2732,7 @@
                                 const SpdyHeaderBlock& headers) {
   CHECK(in_io_loop_);
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_PUSH_PROMISE,
                       base::Bind(&NetLogSpdyPushPromiseReceivedCallback,
                                  &headers, stream_id, promised_stream_id));
@@ -2922,7 +2926,7 @@
       buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack));
   EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass());
 
-  if (net_log().IsLogging()) {
+  if (net_log().GetCaptureMode().enabled()) {
     net_log().AddEvent(
         NetLog::TYPE_HTTP2_SESSION_PING,
         base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent"));
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index af8ba39..a470606 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -1192,13 +1192,13 @@
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
 
   scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
-      NULL, 0, 2, 1, "http://www.google.com/a.dat"));
+      NULL, 0, 2, 1, "http://www.example.org/a.dat"));
   scoped_ptr<SpdyFrame> push_a_body(
       spdy_util_.ConstructSpdyBodyFrame(2, false));
   // In ascii "0" < "a". We use it to verify that we properly handle std::map
   // iterators inside. See http://crbug.com/443490
   scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
-      NULL, 0, 4, 1, "http://www.google.com/0.dat"));
+      NULL, 0, 4, 1, "http://www.example.org/0.dat"));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)};
   MockRead reads[] = {
       CreateMockRead(*push_a, 1), CreateMockRead(*push_a_body, 2),
@@ -1232,7 +1232,7 @@
   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
   SpdySession::PushedStreamMap::iterator iter =
       session->unclaimed_pushed_streams_.find(
-          GURL("http://www.google.com/a.dat"));
+          GURL("http://www.example.org/a.dat"));
   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
 
   if (session->flow_control_state_ ==
@@ -1252,7 +1252,7 @@
   // Verify that the second pushed stream evicted the first pushed stream.
   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
   iter = session->unclaimed_pushed_streams_.find(
-      GURL("http://www.google.com/0.dat"));
+      GURL("http://www.example.org/0.dat"));
   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
 
   if (session->flow_control_state_ ==
@@ -1787,7 +1787,7 @@
       break;
     case SPDY4:
       histogram_tester.ExpectBucketCount(
-          "Net.SpdySynStreamCompressionPercentage", 82, 1);
+          "Net.SpdySynStreamCompressionPercentage", 81, 1);
       break;
     default:
       NOTREACHED();
@@ -3303,7 +3303,7 @@
 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
   CreateDeterministicNetworkSession();
 
-  HostPortPair host_port_pair("www.google.com", 443);
+  HostPortPair host_port_pair("www.example.org", 443);
   SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
                                      PRIVACY_MODE_ENABLED);
   SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
@@ -3674,7 +3674,7 @@
   if (GetParam() < kProtoSPDY31)
     return;
 
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
 
   const int32 msg_data_size = 100;
   const std::string msg_data(msg_data_size, 'a');
@@ -3762,7 +3762,7 @@
   if (GetParam() < kProtoSPDY31)
     return;
 
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
 
   const int32 msg_data_size = 100;
   const std::string msg_data(msg_data_size, 'a');
@@ -3841,7 +3841,7 @@
   if (GetParam() < kProtoSPDY31)
     return;
 
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
 
   const int32 msg_data_size = 100;
   const std::string msg_data(msg_data_size, 'a');
@@ -3969,7 +3969,7 @@
     const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
     const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
         unstall_function) {
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
   GURL url(kStreamUrl);
 
   session_deps_.host_resolver->set_synchronous_mode(true);
@@ -4122,7 +4122,7 @@
   if (GetParam() < kProtoSPDY31)
     return;
 
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
   GURL url(kStreamUrl);
 
   session_deps_.host_resolver->set_synchronous_mode(true);
@@ -4276,7 +4276,7 @@
   if (GetParam() < kProtoSPDY31)
     return;
 
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
   GURL url(kStreamUrl);
 
   session_deps_.host_resolver->set_synchronous_mode(true);
@@ -4438,7 +4438,7 @@
   if (GetParam() < kProtoSPDY31)
     return;
 
-  const char kStreamUrl[] = "http://www.google.com/";
+  const char kStreamUrl[] = "http://www.example.org/";
   GURL url(kStreamUrl);
 
   session_deps_.host_resolver->set_synchronous_mode(true);
@@ -4604,7 +4604,7 @@
 }
 
 TEST_P(SpdySessionTest, SplitHeaders) {
-  GURL kStreamUrl("http://www.google.com/foo.dat");
+  GURL kStreamUrl("http://www.example.org/foo.dat");
   SpdyHeaderBlock headers;
   spdy_util_.AddUrlToHeaderBlock(kStreamUrl.spec(), &headers);
   headers["alpha"] = "beta";
@@ -4634,7 +4634,7 @@
   scoped_ptr<SpdyFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(new_settings));
   scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush(
-      NULL, 0, 2, 1, "http://www.google.com/a.dat"));
+      NULL, 0, 2, 1, "http://www.example.org/a.dat"));
   MockRead reads[] = {
       CreateMockRead(*settings_frame), CreateMockRead(*pushed, 3),
       MockRead(ASYNC, 0, 4),
@@ -4712,9 +4712,9 @@
 
 TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
   scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
-      NULL, 0, 2, 1, "http://www.google.com/a.dat"));
+      NULL, 0, 2, 1, "http://www.example.org/a.dat"));
   scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
-      NULL, 0, 4, 1, "http://www.google.com/b.dat"));
+      NULL, 0, 4, 1, "http://www.example.org/b.dat"));
   MockRead reads[] = {
       CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
       MockRead(ASYNC, 0, 4),
@@ -4791,9 +4791,9 @@
     return;
 
   scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
-      NULL, 0, 2, 1, "http://www.google.com/a.dat"));
+      NULL, 0, 2, 1, "http://www.example.org/a.dat"));
   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
-  spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat",
+  spdy_util_.AddUrlToHeaderBlock("http://www.example.org/b.dat",
                                  push_headers.get());
   scoped_ptr<SpdyFrame> push_b(
       spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1));
@@ -4882,7 +4882,7 @@
   if (spdy_util_.spdy_version() < SPDY4)
     return;
 
-  const char kPushedUrl[] = "http://www.google.com/a.dat";
+  const char kPushedUrl[] = "http://www.example.org/a.dat";
   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
   spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get());
   scoped_ptr<SpdyFrame> push_promise(
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index 7f29364..f841be1 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -20,10 +20,11 @@
 
 namespace {
 
-base::Value* NetLogSpdyStreamErrorCallback(SpdyStreamId stream_id,
-                                           int status,
-                                           const std::string* description,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* NetLogSpdyStreamErrorCallback(
+    SpdyStreamId stream_id,
+    int status,
+    const std::string* description,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", static_cast<int>(stream_id));
   dict->SetInteger("status", status);
@@ -35,7 +36,7 @@
     SpdyStreamId stream_id,
     int32 delta,
     int32 window_size,
-    NetLog::LogLevel /* log_level */) {
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("stream_id", stream_id);
   dict->SetInteger("delta", delta);
diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc
index fc8d35f2..15f67301 100644
--- a/net/spdy/spdy_stream_unittest.cc
+++ b/net/spdy/spdy_stream_unittest.cc
@@ -32,7 +32,7 @@
 
 namespace {
 
-const char kStreamUrl[] = "http://www.google.com/";
+const char kStreamUrl[] = "http://www.example.org/";
 const char kPostBody[] = "\0hello!\xff";
 const size_t kPostBodyLength = arraysize(kPostBody);
 const base::StringPiece kPostBodyStringPiece(kPostBody, kPostBodyLength);
@@ -51,9 +51,8 @@
         offset_(0) {}
 
   base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
-    SpdySessionKey key(HostPortPair("www.google.com", 80),
-                       ProxyServer::Direct(),
-                       PRIVACY_MODE_DISABLED);
+    SpdySessionKey key(HostPortPair("www.example.org", 80),
+                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
     return CreateInsecureSpdySession(session_, key, BoundNetLog());
   }
 
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index d95b69f..781dbb2 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -44,7 +44,7 @@
 
 // Default upload data used by both, mock objects and framer when creating
 // data frames.
-const char kDefaultURL[] = "http://www.google.com";
+const char kDefaultURL[] = "http://www.example.org";
 const char kUploadData[] = "hello!";
 const int kUploadDataSize = arraysize(kUploadData)-1;
 
diff --git a/net/ssl/channel_id_service.cc b/net/ssl/channel_id_service.cc
index e52d470c..7fcbc53 100644
--- a/net/ssl/channel_id_service.cc
+++ b/net/ssl/channel_id_service.cc
@@ -27,7 +27,7 @@
 #include "net/cert/x509_util.h"
 #include "url/gurl.h"
 
-#if defined(USE_NSS_CERTS)
+#if !defined(USE_OPENSSL)
 #include <private/pprthred.h>  // PR_DetachThread
 #endif
 
@@ -246,7 +246,7 @@
     scoped_ptr<ChannelIDStore::ChannelID> cert =
         GenerateChannelID(server_identifier_, serial_number_, &error);
     DVLOG(1) << "GenerateCert " << server_identifier_ << " returned " << error;
-#if defined(USE_NSS_CERTS)
+#if !defined(USE_OPENSSL)
     // Detach the thread from NSPR.
     // Calling NSS functions attaches the thread to NSPR, which stores
     // the NSPR thread ID in thread-specific data.
diff --git a/net/ssl/openssl_platform_key_nss.cc b/net/ssl/openssl_platform_key_nss.cc
new file mode 100644
index 0000000..a9471e4
--- /dev/null
+++ b/net/ssl/openssl_platform_key_nss.cc
@@ -0,0 +1,17 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "net/ssl/openssl_platform_key.h"
+
+namespace net {
+
+crypto::ScopedEVP_PKEY FetchClientCertPrivateKey(
+    const X509Certificate* certificate) {
+  // TODO(davidben): Implement client auth for NSS. https://crbug.com/479036
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+}  // namespace net
diff --git a/net/ssl/openssl_ssl_util.cc b/net/ssl/openssl_ssl_util.cc
index f7acd62..54a3400 100644
--- a/net/ssl/openssl_ssl_util.cc
+++ b/net/ssl/openssl_ssl_util.cc
@@ -155,7 +155,7 @@
 base::Value* NetLogOpenSSLErrorCallback(int net_error,
                                         int ssl_error,
                                         const OpenSSLErrorInfo& error_info,
-                                        NetLog::LogLevel /* log_level */) {
+                                        NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("net_error", net_error);
   dict->SetInteger("ssl_error", ssl_error);
diff --git a/net/test/cert_test_util_nss.cc b/net/test/cert_test_util_nss.cc
index ee929e5a..74884c7dd 100644
--- a/net/test/cert_test_util_nss.cc
+++ b/net/test/cert_test_util_nss.cc
@@ -19,6 +19,14 @@
     const base::FilePath& dir,
     const std::string& key_filename,
     PK11SlotInfo* slot) {
+#if defined(USE_OPENSSL)
+  // TODO(davidben): Port RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo away
+  // from RSAPrivateKey so it doesn't make assumptions about the internal crypto
+  // library. Instead, return a ScopedSECKEYPrivateKey or have this function
+  // just return bool. https://crbug.com/478777
+  NOTIMPLEMENTED();
+  return nullptr;
+#else
   base::FilePath key_path = dir.AppendASCII(key_filename);
   std::string key_pkcs8;
   bool success = base::ReadFileToString(key_path, &key_pkcs8);
@@ -38,6 +46,7 @@
   LOG_IF(ERROR, !private_key) << "Could not create key from file "
                               << key_path.value();
   return private_key.Pass();
+#endif
 }
 
 bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,
diff --git a/net/test/net_test_suite.cc b/net/test/net_test_suite.cc
index ac927e5c..b14e3fe 100644
--- a/net/test/net_test_suite.cc
+++ b/net/test/net_test_suite.cc
@@ -15,7 +15,7 @@
 #endif
 
 class StaticReset : public ::testing::EmptyTestEventListener {
-  virtual void OnTestStart(const ::testing::TestInfo& test_info) override {
+  void OnTestStart(const ::testing::TestInfo& test_info) override {
     net::HttpStreamFactory::ResetStaticSettingsToInit();
   }
 };
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index 3eeb685..b8ded1f 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -310,6 +310,24 @@
   return true;
 }
 
+bool BaseTestServer::LoadTestRootCert() const {
+  TestRootCerts* root_certs = TestRootCerts::GetInstance();
+  if (!root_certs)
+    return false;
+
+  // Should always use absolute path to load the root certificate.
+  base::FilePath root_certificate_path = certificates_dir_;
+  if (!certificates_dir_.IsAbsolute()) {
+    base::FilePath src_dir;
+    if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
+      return false;
+    root_certificate_path = src_dir.Append(certificates_dir_);
+  }
+
+  return root_certs->AddFromFile(
+      root_certificate_path.AppendASCII("root_ca_cert.pem"));
+}
+
 void BaseTestServer::Init(const std::string& host) {
   host_port_pair_ = HostPortPair(host, 0);
 
@@ -352,24 +370,6 @@
   return true;
 }
 
-bool BaseTestServer::LoadTestRootCert() const {
-  TestRootCerts* root_certs = TestRootCerts::GetInstance();
-  if (!root_certs)
-    return false;
-
-  // Should always use absolute path to load the root certificate.
-  base::FilePath root_certificate_path = certificates_dir_;
-  if (!certificates_dir_.IsAbsolute()) {
-    base::FilePath src_dir;
-    if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
-      return false;
-    root_certificate_path = src_dir.Append(certificates_dir_);
-  }
-
-  return root_certs->AddFromFile(
-      root_certificate_path.AppendASCII("root_ca_cert.pem"));
-}
-
 bool BaseTestServer::SetupWhenServerStarted() {
   DCHECK(host_port_pair_.port());
 
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h
index 5fd57f1..d430b0e 100644
--- a/net/test/spawned_test_server/base_test_server.h
+++ b/net/test/spawned_test_server/base_test_server.h
@@ -262,6 +262,10 @@
     ws_basic_auth_ = ws_basic_auth;
   }
 
+  // Marks the root certificate of an HTTPS test server as trusted for
+  // the duration of tests.
+  bool LoadTestRootCert() const WARN_UNUSED_RESULT;
+
  protected:
   virtual ~BaseTestServer();
   Type type() const { return type_; }
@@ -300,10 +304,6 @@
  private:
   void Init(const std::string& host);
 
-  // Marks the root certificate of an HTTPS test server as trusted for
-  // the duration of tests.
-  bool LoadTestRootCert() const WARN_UNUSED_RESULT;
-
   // Document root of the test server.
   base::FilePath document_root_;
 
diff --git a/net/tools/gdig/gdig.cc b/net/tools/gdig/gdig.cc
index faaffa7..285668b5 100644
--- a/net/tools/gdig/gdig.cc
+++ b/net/tools/gdig/gdig.cc
@@ -296,15 +296,17 @@
 
   if (parsed_command_line.HasSwitch("net_log")) {
     std::string log_param = parsed_command_line.GetSwitchValueASCII("net_log");
-    NetLog::LogLevel level = NetLog::LOG_ALL_BUT_BYTES;
+    NetLogCaptureMode capture_mode =
+        NetLogCaptureMode::IncludeCookiesAndCredentials();
 
     if (log_param.length() > 0) {
-      std::map<std::string, NetLog::LogLevel> log_levels;
-      log_levels["all"] = NetLog::LOG_ALL;
-      log_levels["no_bytes"] = NetLog::LOG_ALL_BUT_BYTES;
+      std::map<std::string, NetLogCaptureMode> capture_modes;
+      capture_modes["all"] = NetLogCaptureMode::IncludeSocketBytes();
+      capture_modes["no_bytes"] =
+          NetLogCaptureMode::IncludeCookiesAndCredentials();
 
-      if (log_levels.find(log_param) != log_levels.end()) {
-        level = log_levels[log_param];
+      if (capture_modes.find(log_param) != capture_modes.end()) {
+        capture_mode = capture_modes[log_param];
       } else {
         fprintf(stderr, "Invalid net_log parameter\n");
         return false;
@@ -312,7 +314,7 @@
     }
     log_.reset(new NetLog);
     log_observer_.reset(new FileNetLogObserver(stderr));
-    log_->DeprecatedAddObserver(log_observer_.get(), level);
+    log_->DeprecatedAddObserver(log_observer_.get(), capture_mode);
   }
 
   print_config_ = parsed_command_line.HasSwitch("print_config");
diff --git a/net/tools/get_server_time/get_server_time.cc b/net/tools/get_server_time/get_server_time.cc
index e8d4d76..98a48c100 100644
--- a/net/tools/get_server_time/get_server_time.cc
+++ b/net/tools/get_server_time/get_server_time.cc
@@ -226,7 +226,8 @@
   // printing_log_observer.
   net::NetLog net_log;
   PrintingLogObserver printing_log_observer;
-  net_log.DeprecatedAddObserver(&printing_log_observer, net::NetLog::LOG_ALL);
+  net_log.DeprecatedAddObserver(&printing_log_observer,
+                                net::NetLogCaptureMode::IncludeSocketBytes());
 
   QuitDelegate delegate;
   scoped_ptr<net::URLFetcher> fetcher(
diff --git a/net/tools/quic/quic_simple_client.cc b/net/tools/quic/quic_simple_client.cc
index 703f22f..e29a7a3 100644
--- a/net/tools/quic/quic_simple_client.cc
+++ b/net/tools/quic/quic_simple_client.cc
@@ -15,6 +15,7 @@
 #include "net/quic/quic_default_packet_writer.h"
 #include "net/quic/quic_protocol.h"
 #include "net/quic/quic_server_id.h"
+#include "net/quic/spdy_utils.h"
 #include "net/spdy/spdy_http_utils.h"
 #include "net/udp/udp_client_socket.h"
 
@@ -188,8 +189,10 @@
     return;
   }
   SpdyHeaderBlock header_block;
-  CreateSpdyHeadersFromHttpRequest(headers, headers.extra_headers, SPDY3, true,
-                                   &header_block);
+  SpdyMajorVersion spdy_version =
+      SpdyUtils::GetSpdyVersionForQuicVersion(stream->version());
+  CreateSpdyHeadersFromHttpRequest(headers, headers.extra_headers, spdy_version,
+                                   true, &header_block);
   stream->SendRequest(header_block, body, fin);
   stream->set_visitor(this);
 }
@@ -249,7 +252,9 @@
   QuicSpdyClientStream* client_stream =
       static_cast<QuicSpdyClientStream*>(stream);
   HttpResponseInfo response;
-  SpdyHeadersToHttpResponse(client_stream->headers(), SPDY3, &response);
+  SpdyMajorVersion spdy_version =
+      SpdyUtils::GetSpdyVersionForQuicVersion(client_stream->version());
+  SpdyHeadersToHttpResponse(client_stream->headers(), spdy_version, &response);
   if (response_listener_.get() != nullptr) {
     response_listener_->OnCompleteResponse(
         stream->id(), *response.headers, client_stream->data());
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc
index 7c451a3..1960521 100644
--- a/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -188,7 +188,7 @@
       : connection_id_(connection_id), sequence_number_(number) {
   }
 
-  virtual bool MatchAndExplain(
+  bool MatchAndExplain(
       const std::tr1::tuple<const char*, int> packet_buffer,
       testing::MatchResultListener* /* listener */) const override {
     FramerVisitorCapturingPublicReset visitor;
@@ -206,9 +206,9 @@
         kTestPort == packet.client_address.port();
   }
 
-  virtual void DescribeTo(::std::ostream* os) const override {}
+  void DescribeTo(::std::ostream* os) const override {}
 
-  virtual void DescribeNegationTo(::std::ostream* os) const override {}
+  void DescribeNegationTo(::std::ostream* os) const override {}
 
  private:
   QuicConnectionId connection_id_;
diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h
index 7cb4516c..e7884680 100644
--- a/net/tools/quic/test_tools/quic_test_utils.h
+++ b/net/tools/quic/test_tools/quic_test_utils.h
@@ -43,14 +43,14 @@
 class TestSession : public QuicSession {
  public:
   TestSession(QuicConnection* connection, const QuicConfig& config);
-  virtual ~TestSession();
+  ~TestSession() override;
 
   MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
   MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
 
   void SetCryptoStream(QuicCryptoStream* stream);
 
-  virtual QuicCryptoStream* GetCryptoStream() override;
+  QuicCryptoStream* GetCryptoStream() override;
 
  private:
   QuicCryptoStream* crypto_stream_;
diff --git a/net/udp/udp_net_log_parameters.cc b/net/udp/udp_net_log_parameters.cc
index c258823..fb25b4c7 100644
--- a/net/udp/udp_net_log_parameters.cc
+++ b/net/udp/udp_net_log_parameters.cc
@@ -16,10 +16,10 @@
 base::Value* NetLogUDPDataTranferCallback(int byte_count,
                                           const char* bytes,
                                           const IPEndPoint* address,
-                                          NetLog::LogLevel log_level) {
+                                          NetLogCaptureMode capture_mode) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetInteger("byte_count", byte_count);
-  if (NetLog::IsLoggingBytes(log_level))
+  if (capture_mode.include_socket_bytes())
     dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
   if (address)
     dict->SetString("address", address->ToString());
@@ -27,7 +27,7 @@
 }
 
 base::Value* NetLogUDPConnectCallback(const IPEndPoint* address,
-                                      NetLog::LogLevel /* log_level */) {
+                                      NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("address", address->ToString());
   return dict;
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
index 82597777..2fce83f51 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -496,7 +496,7 @@
     return;
   }
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     DCHECK(addr_len > 0);
     DCHECK(addr);
 
@@ -533,7 +533,7 @@
     return;
   }
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         NetLog::TYPE_UDP_BYTES_SENT,
         CreateNetLogUDPDataTranferCallback(result, bytes, address));
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
index b47247a9..8c226f9 100644
--- a/net/udp/udp_socket_win.cc
+++ b/net/udp/udp_socket_win.cc
@@ -681,7 +681,7 @@
     return;
   }
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         NetLog::TYPE_UDP_BYTES_RECEIVED,
         CreateNetLogUDPDataTranferCallback(result, bytes, address));
@@ -698,7 +698,7 @@
     return;
   }
 
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         NetLog::TYPE_UDP_BYTES_SENT,
         CreateNetLogUDPDataTranferCallback(result, bytes, address));
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index c539bdf0..213307c 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -881,7 +881,7 @@
 int URLRequest::Redirect(const RedirectInfo& redirect_info) {
   // Matches call in NotifyReceivedRedirect.
   OnCallToDelegateComplete();
-  if (net_log_.IsLogging()) {
+  if (net_log_.GetCaptureMode().enabled()) {
     net_log_.AddEvent(
         NetLog::TYPE_URL_REQUEST_REDIRECTED,
         NetLog::StringCallback("location",
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index c47c819..5ca046f 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -227,7 +227,7 @@
  public:
   // GoogleMock does not appear to play nicely with move-only types like
   // scoped_ptr, so this forwarding method acts as a workaround.
-  virtual WebSocketHandshakeStreamBase* CreateBasicStream(
+  WebSocketHandshakeStreamBase* CreateBasicStream(
       scoped_ptr<ClientSocketHandle> connection,
       bool using_proxy) override {
     // Discard the arguments since we don't need them anyway.
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index ce58e6a..106cb856 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -27,7 +27,7 @@
 
 // Callback for TYPE_URL_REQUEST_FILTERS_SET net-internals event.
 base::Value* FiltersSetCallback(Filter* filter,
-                                NetLog::LogLevel /* log_level */) {
+                                NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* event_params = new base::DictionaryValue();
   event_params->SetString("filters", filter->OrderedFilterList());
   return event_params;
@@ -698,7 +698,8 @@
       }
 
       // If logging all bytes is enabled, log the filtered bytes read.
-      if (rv && request() && request()->net_log().IsLoggingBytes() &&
+      if (rv && request() &&
+          request()->net_log().GetCaptureMode().include_socket_bytes() &&
           filtered_data_len > 0) {
         request()->net_log().AddByteTransferEvent(
             NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ,
@@ -789,7 +790,8 @@
 void URLRequestJob::OnRawReadComplete(int bytes_read) {
   DCHECK(raw_read_buffer_.get());
   // If |filter_| is non-NULL, bytes will be logged after it is applied instead.
-  if (!filter_.get() && request() && request()->net_log().IsLoggingBytes() &&
+  if (!filter_.get() && request() &&
+      request()->net_log().GetCaptureMode().include_socket_bytes() &&
       bytes_read > 0) {
     request()->net_log().AddByteTransferEvent(
         NetLog::TYPE_URL_REQUEST_JOB_BYTES_READ,
diff --git a/net/url_request/url_request_netlog_params.cc b/net/url_request/url_request_netlog_params.cc
index a1e8243b..9833fe38 100644
--- a/net/url_request/url_request_netlog_params.cc
+++ b/net/url_request/url_request_netlog_params.cc
@@ -10,12 +10,13 @@
 
 namespace net {
 
-base::Value* NetLogURLRequestStartCallback(const GURL* url,
-                                           const std::string* method,
-                                           int load_flags,
-                                           RequestPriority priority,
-                                           int64 upload_id,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* NetLogURLRequestStartCallback(
+    const GURL* url,
+    const std::string* method,
+    int load_flags,
+    RequestPriority priority,
+    int64 upload_id,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("url", url->possibly_invalid_spec());
   dict->SetString("method", *method);
diff --git a/net/url_request/url_request_netlog_params.h b/net/url_request/url_request_netlog_params.h
index 9ca36bca..d216105ac 100644
--- a/net/url_request/url_request_netlog_params.h
+++ b/net/url_request/url_request_netlog_params.h
@@ -26,7 +26,7 @@
     int load_flags,
     RequestPriority priority,
     int64 upload_id,
-    NetLog::LogLevel /* log_level */);
+    NetLogCaptureMode /* capture_mode */);
 
 // Attempts to extract the load flags from a Value created by the above
 // function.  On success, sets |load_flags| accordingly and returns true.
diff --git a/net/url_request/url_request_throttler_entry.cc b/net/url_request/url_request_throttler_entry.cc
index 1197f6fa..84a9014 100644
--- a/net/url_request/url_request_throttler_entry.cc
+++ b/net/url_request/url_request_throttler_entry.cc
@@ -52,10 +52,11 @@
     "disable";
 
 // Returns NetLog parameters when a request is rejected by throttling.
-base::Value* NetLogRejectedRequestCallback(const std::string* url_id,
-                                           int num_failures,
-                                           const base::TimeDelta& release_after,
-                                           NetLog::LogLevel /* log_level */) {
+base::Value* NetLogRejectedRequestCallback(
+    const std::string* url_id,
+    int num_failures,
+    const base::TimeDelta& release_after,
+    NetLogCaptureMode /* capture_mode */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetString("url", *url_id);
   dict->SetInteger("num_failures", num_failures);
diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc
index 57dd2da..fe49f39 100644
--- a/net/websockets/websocket_channel_test.cc
+++ b/net/websockets/websocket_channel_test.cc
@@ -173,7 +173,7 @@
     OnFinishOpeningHandshakeCalled();
     return CHANNEL_ALIVE;
   }
-  virtual ChannelState OnSSLCertificateError(
+  ChannelState OnSSLCertificateError(
       scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks,
       const GURL& url,
       const SSLInfo& ssl_info,
diff --git a/pdf/instance.h b/pdf/instance.h
index bdb52430..daded88 100644
--- a/pdf/instance.h
+++ b/pdf/instance.h
@@ -58,36 +58,36 @@
                  public ControlOwner {
  public:
   explicit Instance(PP_Instance instance);
-  virtual ~Instance();
+  ~Instance() override;
 
   // pp::Instance implementation.
-  virtual bool Init(uint32_t argc,
-                    const char* argn[],
-                    const char* argv[]) override;
-  virtual bool HandleDocumentLoad(const pp::URLLoader& loader) override;
-  virtual bool HandleInputEvent(const pp::InputEvent& event) override;
-  virtual void DidChangeView(const pp::View& view) override;
-  virtual pp::Var GetInstanceObject() override;
+  bool Init(uint32_t argc,
+            const char* argn[],
+            const char* argv[]) override;
+  bool HandleDocumentLoad(const pp::URLLoader& loader) override;
+  bool HandleInputEvent(const pp::InputEvent& event) override;
+  void DidChangeView(const pp::View& view) override;
+  pp::Var GetInstanceObject() override;
 
   // pp::Find_Private implementation.
-  virtual bool StartFind(const std::string& text, bool case_sensitive) override;
-  virtual void SelectFindResult(bool forward) override;
-  virtual void StopFind() override;
+  bool StartFind(const std::string& text, bool case_sensitive) override;
+  void SelectFindResult(bool forward) override;
+  void StopFind() override;
 
   // pp::PaintManager::Client implementation.
-  virtual void OnPaint(const std::vector<pp::Rect>& paint_rects,
-                       std::vector<PaintManager::ReadyRect>* ready,
-                       std::vector<pp::Rect>* pending) override;
+  void OnPaint(const std::vector<pp::Rect>& paint_rects,
+               std::vector<PaintManager::ReadyRect>* ready,
+               std::vector<pp::Rect>* pending) override;
 
   // pp::Printing_Dev implementation.
-  virtual uint32_t QuerySupportedPrintOutputFormats() override;
-  virtual int32_t PrintBegin(
+  uint32_t QuerySupportedPrintOutputFormats() override;
+  int32_t PrintBegin(
       const PP_PrintSettings_Dev& print_settings) override;
-  virtual pp::Resource PrintPages(
+  pp::Resource PrintPages(
       const PP_PrintPageNumberRange_Dev* page_ranges,
       uint32_t page_range_count) override;
-  virtual void PrintEnd() override;
-  virtual bool IsPrintScalingDisabled() override;
+  void PrintEnd() override;
+  bool IsPrintScalingDisabled() override;
 
   // pp::Private implementation.
   virtual pp::Var GetLinkAtPosition(const pp::Point& point);
@@ -95,18 +95,18 @@
       PP_PdfPrintPresetOptions_Dev* options);
 
   // PPP_Selection_Dev implementation.
-  virtual pp::Var GetSelectedText(bool html) override;
+  pp::Var GetSelectedText(bool html) override;
 
   // WidgetClient_Dev implementation.
-  virtual void InvalidateWidget(pp::Widget_Dev widget,
-                                const pp::Rect& dirty_rect) override;
-  virtual void ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar,
-                                     uint32_t value) override;
-  virtual void ScrollbarOverlayChanged(pp::Scrollbar_Dev scrollbar,
-                                       bool overlay) override;
+  void InvalidateWidget(pp::Widget_Dev widget,
+                        const pp::Rect& dirty_rect) override;
+  void ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar,
+                             uint32_t value) override;
+  void ScrollbarOverlayChanged(pp::Scrollbar_Dev scrollbar,
+                               bool overlay) override;
 
   // pp::Zoom_Dev implementation.
-  virtual void Zoom(double scale, bool text_only) override;
+  void Zoom(double scale, bool text_only) override;
   void ZoomChanged(double factor);  // Override.
 
   void FlushCallback(int32_t result);
@@ -194,8 +194,8 @@
                                pp::Var* exception);
 
   // PreviewModeClient::Client implementation.
-  virtual void PreviewDocumentLoadComplete() override;
-  virtual void PreviewDocumentLoadFailed() override;
+  void PreviewDocumentLoadComplete() override;
+  void PreviewDocumentLoadFailed() override;
 
   // Helper functions for implementing PPP_PDF.
   void RotateClockwise();
diff --git a/pdf/out_of_process_instance.h b/pdf/out_of_process_instance.h
index 62d21c1..091fbc3 100644
--- a/pdf/out_of_process_instance.h
+++ b/pdf/out_of_process_instance.h
@@ -45,35 +45,32 @@
                              public PreviewModeClient::Client {
  public:
   explicit OutOfProcessInstance(PP_Instance instance);
-  virtual ~OutOfProcessInstance();
+  ~OutOfProcessInstance() override;
 
   // pp::Instance implementation.
-  virtual bool Init(uint32_t argc,
-                    const char* argn[],
-                    const char* argv[]) override;
-  virtual void HandleMessage(const pp::Var& message) override;
-  virtual bool HandleInputEvent(const pp::InputEvent& event) override;
-  virtual void DidChangeView(const pp::View& view) override;
+  bool Init(uint32_t argc, const char* argn[], const char* argv[]) override;
+  void HandleMessage(const pp::Var& message) override;
+  bool HandleInputEvent(const pp::InputEvent& event) override;
+  void DidChangeView(const pp::View& view) override;
 
   // pp::Find_Private implementation.
-  virtual bool StartFind(const std::string& text, bool case_sensitive) override;
-  virtual void SelectFindResult(bool forward) override;
-  virtual void StopFind() override;
+  bool StartFind(const std::string& text, bool case_sensitive) override;
+  void SelectFindResult(bool forward) override;
+  void StopFind() override;
 
   // pp::PaintManager::Client implementation.
-  virtual void OnPaint(const std::vector<pp::Rect>& paint_rects,
-                       std::vector<PaintManager::ReadyRect>* ready,
-                       std::vector<pp::Rect>* pending) override;
+  void OnPaint(const std::vector<pp::Rect>& paint_rects,
+               std::vector<PaintManager::ReadyRect>* ready,
+               std::vector<pp::Rect>* pending) override;
 
   // pp::Printing_Dev implementation.
-  virtual uint32_t QuerySupportedPrintOutputFormats() override;
-  virtual int32_t PrintBegin(
-      const PP_PrintSettings_Dev& print_settings) override;
-  virtual pp::Resource PrintPages(
+  uint32_t QuerySupportedPrintOutputFormats() override;
+  int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) override;
+  pp::Resource PrintPages(
       const PP_PrintPageNumberRange_Dev* page_ranges,
       uint32_t page_range_count) override;
-  virtual void PrintEnd() override;
-  virtual bool IsPrintScalingDisabled() override;
+  void PrintEnd() override;
+  bool IsPrintScalingDisabled() override;
 
   // pp::Private implementation.
   virtual pp::Var GetLinkAtPosition(const pp::Point& point);
@@ -81,7 +78,7 @@
       PP_PdfPrintPresetOptions_Dev* options);
 
   // PPP_Selection_Dev implementation.
-  virtual pp::Var GetSelectedText(bool html) override;
+  pp::Var GetSelectedText(bool html) override;
 
   void FlushCallback(int32_t result);
   void DidOpen(int32_t result);
diff --git a/ppapi/native_client/src/untrusted/irt_stub/irt_stub.gyp b/ppapi/native_client/src/untrusted/irt_stub/irt_stub.gyp
index db1493d..c00cf980 100644
--- a/ppapi/native_client/src/untrusted/irt_stub/irt_stub.gyp
+++ b/ppapi/native_client/src/untrusted/irt_stub/irt_stub.gyp
@@ -25,9 +25,6 @@
         'ppapi_plugin_start.c',
         'thread_creator.c'
       ],
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
   ],
 }
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
index a2e9e1f..946437d9 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
@@ -51,9 +51,6 @@
           '-DPNACL_SHIM_AOT',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
     # Smaller shim library for PNaCl in-browser translation.
     # Uses an unstable IRT hook interface to get the shim from the IRT itself.
@@ -87,9 +84,6 @@
           '--strip-debug',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
     {
       # Second half of shim library for PNaCl in-browser translation.
@@ -109,9 +103,6 @@
           'pnacl_shim.c',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
   ],
 }
diff --git a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
index e8dc67d..573151df 100644
--- a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
+++ b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
@@ -20,7 +20,6 @@
       ['disable_nacl==0 and disable_pnacl==0 and disable_nacl_untrusted==0', {
         'dependencies': [
           '../../../../../ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:browser',
-          '../../../../../native_client/tools.gyp:prep_toolchain',
         ],
         'sources': [
           'pnacl_component_crx_gen.py',
diff --git a/ppapi/ppapi_ipc_nacl.gyp b/ppapi/ppapi_ipc_nacl.gyp
index c82a4ec5..3608f80 100644
--- a/ppapi/ppapi_ipc_nacl.gyp
+++ b/ppapi/ppapi_ipc_nacl.gyp
@@ -31,7 +31,6 @@
             '..',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
             '../base/base_nacl.gyp:base_nacl_nonsfi',
             '../gpu/gpu_nacl.gyp:gpu_ipc_nacl',
diff --git a/ppapi/ppapi_nacl.gyp b/ppapi/ppapi_nacl.gyp
index 91a4a40a..aa7b718be 100644
--- a/ppapi/ppapi_nacl.gyp
+++ b/ppapi/ppapi_nacl.gyp
@@ -27,9 +27,6 @@
           'cpp/ppp_entrypoints.cc',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
     {
       'target_name': 'ppapi_gles2_lib',
@@ -49,15 +46,11 @@
           'lib/gl/gles2/gles2.c',
         ],
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
     },
     {
       'target_name': 'ppapi_nacl_tests',
       'type': 'none',
       'dependencies': [
-         '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
          '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:nacl_lib',
          '<(DEPTH)/native_client/src/untrusted/pthread/pthread.gyp:pthread_lib',
          'ppapi_cpp_lib',
diff --git a/ppapi/ppapi_proxy_nacl.gyp b/ppapi/ppapi_proxy_nacl.gyp
index c71f9e55..7740a4e7 100644
--- a/ppapi/ppapi_proxy_nacl.gyp
+++ b/ppapi/ppapi_proxy_nacl.gyp
@@ -42,7 +42,6 @@
             '../ipc/ipc_nacl.gyp:ipc_nacl',
             '../ipc/ipc_nacl.gyp:ipc_nacl_nonsfi',
             '../mojo/mojo_nacl.gyp:monacl_codegen',
-            '../native_client/tools.gyp:prep_toolchain',
             '../ppapi/ppapi_ipc_nacl.gyp:ppapi_ipc_nacl',
             '../ppapi/ppapi_shared_nacl.gyp:ppapi_shared_nacl',
             '../third_party/WebKit/public/blink_headers.gyp:blink_headers',
diff --git a/ppapi/ppapi_shared_nacl.gyp b/ppapi/ppapi_shared_nacl.gyp
index 819acc7..05e4aca 100644
--- a/ppapi/ppapi_shared_nacl.gyp
+++ b/ppapi/ppapi_shared_nacl.gyp
@@ -31,7 +31,6 @@
             '..',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
             '../base/base_nacl.gyp:base_nacl_nonsfi',
             '../gpu/command_buffer/command_buffer_nacl.gyp:gles2_utils_nacl',
diff --git a/remoting/BUILD.gn b/remoting/BUILD.gn
index 8409632..02adc68d 100644
--- a/remoting/BUILD.gn
+++ b/remoting/BUILD.gn
@@ -19,15 +19,19 @@
   deps = [
     #"//remoting:remoting_browser_test_resources",
     "//remoting:remoting_unittests",
-
-    #"//remoting:remoting_webapp",
-    "//remoting/webapp:html",
-
     #"//remoting:remoting_webapp_unittests",
     #"//app_remoting_test.gyp:ar_sample_test_driver",
     #"//app_remoting_webapp.gyp:ar_sample_app",
   ]
 
+  if ((is_linux && !is_chromeos) || is_mac) {
+    deps += [
+      # TODO(gyp) Enable this for Windows once the webapp can be built without
+      # exceeding the 8k cmd line limit on Windows.
+      "//remoting/webapp",
+    ]
+  }
+
   if (is_win) {
     deps += [
       #"//remoting:remoting_breakpad_tester",
@@ -136,10 +140,8 @@
   }
 }
 
-# TODO(GYP) remoting_unittests on Mac/Windows. Currently this fails with a
-# duplicate resource error on linking on Windows. Just needs to be checked on
-# Mac.
-if (!is_win && !is_mac) {
+# TODO(GYP) remoting_unittests on Mac. Needs to be tested.
+if (!is_mac) {
   test("remoting_unittests") {
     # Sources not included in one of the more specific unit_tests deps.
     sources = [
@@ -186,6 +188,7 @@
       deps += [
         "//remoting/codec:unit_tests",
         "//remoting/host:unit_tests",
+        "//ui/gfx",
       ]
     }
 
diff --git a/remoting/base/BUILD.gn b/remoting/base/BUILD.gn
index bb79d52..48f40ef 100644
--- a/remoting/base/BUILD.gn
+++ b/remoting/base/BUILD.gn
@@ -29,6 +29,27 @@
   ]
 }
 
+source_set("breakpad") {
+  sources = [
+    "breakpad.h",
+    "breakpad_linux.cc",
+    "breakpad_mac.mm",
+    "breakpad_win.cc",
+  ]
+
+  configs += [ "//build/config/compiler:wexit_time_destructors" ]
+
+  deps = [
+    "//base",
+  ]
+
+  if (is_mac) {
+    deps += [ "//breakpad" ]
+  } else if (is_win) {
+    deps += [ "//breakpad:breakpad_handler" ]
+  }
+}
+
 source_set("unit_tests") {
   testonly = true
 
@@ -50,6 +71,7 @@
 
   deps = [
     ":base",
+    ":breakpad",
     "//base",
     "//net:test_support",
     "//testing/gmock",
@@ -62,5 +84,4 @@
     sources += [ "resources_unittest.cc" ]
     deps += [ "//breakpad:client" ]
   }
-
 }
diff --git a/remoting/base/vlog_net_log.cc b/remoting/base/vlog_net_log.cc
index db72ad3..39a388a7 100644
--- a/remoting/base/vlog_net_log.cc
+++ b/remoting/base/vlog_net_log.cc
@@ -42,7 +42,8 @@
 
 VlogNetLog::VlogNetLog()
     : observer_(new Observer()) {
-  DeprecatedAddObserver(observer_.get(), LOG_ALL_BUT_BYTES);
+  DeprecatedAddObserver(observer_.get(),
+                        net::NetLogCaptureMode::IncludeCookiesAndCredentials());
 }
 
 VlogNetLog::~VlogNetLog() {
diff --git a/remoting/client/jni/chromoting_jni_instance.cc b/remoting/client/jni/chromoting_jni_instance.cc
index 6cfc8870e..33bd2466 100644
--- a/remoting/client/jni/chromoting_jni_instance.cc
+++ b/remoting/client/jni/chromoting_jni_instance.cc
@@ -450,10 +450,10 @@
   // |client_| must be torn down before |signaling_|.
   client_.reset();
   client_status_logger_.reset();
-  client_context_.reset();
   video_renderer_.reset();
   authenticator_.reset();
   signaling_.reset();
+  client_context_.reset();
 }
 
 void ChromotingJniInstance::FetchSecret(
diff --git a/remoting/client/software_video_renderer.cc b/remoting/client/software_video_renderer.cc
index 0be8b498..51782e05 100644
--- a/remoting/client/software_video_renderer.cc
+++ b/remoting/client/software_video_renderer.cc
@@ -325,7 +325,8 @@
 
 SoftwareVideoRenderer::~SoftwareVideoRenderer() {
   DCHECK(CalledOnValidThread());
-  decode_task_runner_->DeleteSoon(FROM_HERE, core_.release());
+  bool result = decode_task_runner_->DeleteSoon(FROM_HERE, core_.release());
+  DCHECK(result);
 }
 
 void SoftwareVideoRenderer::OnSessionConfig(
diff --git a/remoting/host/it2me/BUILD.gn b/remoting/host/it2me/BUILD.gn
index 965977c..076c21b 100644
--- a/remoting/host/it2me/BUILD.gn
+++ b/remoting/host/it2me/BUILD.gn
@@ -45,6 +45,7 @@
       "//remoting/host",
       "//remoting/host/native_messaging",
       "//remoting/proto",
+      "//ui/gfx",
     ]
 
     if (enable_webrtc) {
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 6d783c2..d4f1764c4 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -84,6 +84,7 @@
 
   'targets': [
     {
+      # GN version: //remoting/base:breakpad
       'target_name': 'remoting_breakpad',
       'type': 'static_library',
       'variables': { 'enable_wexit_time_destructors': 1, },
diff --git a/remoting/remoting_client.gypi b/remoting/remoting_client.gypi
index 718d90f..d146658 100644
--- a/remoting/remoting_client.gypi
+++ b/remoting/remoting_client.gypi
@@ -49,11 +49,12 @@
     },  # end of target 'remoting_client'
 
     {
+      # GN version: //remoting/webapp:html
       'target_name': 'remoting_webapp_html',
       'type': 'none',
       'actions': [
         {
-          # GN version: //remoting/webapp:html
+          # GN version: //remoting/webapp:main_html
           'action_name': 'Build Remoting Webapp main.html',
           'inputs': [
             'webapp/build-html.py',
@@ -74,6 +75,7 @@
           ],
         },
         {
+          # GN version: //remoting/webapp:wcs_sandbox_html
           'action_name': 'Build Remoting Webapp wcs_sandbox.html',
           'inputs': [
             'webapp/build-html.py',
@@ -90,6 +92,7 @@
           ],
         },
         {
+          # GN version: //remoting/webapp:background_html
           'action_name': 'Build Remoting Webapp background.html',
           'inputs': [
             'webapp/build-html.py',
diff --git a/remoting/remoting_key_tester.gypi b/remoting/remoting_key_tester.gypi
index 7eac507..ba16e417 100644
--- a/remoting/remoting_key_tester.gypi
+++ b/remoting/remoting_key_tester.gypi
@@ -96,10 +96,6 @@
             '-lppapi_stub',
             '-lppapi_cpp',
           ],
-          'dependencies': [
-            # TODO(mseaborn): Remove need for this (https://crbug.com/456902).
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-          ],
         },  # end of target 'remoting_key_tester_pexe'
       ],
     }]
diff --git a/remoting/remoting_locales.gni b/remoting/remoting_locales.gni
index 0bd0536..d4dd4e8 100644
--- a/remoting/remoting_locales.gni
+++ b/remoting/remoting_locales.gni
@@ -6,10 +6,11 @@
 
 # See also remoting_locales_with_underscores below.
 remoting_locales = [
-  "am",
+  #"am",
   "ar",
   "bg",
-  "bn",
+
+  #"bn",
   "ca",
   "cs",
   "da",
@@ -20,12 +21,14 @@
   "es",
   "es-419",
   "et",
-  "fa",
-  "fake-bidi",
+
+  #"fa",
+  #"fake-bidi",
   "fi",
   "fil",
   "fr",
-  "gu",
+
+  #"gu",
   "he",
   "hi",
   "hr",
@@ -33,13 +36,15 @@
   "id",
   "it",
   "ja",
-  "kn",
+
+  #"kn",
   "ko",
   "lt",
   "lv",
-  "ml",
-  "mr",
-  "ms",
+
+  #"ml",
+  #"mr",
+  #"ms",
   "nb",
   "nl",
   "pl",
@@ -51,9 +56,10 @@
   "sl",
   "sr",
   "sv",
-  "sw",
-  "ta",
-  "te",
+
+  #"sw",
+  #"ta",
+  #"te",
   "th",
   "tr",
   "uk",
@@ -68,7 +74,8 @@
 remoting_locales_with_underscores -= [
   "en-GB",
   "es-419",
-  "fake-bidi",
+
+  #"fake-bidi",
   "pt-BR",
   "pt-PT",
   "zh-CN",
@@ -77,7 +84,8 @@
 remoting_locales_with_underscores += [
   "en_GB",
   "es_419",
-  "fake_bidi",
+
+  #"fake_bidi",
   "pt_BR",
   "pt_PT",
   "zh_CN",
diff --git a/remoting/remoting_nacl.gyp b/remoting/remoting_nacl.gyp
index b7c7374..b66a742b 100644
--- a/remoting/remoting_nacl.gyp
+++ b/remoting/remoting_nacl.gyp
@@ -74,7 +74,6 @@
         'GOOGLE_PROTOBUF_HOST_ARCH_64_BIT=1'
       ],
       'dependencies': [
-        '../native_client/tools.gyp:prep_toolchain',
         '../third_party/protobuf/protobuf_nacl.gyp:protobuf_lite_nacl',
         'proto/chromotocol.gyp:chromotocol_proto_lib',
       ],
@@ -101,7 +100,6 @@
       'dependencies': [
         '../base/base_nacl.gyp:base_nacl',
         '../jingle/jingle_nacl.gyp:jingle_glue_nacl',
-        '../native_client/tools.gyp:prep_toolchain',
         '../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
         '../net/net_nacl.gyp:net_nacl',
         '../third_party/boringssl/boringssl_nacl.gyp:boringssl_nacl',
@@ -181,7 +179,6 @@
         '../crypto/crypto_nacl.gyp:crypto_nacl',
         '../jingle/jingle_nacl.gyp:jingle_glue_nacl',
         '../media/media_nacl.gyp:media_yuv_nacl',
-        '../native_client/tools.gyp:prep_toolchain',
         '../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
         '../net/net_nacl.gyp:net_nacl',
         '../ppapi/native_client/native_client.gyp:ppapi_lib',
diff --git a/remoting/remoting_options.gni b/remoting/remoting_options.gni
new file mode 100644
index 0000000..9a62253
--- /dev/null
+++ b/remoting/remoting_options.gni
@@ -0,0 +1,33 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Set this to run the jscompile checks after building the webapp.
+run_jscompile = 0
+
+# Set this to enable cast mode on the android client.
+enable_cast = 0
+
+# Set this to use GCD instead of the remoting directory service.
+remoting_use_gcd = 0
+
+# Enable the multi-process host on Windows by default.
+if (is_win) {
+  remoting_multi_process = 1
+} else {
+  remoting_multi_process = 0
+}
+
+remoting_rdp_session = 1
+
+branding_path = "../remoting/branding_<(branding)"
+
+# The ar_service_environment variable is used to define the target
+# environment for the app being built.
+# The allowed values are dev, test, staging, prod, and prod-testing.
+if (is_debug) {
+  ar_service_environment = "dev"
+} else {
+  # Non-dev builds should default to 'prod'.
+  ar_service_environment = "prod"
+}
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi
index c4274743..2e98b04 100644
--- a/remoting/remoting_webapp_files.gypi
+++ b/remoting/remoting_webapp_files.gypi
@@ -72,6 +72,7 @@
       'webapp/base/js/ipc_unittest.js',
       'webapp/base/js/protocol_extension_manager_unittest.js',
       'webapp/crd/js/apps_v2_migration_unittest.js',
+      'webapp/crd/js/client_session_unittest.js',
       'webapp/crd/js/desktop_viewport_unittest.js',
       'webapp/crd/js/client_session_factory_unittest.js',
       'webapp/crd/js/dns_blackhole_checker_unittest.js',
diff --git a/remoting/resources/BUILD.gn b/remoting/resources/BUILD.gn
index 05aab92..d28753b 100644
--- a/remoting/resources/BUILD.gn
+++ b/remoting/resources/BUILD.gn
@@ -59,7 +59,7 @@
            ] + rebase_path(sources_to_verify, root_build_dir)
 
     deps = [
-      "//remoting/webapp:html",
+      "//remoting/webapp:main_html",
     ]  # Generates main.html.
   }
 }  # if false
diff --git a/remoting/webapp/BUILD.gn b/remoting/webapp/BUILD.gn
index 67af8ea1..02b6667 100644
--- a/remoting/webapp/BUILD.gn
+++ b/remoting/webapp/BUILD.gn
@@ -2,12 +2,49 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Keep in sync with 'remoting_webapp_html' target in
-# remoting/remoting_client.gypi.
+# Keep in sync with targets in remoting/remoting_client.gypi.
 
-import("//remoting/webapp/files.gni")
+import("//build/config/features.gni")
+import("//remoting/webapp/build_template.gni")
 
-action("html") {
+group("webapp") {
+  deps = [
+    ":webapp_v1",
+  ]
+
+  if (enable_nacl) {
+    deps += [ ":webapp_v2" ]
+  }
+}
+
+remoting_webapp("webapp_v1") {
+  webapp_type = "v1"
+  output_dir = "remoting.webapp"
+  zip_path = "remoting-webapp.zip"
+  extra_files = []
+}
+
+remoting_webapp("webapp_v2") {
+  webapp_type = "v2_pnacl"
+  output_dir = "remoting.webapp.v2"
+  zip_path = "remoting-webapp.v2.zip"
+  extra_files = [
+    "crd/remoting_client_pnacl.nmf.jinja2",
+    # TODO(garykac): Get correct path to this.
+    #"<(PRODUCT_DIR)/remoting_client_plugin_newlib.pexe",
+  ]
+}
+
+group("html") {
+  deps = [
+    ":background_html",
+    ":main_html",
+    ":message_window_html",
+    ":wcs_sandbox_html",
+  ]
+}
+
+action("main_html") {
   script = "build-html.py"
 
   inputs = [ remoting_webapp_template_main ] + remoting_webapp_template_files +
@@ -17,23 +54,72 @@
     "$target_gen_dir/main.html",
   ]
 
-  # Template files are relative to this directory. This passes some template
-  # files to the script, and the script reads templates from the files on disk.
-  # They all have to be relative to the same directory. The GYP build made all
-  # of these relative to the remoting directory, so this does the same.
-  template_rel_dir = "//remoting"
-
   args = [
     rebase_path("$target_gen_dir/main.html", root_build_dir),
     rebase_path(remoting_webapp_template_main, root_build_dir),
   ]
   args += [
     "--template-dir",
-    rebase_path(template_rel_dir, root_build_dir),
+    rebase_path(remoting_dir, root_build_dir),
   ]
   args += [ "--templates" ] +
-          rebase_path(remoting_webapp_template_files, template_rel_dir)
-  args += [ "--js" ] + rebase_path(remoting_webapp_crd_main_html_all_js_files,
-                                   template_rel_dir)
+          rebase_path(remoting_webapp_template_files, remoting_dir)
+  args += [ "--js" ] +
+          rebase_path(remoting_webapp_crd_main_html_all_js_files, remoting_dir)
 }
-# TODO(GYP) wcs_sandbox.html, background.html, message_window.html
+
+action("wcs_sandbox_html") {
+  script = "build-html.py"
+
+  inputs = [ remoting_webapp_template_wcs_sandbox ] +
+           remoting_webapp_wcs_sandbox_html_all_js_files
+
+  outputs = [
+    "$target_gen_dir/wcs_sandbox.html",
+  ]
+
+  args = [
+    rebase_path("$target_gen_dir/wcs_sandbox.html", root_build_dir),
+    rebase_path(remoting_webapp_template_wcs_sandbox, root_build_dir),
+  ]
+  args +=
+      [ "--js" ] +
+      rebase_path(remoting_webapp_wcs_sandbox_html_all_js_files, remoting_dir)
+}
+
+action("background_html") {
+  script = "build-html.py"
+
+  inputs = [ remoting_webapp_template_background ] +
+           remoting_webapp_background_html_all_js_files
+
+  outputs = [
+    "$target_gen_dir/background.html",
+  ]
+
+  args = [
+    rebase_path("$target_gen_dir/background.html", root_build_dir),
+    rebase_path(remoting_webapp_template_background, root_build_dir),
+  ]
+  args += [ "--js" ] + rebase_path(remoting_webapp_background_html_all_js_files,
+                                   remoting_dir)
+}
+
+action("message_window_html") {
+  script = "build-html.py"
+
+  inputs = [ remoting_webapp_template_message_window ] +
+           remoting_webapp_message_window_html_all_js_files
+
+  outputs = [
+    "$target_gen_dir/message_window.html",
+  ]
+
+  args = [
+    rebase_path("$target_gen_dir/message_window.html", root_build_dir),
+    rebase_path(remoting_webapp_template_message_window, root_build_dir),
+  ]
+  args +=
+      [ "--js" ] + rebase_path(remoting_webapp_message_window_html_all_js_files,
+                               remoting_dir)
+}
diff --git a/remoting/webapp/browser_test/timeout_waiter.js b/remoting/webapp/browser_test/timeout_waiter.js
index fd75ada..cb1a3a4 100644
--- a/remoting/webapp/browser_test/timeout_waiter.js
+++ b/remoting/webapp/browser_test/timeout_waiter.js
@@ -34,31 +34,32 @@
  * @return {Promise}
  */
 browserTest.waitFor = function(predicate, opt_timeout) {
-  /**
-   * @param {function():void} fulfill
-   * @param {function(Error):void} reject
-   */
-  return new Promise(function (fulfill, reject) {
-    if (opt_timeout === undefined) {
-      opt_timeout = browserTest.Timeout.DEFAULT;
-    }
+  return new Promise(
+      /**
+       * @param {function(boolean):void} fulfill
+       * @param {function(Error):void} reject
+       */
+      function (fulfill, reject) {
+        if (opt_timeout === undefined) {
+          opt_timeout = browserTest.Timeout.DEFAULT;
+        }
 
-    var timeout = /** @type {number} */ (opt_timeout);
-    var end = Number(Date.now()) + timeout;
-    var testPredicate = function() {
-      if (predicate.evaluate()) {
-        console.log(predicate.description() + ' satisfied.');
-        fulfill(true);
-      } else if (Date.now() >= end) {
-        reject(new Error('Timed out (' + opt_timeout + 'ms) waiting for ' +
-                         predicate.description()));
-      } else {
-        console.log(predicate.description() + ' not yet satisfied.');
-        window.setTimeout(testPredicate, 500);
-      }
-    };
-    testPredicate();
-  });
+        var timeout = /** @type {number} */ (opt_timeout);
+        var end = Number(Date.now()) + timeout;
+        var testPredicate = function() {
+          if (predicate.evaluate()) {
+            console.log(predicate.description() + ' satisfied.');
+            fulfill(true);
+          } else if (Date.now() >= end) {
+            reject(new Error('Timed out (' + opt_timeout + 'ms) waiting for ' +
+                             predicate.description()));
+          } else {
+            console.log(predicate.description() + ' not yet satisfied.');
+            window.setTimeout(testPredicate, 500);
+          }
+        };
+        testPredicate();
+      });
 };
 
 /**
diff --git a/remoting/webapp/build_template.gni b/remoting/webapp/build_template.gni
new file mode 100644
index 0000000..d1e2265
--- /dev/null
+++ b/remoting/webapp/build_template.gni
@@ -0,0 +1,95 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Keep in sync with 'remoting_webapp' target in remoting/remoting_client.gypi.
+
+import("//remoting/remoting_locales.gni")
+import("//remoting/remoting_options.gni")
+import("//remoting/remoting_version.gni")
+import("//remoting/webapp/files.gni")
+
+# The base remoting directory that is used as the root directory for file
+# references. Many of the scripts rely on the files being specified relative
+# to this directory.
+remoting_dir = "//remoting"
+
+template("remoting_webapp") {
+  locales_listfile = target_name + "_locales"
+  listfile = "$target_gen_dir/${target_name}_locales.txt"
+  listfile_rel = rebase_path(listfile, root_build_dir)
+
+  action(locales_listfile) {
+    script = "../tools/build/remoting_localize.py"
+
+    inputs = []
+    outputs = [
+      listfile,
+    ]
+
+    args = [
+      "--locale_output",
+      rebase_path(webapp_locale_dir, root_build_dir) +
+          "/@{json_suffix}/messages.json",
+      "--locales_listfile",
+      listfile_rel,
+    ]
+    args += remoting_locales
+  }
+
+  action(target_name) {
+    script = "build-webapp.py"
+
+    webapp_type = invoker.webapp_type
+    output_dir = invoker.output_dir
+    zip_path = invoker.zip_path
+    extra_files = invoker.extra_files
+
+    inputs = []
+    outputs = [
+      "$target_gen_dir/$zip_path",
+    ]
+
+    deps = [
+      ":html",
+      ":$locales_listfile",
+      "//remoting/resources",
+    ]
+
+    buildtype = "Dev"
+    if (!is_debug) {
+      if (is_official_build) {
+        buildtype = "Official"
+      } else {
+        buildtype = "Release"
+      }
+    }
+
+    generated_html_files = [
+      "$target_gen_dir/background.html",
+      "$target_gen_dir/main.html",
+      "$target_gen_dir/message_window.html",
+      "$target_gen_dir/wcs_sandbox.html",
+    ]
+
+    args = [
+      buildtype,
+      version_full,
+      output_dir,
+      zip_path,
+      rebase_path("crd/manifest.json.jinja2", root_build_dir),
+      webapp_type,
+    ]
+    args += rebase_path(generated_html_files, root_build_dir)
+    args += rebase_path(remoting_webapp_crd_files, root_build_dir)
+    args += rebase_path(extra_files, root_build_dir)
+    args += [
+      "--locales_listfile",
+      listfile_rel,
+    ]
+    args += [
+      "--use_gcd",
+      "$remoting_use_gcd",
+    ]
+  }
+}
diff --git a/remoting/webapp/crd/js/app_launcher.js b/remoting/webapp/crd/js/app_launcher.js
index e5f158d..fc28ab7 100644
--- a/remoting/webapp/crd/js/app_launcher.js
+++ b/remoting/webapp/crd/js/app_launcher.js
@@ -52,38 +52,41 @@
 remoting.V1AppLauncher.prototype.launch = function(opt_launchArgs) {
   var url = base.urlJoin('main.html', opt_launchArgs);
 
-  /**
-   * @param {function(*=):void} resolve
-   * @param {function(*=):void} reject
-   */
-  return new Promise(function(resolve, reject) {
-      chrome.tabs.create({ url: url, selected: true },
-        /** @param {chrome.Tab} tab The created tab. */
-        function(tab) {
-          if (!tab) {
-            reject(new Error(chrome.runtime.lastError.message));
-          } else {
-            resolve(String(tab.id));
-          }
-      });
-  });
+  return new Promise(
+      /**
+       * @param {function(*=):void} resolve
+       * @param {function(*=):void} reject
+       */
+      function(resolve, reject) {
+        chrome.tabs.create({ url: url, selected: true },
+            /** @param {chrome.Tab} tab The created tab. */
+            function(tab) {
+              if (!tab) {
+                reject(new Error(chrome.runtime.lastError.message));
+              } else {
+                resolve(String(tab.id));
+              }
+            });
+       });
 };
 
 remoting.V1AppLauncher.prototype.close = function(id) {
-  /**
-   * @param {function(*=):void} resolve
-   * @param {function(*=):void} reject
-   */
-  return new Promise(function(resolve, reject) {
-    /** @param {chrome.Tab} tab The retrieved tab. */
-    chrome.tabs.get(id, function(tab) {
-      if (!tab) {
-        reject(new Error(chrome.runtime.lastError.message));
-      } else {
-        chrome.tabs.remove(tab.id, /** @type {function(*=):void} */ (resolve));
-      }
-    });
-  });
+  return new Promise(
+      /**
+       * @param {function(*=):void} resolve
+       * @param {function(*=):void} reject
+       */
+      function(resolve, reject) {
+        chrome.tabs.get(id,
+            /** @param {chrome.Tab} tab The retrieved tab. */
+            function(tab) {
+              if (!tab) {
+                reject(new Error(chrome.runtime.lastError.message));
+              } else {
+                chrome.tabs.remove(tab.id, /** function(*=):void */ (resolve));
+              }
+            });
+      });
 };
 
 
@@ -110,49 +113,51 @@
 remoting.V2AppLauncher.prototype.launch = function(opt_launchArgs) {
   var url = base.urlJoin(APP_MAIN_URL, opt_launchArgs);
 
-  /**
-   * @param {function(*=):void} resolve
-   * @param {function(*=):void} reject
-   */
-  return new Promise(function(resolve, reject) {
-    var START_FULLSCREEN = 'start-fullscreen';
-    /** @param {Object} values */
-    var onValues = function(values) {
-      /** @type {string} */
-      var state = values[START_FULLSCREEN] ? 'fullscreen' : 'normal';
-      chrome.app.window.create(url, {
-          'width': 800,
-          'height': 600,
-          'frame': 'none',
-          'id': String(getNextWindowId()),
-          'state': state
-        },
-        /** @param {AppWindow=} appWindow */
-        function(appWindow) {
-          if (!appWindow) {
-            reject(new Error(chrome.runtime.lastError.message));
-          } else {
-            resolve(appWindow.id);
-          }
-        });
-    };
-    chrome.storage.local.get(START_FULLSCREEN, onValues);
-  });
+  return new Promise(
+      /**
+       * @param {function(*=):void} resolve
+       * @param {function(*=):void} reject
+       */
+      function(resolve, reject) {
+        var START_FULLSCREEN = 'start-fullscreen';
+        /** @param {Object} values */
+        var onValues = function(values) {
+          /** @type {string} */
+          var state = values[START_FULLSCREEN] ? 'fullscreen' : 'normal';
+          chrome.app.window.create(url, {
+              'width': 800,
+              'height': 600,
+              'frame': 'none',
+              'id': String(getNextWindowId()),
+              'state': state
+            },
+            /** @param {AppWindow=} appWindow */
+            function(appWindow) {
+              if (!appWindow) {
+                reject(new Error(chrome.runtime.lastError.message));
+              } else {
+                resolve(appWindow.id);
+              }
+            });
+        };
+        chrome.storage.local.get(START_FULLSCREEN, onValues);
+      });
 };
 
 remoting.V2AppLauncher.prototype.close = function(id) {
-  /**
-   * @param {function(*=):void} resolve
-   * @param {function(*=):void} reject
-   */
-  return new Promise(function(resolve, reject) {
-    var appWindow = chrome.app.window.get(id);
-    if (!appWindow) {
-      return Promise.reject(new Error(chrome.runtime.lastError.message));
-    }
-    appWindow.onClosed.addListener(resolve);
-    appWindow.close();
-  });
+  return new Promise(
+      /**
+       * @param {function(*=):void} resolve
+       * @param {function(*=):void} reject
+       */
+      function(resolve, reject) {
+        var appWindow = chrome.app.window.get(id);
+        if (!appWindow) {
+          return Promise.reject(new Error(chrome.runtime.lastError.message));
+        }
+        appWindow.onClosed.addListener(resolve);
+        appWindow.close();
+      });
 };
 
 /**
diff --git a/remoting/webapp/crd/js/client_plugin_host_desktop_impl.js b/remoting/webapp/crd/js/client_plugin_host_desktop_impl.js
index 74ba989..94ed9d27 100644
--- a/remoting/webapp/crd/js/client_plugin_host_desktop_impl.js
+++ b/remoting/webapp/crd/js/client_plugin_host_desktop_impl.js
@@ -15,7 +15,7 @@
 'use strict';
 
 /**
- * @param {remoting.ClientPluginImpl} plugin
+ * @param {remoting.ClientPlugin} plugin
  * @param {function(Object):void} postMessageCallback Callback to post a message
  *   to the Client Plugin.
  *
diff --git a/remoting/webapp/crd/js/client_plugin_impl.js b/remoting/webapp/crd/js/client_plugin_impl.js
index b441ef6d..6248956 100644
--- a/remoting/webapp/crd/js/client_plugin_impl.js
+++ b/remoting/webapp/crd/js/client_plugin_impl.js
@@ -83,11 +83,12 @@
 
   /** @type {remoting.ClientPluginImpl} */
   var that = this;
-  /** @param {Event} event Message event from the plugin. */
-  this.plugin_.addEventListener('message', function(event) {
-      that.handleMessage_(
-          /** @type {remoting.ClientPluginMessage} */ (event.data));
-    }, false);
+  this.plugin_.addEventListener('message',
+        /** @param {Event} event Message event from the plugin. */
+        function(event) {
+          that.handleMessage_(
+              /** @type {remoting.ClientPluginMessage} */ (event.data));
+        }, false);
 
   if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') {
     window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500);
diff --git a/remoting/webapp/crd/js/client_session.js b/remoting/webapp/crd/js/client_session.js
index 2737658..8a6bdb87 100644
--- a/remoting/webapp/crd/js/client_session.js
+++ b/remoting/webapp/crd/js/client_session.js
@@ -302,10 +302,6 @@
   var state = error.isNone() ?
                   remoting.ClientSession.State.CLOSED :
                   remoting.ClientSession.State.FAILED;
-
-  // The plugin won't send a state change notification, so we explicitly log
-  // the fact that the connection has closed.
-  this.logToServer_.logClientSessionStateChange(state, error);
   this.error_ = error;
   this.setState_(state);
 };
@@ -496,6 +492,7 @@
   var finishedStates = [
     remoting.ClientSession.State.CLOSED,
     remoting.ClientSession.State.FAILED,
+    remoting.ClientSession.State.CONNECTION_CANCELED,
     remoting.ClientSession.State.CONNECTION_DROPPED
   ];
   return finishedStates.indexOf(this.getState()) !== -1;
@@ -557,9 +554,12 @@
       this.listener_.onDisconnected();
       break;
 
+    case remoting.ClientSession.State.CONNECTION_CANCELED:
     case remoting.ClientSession.State.FAILED:
       error = this.getError();
-      console.error('Connection failed: ' + error.toString());
+      if (!error.isNone()) {
+        console.error('Connection failed: ' + error.toString());
+      }
       this.listener_.onConnectionFailed(error);
       break;
 
diff --git a/remoting/webapp/crd/js/client_session_factory_unittest.js b/remoting/webapp/crd/js/client_session_factory_unittest.js
index f0e884c..819378c1 100644
--- a/remoting/webapp/crd/js/client_session_factory_unittest.js
+++ b/remoting/webapp/crd/js/client_session_factory_unittest.js
@@ -6,18 +6,12 @@
 
 'use strict';
 
-var originalPluginFactory;
-var originalIdentity;
-var originalSettings;
-
-/** @type {remoting.MockSignalStrategy} */
-var mockSignalStrategy;
+/** @type {remoting.MockConnection} */
+var mockConnection;
 /** @type {remoting.ClientSessionFactory} */
 var factory;
 /** @type {remoting.ClientSession.EventHandler} */
 var listener;
-/** @type {sinon.TestStub} */
-var createSignalStrategyStub;
 
 /**
  * @constructor
@@ -31,69 +25,70 @@
 
 QUnit.module('ClientSessionFactory', {
   beforeEach: function() {
-    originalPluginFactory = remoting.ClientPlugin.factory;
-    remoting.ClientPlugin.factory = new remoting.MockClientPluginFactory();
-
-    mockSignalStrategy = new remoting.MockSignalStrategy(
-        'jid', remoting.SignalStrategy.Type.XMPP);
-    createSignalStrategyStub = sinon.stub(remoting.SignalStrategy, 'create');
-    createSignalStrategyStub.returns(mockSignalStrategy);
-    listener = new SessionListener();
-
-    originalIdentity = remoting.identity;
-    remoting.identity = new remoting.Identity();
     chromeMocks.activate(['identity']);
     chromeMocks.identity.mock$setToken('fake_token');
 
-    originalSettings = remoting.settings;
-    remoting.settings = new remoting.Settings();
-
-    remoting.identity.getUserInfo = function() {
-      return { email: 'email', userName: 'userName'};
-    };
-
+    mockConnection = new remoting.MockConnection();
+    listener = new SessionListener();
     factory = new remoting.ClientSessionFactory(
-      document.createElement('div'), ['fake_capability']);
+        document.createElement('div'),
+        [remoting.ClientSession.Capability.VIDEO_RECORDER]);
   },
   afterEach: function() {
-    remoting.settings = originalSettings;
-    remoting.identity = originalIdentity;
+    mockConnection.restore();
     chromeMocks.restore();
-    remoting.identity = null;
-    remoting.ClientPlugin.factory = originalPluginFactory;
-    createSignalStrategyStub.restore();
   }
 });
 
 QUnit.test('createSession() should return a remoting.ClientSession',
     function(assert) {
-
-  mockSignalStrategy.connect = function() {
-    mockSignalStrategy.setStateForTesting(
-        remoting.SignalStrategy.State.CONNECTED);
-  };
-
   return factory.createSession(listener).then(
     function(/** remoting.ClientSession */ session){
       assert.ok(session instanceof remoting.ClientSession);
+      assert.ok(
+          mockConnection.plugin().hasCapability(
+              remoting.ClientSession.Capability.VIDEO_RECORDER),
+          'Capability is set correctly.');
   });
 });
 
 QUnit.test('createSession() should reject on signal strategy failure',
     function(assert) {
-
+  var mockSignalStrategy = mockConnection.signalStrategy();
   mockSignalStrategy.connect = function() {
-    mockSignalStrategy.setStateForTesting(remoting.SignalStrategy.State.FAILED);
+    Promise.resolve().then(function () {
+      mockSignalStrategy.setStateForTesting(
+          remoting.SignalStrategy.State.FAILED);
+    });
   };
 
-  var signalStrategyDispose =
-      /** @type {sinon.Spy} */ (sinon.spy(mockSignalStrategy, 'dispose'));
+  var signalStrategyDispose = sinon.stub(mockSignalStrategy, 'dispose');
 
   return factory.createSession(listener).then(
-    assert.ok.bind(assert, false, 'Expect createSession to fail')
+    assert.ok.bind(assert, false, 'Expect createSession() to fail.')
   ).catch(function(/** remoting.Error */ error) {
-    assert.ok(signalStrategyDispose.called);
-    assert.equal(error.getDetail(), 'setStateForTesting');
+    assert.ok(
+        signalStrategyDispose.called, 'SignalStrategy is disposed on failure.');
+    assert.equal(error.getDetail(), 'setStateForTesting',
+                 'Error message is set correctly.');
+  });
+});
+
+QUnit.test('createSession() should reject on plugin initialization failure',
+    function(assert) {
+  var mockSignalStrategy = mockConnection.signalStrategy();
+  var plugin = mockConnection.plugin();
+  plugin.mock$initializationResult = false;
+
+  var signalStrategyDispose = sinon.stub(mockSignalStrategy, 'dispose');
+
+  return factory.createSession(listener).then(function() {
+    assert.ok(false, 'Expect createSession() to fail.');
+  }).catch(function(/** remoting.Error */ error) {
+    assert.ok(
+        signalStrategyDispose.called, 'SignalStrategy is disposed on failure.');
+    assert.ok(error.hasTag(remoting.Error.Tag.MISSING_PLUGIN),
+        'Initialization failed with MISSING_PLUGIN.');
   });
 });
 
diff --git a/remoting/webapp/crd/js/client_session_unittest.js b/remoting/webapp/crd/js/client_session_unittest.js
new file mode 100644
index 0000000..503b83d
--- /dev/null
+++ b/remoting/webapp/crd/js/client_session_unittest.js
@@ -0,0 +1,177 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+
+'use strict';
+
+/** @type {remoting.MockConnection} */
+var mockConnection;
+/** @type {remoting.ClientSession} */
+var session;
+/** @type {remoting.ClientSession.EventHandler} */
+var listener;
+/** @type {sinon.TestStub} */
+var logToServerStub;
+
+/**
+ * @constructor
+ * @implements {remoting.ClientSession.EventHandler}
+ */
+var SessionListener = function() {};
+SessionListener.prototype.onConnectionFailed = function(error) {};
+SessionListener.prototype.onConnected = function(connectionInfo) {};
+SessionListener.prototype.onDisconnected = function() {};
+SessionListener.prototype.onError = function(error) {};
+
+/**
+ * @param {remoting.ClientSession.ConnectionError=} opt_error
+ * @return {Promise}
+ */
+function connect(opt_error) {
+  var deferred = new base.Deferred();
+  var host = new remoting.Host('fake_hostId');
+  host.jabberId = 'fake_jid';
+
+  var plugin = mockConnection.plugin();
+  var State = remoting.ClientSession.State;
+
+  plugin.mock$onConnect().then(function() {
+    plugin.mock$setConnectionStatus(State.CONNECTING);
+  }).then(function() {
+    var status = (opt_error) ? State.FAILED : State.CONNECTED;
+    plugin.mock$setConnectionStatus(status, opt_error);
+  });
+
+  session.connect(host, new remoting.CredentialsProvider({
+    pairingInfo: { clientId: 'fake_clientId', sharedSecret: 'fake_secret' }
+  }));
+
+  listener.onConnected = function() {
+    deferred.resolve();
+  };
+
+  listener.onConnectionFailed = function(/** remoting.Error */ error) {
+    deferred.reject(error);
+  };
+
+  return deferred.promise();
+}
+
+QUnit.module('ClientSession', {
+  beforeEach: function() {
+    chromeMocks.activate(['identity']);
+    chromeMocks.identity.mock$setToken('fake_token');
+
+    mockConnection = new remoting.MockConnection();
+    listener = new SessionListener();
+
+    var sessionFactory = new remoting.ClientSessionFactory(
+      document.createElement('div'), ['fake_capability']);
+
+    return sessionFactory.createSession(listener).then(function(clientSession) {
+      session = clientSession;
+      logToServerStub =
+          sinon.stub(session.getLogger(), 'logClientSessionStateChange');
+    });
+  },
+  afterEach: function() {
+    session.dispose();
+    mockConnection.restore();
+    chromeMocks.restore();
+  }
+});
+
+QUnit.test('should raise CONNECTED event on connected', function(assert) {
+  return connect().then(function(){
+    assert.ok(true, 'Expect session to connect.');
+  });
+});
+
+QUnit.test('onOutgoingIq() should send Iq to signalStrategy', function(assert) {
+  var sendMessage = sinon.stub(mockConnection.signalStrategy(), 'sendMessage');
+  return connect().then(function(){
+    session.onOutgoingIq('sample message');
+    assert.ok(sendMessage.calledWith('sample message'));
+  });
+});
+
+QUnit.test('should foward Iq from signalStrategy to plugin', function(assert) {
+  var onIncomingIq = sinon.stub(mockConnection.plugin(), 'onIncomingIq');
+  return connect().then(function() {
+    var stanza = new DOMParser()
+                     .parseFromString('<iq>sample</iq>', 'text/xml')
+                     .firstElementChild;
+    mockConnection.signalStrategy().mock$onIncomingStanza(stanza);
+    assert.ok(onIncomingIq.calledWith('<iq>sample</iq>'));
+  });
+});
+
+QUnit.test('logHostOfflineErrors(false) should suppress offline errors',
+  function(assert) {
+
+  session.logHostOfflineErrors(false);
+
+  var PluginError = remoting.ClientSession.ConnectionError;
+  var State = remoting.ClientSession.State;
+
+  return connect(PluginError.HOST_IS_OFFLINE).then(function() {
+    assert.ok(false, 'Expect connection to fail');
+  }).catch(function(/** remoting.Error */ error) {
+    assert.ok(error.hasTag(remoting.Error.Tag.HOST_IS_OFFLINE));
+    assert.equal(logToServerStub.args[1][0], State.CONNECTION_CANCELED);
+    var errorLogged = /** @type {remoting.Error} */(logToServerStub.args[1][1]);
+    assert.equal(errorLogged.getTag(), remoting.Error.Tag.HOST_IS_OFFLINE);
+
+  });
+});
+
+QUnit.test('disconnect() should raise the CLOSED event', function(assert) {
+  return connect().then(function() {
+    var onDisconnected = sinon.stub(listener, 'onDisconnected');
+    session.disconnect(remoting.Error.none());
+    assert.equal(onDisconnected.callCount, 1);
+  });
+});
+
+QUnit.test(
+  'Connection error after CONNECTED should raise the CONNECTION_DROPPED event',
+  function(assert) {
+
+  var State = remoting.ClientSession.State;
+
+  return connect().then(function() {
+    var onError = sinon.stub(listener, 'onError');
+    session.disconnect(new remoting.Error(remoting.Error.Tag.P2P_FAILURE));
+    assert.equal(onError.callCount, 1);
+    assert.equal(logToServerStub.args[2][0], State.CONNECTION_DROPPED);
+  });
+});
+
+QUnit.test(
+  'Connection error before CONNECTED should raise the CONNECTION_FAILED event',
+  function(assert) {
+
+  session.logHostOfflineErrors(true);
+
+  var PluginError = remoting.ClientSession.ConnectionError;
+  var State = remoting.ClientSession.State;
+
+  return connect(PluginError.SESSION_REJECTED).then(function() {
+    assert.ok(false, 'Expect connection to fail');
+  }).catch(function(/** remoting.Error */ error) {
+    assert.ok(error.hasTag(remoting.Error.Tag.INVALID_ACCESS_CODE));
+    assert.equal(logToServerStub.args[1][0], State.FAILED);
+    var errorLogged = /** @type {remoting.Error} */(logToServerStub.args[1][1]);
+    assert.equal(errorLogged.getTag(), remoting.Error.Tag.INVALID_ACCESS_CODE);
+  });
+});
+
+QUnit.test('dispose() should dispose the plugin', function(assert) {
+  var pluginDispose = sinon.stub(mockConnection.plugin(), 'dispose');
+  session.dispose();
+  assert.equal(pluginDispose.callCount, 1);
+});
+
+})();
diff --git a/remoting/webapp/crd/js/dns_blackhole_checker_unittest.js b/remoting/webapp/crd/js/dns_blackhole_checker_unittest.js
index 601157b..46abdd4f 100644
--- a/remoting/webapp/crd/js/dns_blackhole_checker_unittest.js
+++ b/remoting/webapp/crd/js/dns_blackhole_checker_unittest.js
@@ -37,7 +37,7 @@
     onStateChange = sinon.spy();
     onIncomingStanzaCallback = sinon.spy();
     signalStrategy = new remoting.MockSignalStrategy();
-    sinon.spy(signalStrategy, 'connect');
+    sinon.stub(signalStrategy, 'connect', base.doNothing);
     checker = new remoting.DnsBlackholeChecker(signalStrategy);
 
     checker.setStateChangedCallback(onStateChange);
diff --git a/remoting/webapp/crd/js/host_installer.js b/remoting/webapp/crd/js/host_installer.js
index 3ff1013b..c8a15a3 100644
--- a/remoting/webapp/crd/js/host_installer.js
+++ b/remoting/webapp/crd/js/host_installer.js
@@ -47,31 +47,32 @@
   // Always do a fresh check as we don't get notified when the host is
   // uninstalled.
 
-  /** @param {function(*=):void} resolve */
-  return new Promise(function(resolve) {
-    // TODO(kelvinp): Use different native messaging ports for the Me2me host
-    // vs It2MeHost.
-    /** @type {chrome.runtime.Port} */
-    var port =
-        chrome.runtime.connectNative('com.google.chrome.remote_assistance');
+  return new Promise(
+      /** @param {function(*=):void} resolve */
+      function(resolve) {
+        // TODO(kelvinp): Use different native messaging ports for the Me2me
+        // host vs It2MeHost.
+        /** @type {chrome.runtime.Port} */
+        var port =
+            chrome.runtime.connectNative('com.google.chrome.remote_assistance');
 
-    function onMessage() {
-      port.onDisconnect.removeListener(onDisconnected);
-      port.onMessage.removeListener(onMessage);
-      port.disconnect();
-      resolve(true);
-    }
+        function onMessage() {
+          port.onDisconnect.removeListener(onDisconnected);
+          port.onMessage.removeListener(onMessage);
+          port.disconnect();
+          resolve(true);
+        }
 
-    function onDisconnected() {
-      port.onDisconnect.removeListener(onDisconnected);
-      port.onMessage.removeListener(onMessage);
-      resolve(false);
-    }
+        function onDisconnected() {
+          port.onDisconnect.removeListener(onDisconnected);
+          port.onMessage.removeListener(onMessage);
+          resolve(false);
+        }
 
-    port.onDisconnect.addListener(onDisconnected);
-    port.onMessage.addListener(onMessage);
-    port.postMessage({type: 'hello'});
-  });
+        port.onDisconnect.addListener(onDisconnected);
+        port.onMessage.addListener(onMessage);
+        port.postMessage({type: 'hello'});
+      });
 };
 
 /** @type {Object<string,string>} */
diff --git a/remoting/webapp/crd/js/host_list.js b/remoting/webapp/crd/js/host_list.js
index 3b130ec..1678464 100644
--- a/remoting/webapp/crd/js/host_list.js
+++ b/remoting/webapp/crd/js/host_list.js
@@ -48,7 +48,7 @@
   /** @private {HTMLElement} */
   this.loadingIndicator_ = loadingIndicator;
   /** @private */
-  this.onError_ = onError;
+  this.onError_ = remoting.Error.handler(onError);
   /** @private */
   this.handleConnect_ = handleConnect;
 
@@ -152,8 +152,11 @@
     that.lastError_ = error;
     onDone(false);
   };
-  remoting.hostListApi.get(this.onHostListResponse_.bind(this, onDone),
-                           onError);
+  remoting.hostListApi.get().then(function(hosts) {
+    onDone(that.onHostListResponse_(hosts));
+  }).catch(
+    remoting.Error.handler(onError)
+  );
 };
 
 /**
@@ -161,18 +164,17 @@
  * include a JSON-encoded list of host descriptions, which we display if we're
  * able to successfully parse it.
  *
- * @param {function(boolean):void} onDone The callback passed to |refresh|.
  * @param {Array<remoting.Host>} hosts The list of hosts for the user.
- * @return {void} Nothing.
+ * @return {boolean}
  * @private
  */
-remoting.HostList.prototype.onHostListResponse_ = function(onDone, hosts) {
+remoting.HostList.prototype.onHostListResponse_ = function(hosts) {
   this.lastError_ = remoting.Error.none();
   this.hosts_ = hosts;
   this.sortHosts_();
   this.save_();
   this.loadingIndicator_.classList.remove('loading');
-  onDone(true);
+  return true;
 };
 
 /**
@@ -304,8 +306,8 @@
   if (index != -1) {
     this.hostTableEntries_.splice(index, 1);
   }
-  remoting.hostListApi.remove(hostTableEntry.host.hostId, base.doNothing,
-                              this.onError_);
+  remoting.hostListApi.remove(hostTableEntry.host.hostId).
+      catch(this.onError_);
 };
 
 /**
@@ -324,9 +326,8 @@
 
   remoting.hostListApi.put(hostTableEntry.host.hostId,
                            hostTableEntry.host.hostName,
-                           hostTableEntry.host.publicKey,
-                           function() {},
-                           this.onError_);
+                           hostTableEntry.host.publicKey).
+      catch(this.onError_);
 };
 
 /**
@@ -347,13 +348,14 @@
     return;
   }
 
-  var onRemoved = function() {
-    that.refresh(function() {
-      that.display();
-      onDone();
-    });
-  };
-  remoting.hostListApi.remove(hostId, onRemoved, this.onError_);
+  remoting.hostListApi.remove(hostId).
+      then(function() {
+        that.refresh(function() {
+          that.display();
+          onDone();
+        });
+      }).
+      catch(this.onError_);
 };
 
 /**
diff --git a/remoting/webapp/crd/js/host_list_api.js b/remoting/webapp/crd/js/host_list_api.js
index acdff97..9b63ccb 100644
--- a/remoting/webapp/crd/js/host_list_api.js
+++ b/remoting/webapp/crd/js/host_list_api.js
@@ -28,31 +28,28 @@
 /**
  * Fetch the list of hosts for a user.
  *
- * @param {function(Array<remoting.Host>):void} onDone
- * @param {function(!remoting.Error):void} onError
+ * @return {!Promise<!Array<!remoting.Host>>}
  */
-remoting.HostListApi.prototype.get = function(onDone, onError) {
+remoting.HostListApi.prototype.get = function() {
 };
 
 /**
  * Update the information for a host.
  *
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
  * @param {string} hostId
  * @param {string} hostName
  * @param {string} hostPublicKey
+ * @return {!Promise<void>}
  */
 remoting.HostListApi.prototype.put =
-    function(hostId, hostName, hostPublicKey, onDone, onError) {
+    function(hostId, hostName, hostPublicKey) {
 };
 
 /**
  * Delete a host.
  *
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
  * @param {string} hostId
+ * @return {!Promise<void>}
  */
-remoting.HostListApi.prototype.remove = function(hostId, onDone, onError) {
+remoting.HostListApi.prototype.remove = function(hostId) {
 };
diff --git a/remoting/webapp/crd/js/host_list_api_impl.js b/remoting/webapp/crd/js/host_list_api_impl.js
index 55b4868..9cfff10 100644
--- a/remoting/webapp/crd/js/host_list_api_impl.js
+++ b/remoting/webapp/crd/js/host_list_api_impl.js
@@ -56,39 +56,22 @@
   });
 };
 
-/**
- * Fetch the list of hosts for a user.
- *
- * @param {function(Array<remoting.Host>):void} onDone
- * @param {function(!remoting.Error):void} onError
- */
-remoting.HostListApiImpl.prototype.get = function(onDone, onError) {
-  /** @type {function(!remoting.Xhr.Response):void} */
-  var parseHostListResponse =
-      this.parseHostListResponse_.bind(this, onDone, onError);
-  /** @param {string} token */
-  var onToken = function(token) {
-    new remoting.Xhr({
-      method: 'GET',
-      url: remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts',
-      oauthToken: token
-    }).start().then(parseHostListResponse);
-  };
-  remoting.identity.getToken().then(onToken, remoting.Error.handler(onError));
+/** @override */
+remoting.HostListApiImpl.prototype.get = function() {
+  var that = this;
+  return new remoting.Xhr({
+    method: 'GET',
+    url: remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts',
+    useIdentity: true
+  }).start().then(function(/** !remoting.Xhr.Response */ response) {
+    return that.parseHostListResponse_(response);
+  });
 };
 
-/**
- * Update the information for a host.
- *
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
- * @param {string} hostId
- * @param {string} hostName
- * @param {string} hostPublicKey
- */
+/** @override */
 remoting.HostListApiImpl.prototype.put =
-    function(hostId, hostName, hostPublicKey, onDone, onError) {
-  new remoting.Xhr({
+    function(hostId, hostName, hostPublicKey) {
+  return new remoting.Xhr({
     method: 'PUT',
     url: remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts/' + hostId,
     jsonContent: {
@@ -99,23 +82,17 @@
       }
     },
     useIdentity: true
-  }).start().then(remoting.HostListApiImpl.defaultResponse_(onDone, onError));
+  }).start().then(remoting.HostListApiImpl.defaultResponse_());
 };
 
-/**
- * Delete a host.
- *
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
- * @param {string} hostId
- */
-remoting.HostListApiImpl.prototype.remove = function(hostId, onDone, onError) {
-  new remoting.Xhr({
+/** @override */
+remoting.HostListApiImpl.prototype.remove = function(hostId) {
+  return new remoting.Xhr({
     method: 'DELETE',
     url: remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts/' + hostId,
     useIdentity: true
   }).start().then(remoting.HostListApiImpl.defaultResponse_(
-      onDone, onError, [remoting.Error.Tag.NOT_FOUND]));
+      [remoting.Error.Tag.NOT_FOUND]));
 };
 
 /**
@@ -123,19 +100,17 @@
  * include a JSON-encoded list of host descriptions, which is parsed and
  * passed to the callback.
  *
- * @param {function(Array<remoting.Host>):void} onDone
- * @param {function(!remoting.Error):void} onError
  * @param {!remoting.Xhr.Response} response
+ * @return {!Array<!remoting.Host>}
  * @private
  */
-remoting.HostListApiImpl.prototype.parseHostListResponse_ =
-    function(onDone, onError, response) {
+remoting.HostListApiImpl.prototype.parseHostListResponse_ = function(response) {
   if (response.status == 200) {
     var obj = /** @type {{data: {items: Array}}} */
         (base.jsonParseSafe(response.getText()));
     if (!obj || !obj.data) {
       console.error('Invalid "hosts" response from server.');
-      onError(remoting.Error.unexpected());
+      throw remoting.Error.unexpected();
     } else {
       var items = obj.data.items || [];
       var hosts = items.map(
@@ -153,38 +128,33 @@
               base.getStringAttr(item, 'hostOfflineReason', '');
           return host;
       });
-      onDone(hosts);
+      return hosts;
     }
   } else {
-    onError(remoting.Error.fromHttpStatus(response.status));
+    throw remoting.Error.fromHttpStatus(response.status);
   }
 };
 
 /**
  * Generic success/failure response proxy.
  *
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
  * @param {Array<remoting.Error.Tag>=} opt_ignoreErrors
  * @return {function(!remoting.Xhr.Response):void}
  * @private
  */
-remoting.HostListApiImpl.defaultResponse_ = function(
-    onDone, onError, opt_ignoreErrors) {
+remoting.HostListApiImpl.defaultResponse_ = function(opt_ignoreErrors) {
   /** @param {!remoting.Xhr.Response} response */
   var result = function(response) {
     var error = remoting.Error.fromHttpStatus(response.status);
     if (error.isNone()) {
-      onDone();
       return;
     }
 
     if (opt_ignoreErrors && error.hasTag.apply(error, opt_ignoreErrors)) {
-      onDone();
       return;
     }
 
-    onError(error);
+    throw error;
   };
   return result;
 };
diff --git a/remoting/webapp/crd/js/log_to_server.js b/remoting/webapp/crd/js/log_to_server.js
index 87cb039e..e76f67a 100644
--- a/remoting/webapp/crd/js/log_to_server.js
+++ b/remoting/webapp/crd/js/log_to_server.js
@@ -29,6 +29,8 @@
   this.signalStrategy_ = signalStrategy;
   /** @private {string} */
   this.connectionType_ = '';
+  /** @private */
+  this.authTotalTime_ = 0;
 
   this.setSessionId_();
   signalStrategy.sendConnectionSetupResults(this);
@@ -171,8 +173,10 @@
  */
 remoting.LogToServer.prototype.log_ = function(entry) {
   // Log the time taken to get to this point from the time this session started.
+  // Exclude time taken for authorization.
   var sessionDurationInSeconds =
-      (new Date().getTime() - this.sessionStartTime_) / 1000.0;
+      (new Date().getTime() - this.sessionStartTime_ -
+          this.authTotalTime_) / 1000.0;
   entry.addSessionDuration(sessionDurationInSeconds);
 
   // Send the stanza to the debug log.
@@ -247,3 +251,12 @@
   }
   return idArray.join('');
 };
+
+/**
+ * @param {number} totalTime The value of time taken to complete authorization.
+ * @return {void} Nothing.
+ */
+remoting.LogToServer.prototype.setAuthTotalTime = function(totalTime) {
+  this.authTotalTime_ = totalTime;
+};
+
diff --git a/remoting/webapp/crd/js/me2me_activity.js b/remoting/webapp/crd/js/me2me_activity.js
index 7d2b090..0618464 100644
--- a/remoting/webapp/crd/js/me2me_activity.js
+++ b/remoting/webapp/crd/js/me2me_activity.js
@@ -104,8 +104,13 @@
    * @param {function(string):void} onPinFetched
    */
   var requestPin = function(supportsPairing, onPinFetched) {
+    // Set time when PIN was requested.
+    var authStartTime = new Date().getTime();
     that.pinDialog_.show(supportsPairing).then(function(/** string */ pin) {
       remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
+      // Done obtaining PIN information. Log time taken for PIN entry.
+      var logToServer = that.desktopActivity_.getSession().getLogger();
+      logToServer.setAuthTotalTime(new Date().getTime() - authStartTime);
       onPinFetched(pin);
     }).catch(function(/** remoting.Error */ error) {
       base.debug.assert(error.hasTag(remoting.Error.Tag.CANCELLED));
diff --git a/remoting/webapp/crd/js/mock_client_plugin.js b/remoting/webapp/crd/js/mock_client_plugin.js
index 698014749..1f2ba5c 100644
--- a/remoting/webapp/crd/js/mock_client_plugin.js
+++ b/remoting/webapp/crd/js/mock_client_plugin.js
@@ -7,25 +7,30 @@
  * Mock implementation of ClientPlugin for testing.
  */
 
-'use strict';
-
 /** @suppress {duplicate} */
 var remoting = remoting || {};
 
+(function() {
+
+'use strict';
+
 /**
- * @param {Element} container
  * @constructor
  * @implements {remoting.ClientPlugin}
  */
-remoting.MockClientPlugin = function(container) {
-  this.container_ = container;
+remoting.MockClientPlugin = function() {
+  /** @private {Element} */
+  this.container_ = null;
+  /** @private */
   this.element_ = /** @type {HTMLElement} */ (document.createElement('div'));
   this.element_.style.backgroundImage = 'linear-gradient(45deg, blue, red)';
-  this.container_.appendChild(this.element_);
-  this.hostDesktop_ = new remoting.MockClientPlugin.HostDesktop();
+  /** @private */
+  this.hostDesktop_ =
+      new remoting.ClientPlugin.HostDesktopImpl(this, base.doNothing);
+  /** @private */
   this.extensions_ = new remoting.ProtocolExtensionManager(base.doNothing);
-  /** @type {remoting.ClientPlugin.ConnectionEventHandler} */
-  this.connectionEventHandler = null;
+  /** @private {remoting.ClientPlugin.ConnectionEventHandler} */
+  this.connectionEventHandler_ = null;
 
   // Fake initialization result to return.
   this.mock$initializationResult = true;
@@ -35,6 +40,9 @@
       remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION,
       remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS
   ];
+
+  /** @private */
+  this.onConnectDeferred_ = new base.Deferred();
 };
 
 remoting.MockClientPlugin.prototype.dispose = function() {
@@ -65,13 +73,7 @@
 
 remoting.MockClientPlugin.prototype.connect =
     function(host, localJid, credentialsProvider) {
-  base.debug.assert(this.connectionEventHandler !== null);
-  var that = this;
-  window.requestAnimationFrame(function() {
-    that.connectionEventHandler.onConnectionStatusUpdate(
-          remoting.ClientSession.State.CONNECTED,
-          remoting.ClientSession.ConnectionError.NONE);
-  });
+  this.onConnectDeferred_.resolve();
 };
 
 remoting.MockClientPlugin.prototype.injectKeyCombination = function(keys) {};
@@ -125,7 +127,7 @@
 
 remoting.MockClientPlugin.prototype.setConnectionEventHandler =
     function(handler) {
-  this.connetionEventHandler = handler;
+  this.connectionEventHandler_ = handler;
 };
 
 remoting.MockClientPlugin.prototype.setMouseCursorHandler =
@@ -136,60 +138,28 @@
 remoting.MockClientPlugin.prototype.setDebugDirtyRegionHandler =
     function(handler) {};
 
-/**
- * @constructor
- * @implements {remoting.HostDesktop}
- * @extends {base.EventSourceImpl}
- */
-remoting.MockClientPlugin.HostDesktop = function() {
-  base.inherits(this, base.EventSourceImpl);
-  /** @private */
-  this.width_ = 0;
-  /** @private */
-  this.height_ = 0;
-  /** @private */
-  this.xDpi_ = 96;
-  /** @private */
-  this.yDpi_ = 96;
-  /** @private */
-  this.resizable_ = true;
-  this.defineEvents(base.values(remoting.HostDesktop.Events));
+/** @param {Element} container */
+remoting.MockClientPlugin.prototype.mock$setContainer = function(container) {
+  this.container_ = container;
+  this.container_.appendChild(this.element_);
+};
+
+/** @return {Promise} */
+remoting.MockClientPlugin.prototype.mock$onConnect = function() {
+  this.onConnectDeferred_ = new base.Deferred();
+  return this.onConnectDeferred_.promise();
 };
 
 /**
- * @return {{width:number, height:number, xDpi:number, yDpi:number}}
- * @override
+ * @param {remoting.ClientSession.State} status
+ * @param {remoting.ClientSession.ConnectionError=} opt_error
  */
-remoting.MockClientPlugin.HostDesktop.prototype.getDimensions = function() {
-  return {
-    width: this.width_,
-    height: this.height_,
-    xDpi: this.xDpi_,
-    yDpi: this.yDpi_
-  };
-};
-
-/**
- * @return {boolean}
- * @override
- */
-remoting.MockClientPlugin.HostDesktop.prototype.isResizable = function() {
-  return this.resizable_;
-};
-
-/**
- * @param {number} width
- * @param {number} height
- * @param {number} deviceScale
- * @override
- */
-remoting.MockClientPlugin.HostDesktop.prototype.resize =
-    function(width, height, deviceScale) {
-  this.width_ = width;
-  this.height_ = height;
-  this.xDpi_ = this.yDpi_ = Math.floor(deviceScale * 96);
-  this.raiseEvent(remoting.HostDesktop.Events.sizeChanged,
-                  this.getDimensions());
+remoting.MockClientPlugin.prototype.mock$setConnectionStatus = function(
+    status, opt_error) {
+  base.debug.assert(this.connectionEventHandler_ !== null);
+  var PluginError = remoting.ClientSession.ConnectionError;
+  var error = opt_error ? opt_error : PluginError.NONE;
+  this.connectionEventHandler_.onConnectionStatusUpdate(status, error);
 };
 
 /**
@@ -197,14 +167,72 @@
  * @implements {remoting.ClientPluginFactory}
  */
 remoting.MockClientPluginFactory = function() {
-  /** @private {remoting.MockClientPlugin} */
-  this.plugin_ = null;
+  /** @private */
+  this.plugin_ = new remoting.MockClientPlugin();
 };
 
 remoting.MockClientPluginFactory.prototype.createPlugin =
-    function(container, onExtensionMessage) {
-  this.plugin_ = new remoting.MockClientPlugin(container);
+    function(container, capabilities) {
+  this.plugin_.mock$setContainer(container);
+  this.plugin_.mock$capabilities = capabilities;
+  return this.plugin_;
+};
+
+/** @return {remoting.MockClientPlugin} */
+remoting.MockClientPluginFactory.prototype.plugin = function() {
   return this.plugin_;
 };
 
 remoting.MockClientPluginFactory.prototype.preloadPlugin = function() {};
+
+/**
+ * A class that sets up all the dependencies required for mocking a connection.
+ *
+ * @constructor
+ */
+remoting.MockConnection = function() {
+  /** @private */
+  this.originalPluginFactory_ = remoting.ClientPlugin.factory;
+
+  /** @private */
+  this.pluginFactory_ = new remoting.MockClientPluginFactory();
+  remoting.ClientPlugin.factory = this.pluginFactory_;
+
+  /** @private */
+  this.mockSignalStrategy_ = new remoting.MockSignalStrategy(
+      'fake_jid', remoting.SignalStrategy.Type.XMPP);
+
+  /** @private {sinon.TestStub} */
+  this.createSignalStrategyStub_ =
+      sinon.stub(remoting.SignalStrategy, 'create');
+  this.createSignalStrategyStub_.returns(this.mockSignalStrategy_);
+
+  /** @private */
+  this.originalIdentity_ = remoting.identity;
+  remoting.identity = new remoting.Identity();
+  var identityStub = sinon.stub(remoting.identity, 'getUserInfo');
+  identityStub.returns(Promise.resolve({email: 'email', userName: 'userName'}));
+
+  /** @private */
+  this.originalSettings_ = remoting.settings;
+  remoting.settings = new remoting.Settings();
+};
+
+/** @return {remoting.MockClientPlugin} */
+remoting.MockConnection.prototype.plugin = function() {
+  return this.pluginFactory_.plugin();
+};
+
+/** @return {remoting.MockSignalStrategy} */
+remoting.MockConnection.prototype.signalStrategy = function() {
+  return this.mockSignalStrategy_;
+};
+
+remoting.MockConnection.prototype.restore = function() {
+  remoting.settings = this.originalSettings_;
+  remoting.identity = this.originalIdentity_;
+  remoting.ClientPlugin.factory = this.originalPluginFactory_;
+  this.createSignalStrategyStub_.restore();
+};
+
+})();
\ No newline at end of file
diff --git a/remoting/webapp/crd/js/mock_host_list_api.js b/remoting/webapp/crd/js/mock_host_list_api.js
index 7d1516c0..b21462db 100644
--- a/remoting/webapp/crd/js/mock_host_list_api.js
+++ b/remoting/webapp/crd/js/mock_host_list_api.js
@@ -58,64 +58,58 @@
   }
 };
 
-/**
- * @param {function(Array<remoting.Host>):void} onDone
- * @param {function(!remoting.Error):void} onError
- */
-remoting.MockHostListApi.prototype.get = function(onDone, onError) {
-  remoting.mockIdentity.validateTokenAndCall(onDone, onError, [this.hosts]);
+/** @override */
+remoting.MockHostListApi.prototype.get = function() {
+  var that = this;
+  new Promise(function(resolve, reject) {
+    remoting.mockIdentity.validateTokenAndCall(
+        resolve, remoting.Error.handler(reject), [that.hosts]);
+  });
 };
 
-/**
- * @param {string} hostId
- * @param {string} hostName
- * @param {string} hostPublicKey
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
- */
+/** @override */
 remoting.MockHostListApi.prototype.put =
-    function(hostId, hostName, hostPublicKey, onDone, onError) {
+    function(hostId, hostName, hostPublicKey) {
   /** @type {remoting.MockHostListApi} */
   var that = this;
-  var onTokenValid = function() {
-    for (var i = 0; i < that.hosts.length; ++i) {
-      var host = that.hosts[i];
-      if (host.hostId == hostId) {
-        host.hostName = hostName;
-        host.hostPublicKey = hostPublicKey;
-        onDone();
-        return;
+  return new Promise(function(resolve, reject) {
+    var onTokenValid = function() {
+      for (var i = 0; i < that.hosts.length; ++i) {
+        var host = that.hosts[i];
+        if (host.hostId == hostId) {
+          host.hostName = hostName;
+          host.hostPublicKey = hostPublicKey;
+          resolve(undefined);
+          return;
+        }
       }
-    }
-    console.error('PUT request for unknown host: ' + hostId +
-                  ' (' + hostName + ')');
-    onError(remoting.Error.unexpected());
-  };
-  remoting.mockIdentity.validateTokenAndCall(onTokenValid, onError, []);
+      console.error('PUT request for unknown host: ' + hostId +
+                    ' (' + hostName + ')');
+      reject(remoting.Error.unexpected());
+    };
+    remoting.mockIdentity.validateTokenAndCall(onTokenValid, reject, []);
+  });
 };
 
-/**
- * @param {string} hostId
- * @param {function():void} onDone
- * @param {function(!remoting.Error):void} onError
- */
-remoting.MockHostListApi.prototype.remove =
-    function(hostId, onDone, onError) {
+/** @override */
+remoting.MockHostListApi.prototype.remove = function(hostId) {
   /** @type {remoting.MockHostListApi} */
   var that = this;
-  var onTokenValid = function() {
-    for (var i = 0; i < that.hosts.length; ++i) {
-      var host = that.hosts[i];
-      if (host.hostId == hostId) {
-        that.hosts.splice(i, 1);
-        onDone();
-        return;
+  return new Promise(function(resolve, reject) {
+    var onTokenValid = function() {
+      for (var i = 0; i < that.hosts.length; ++i) {
+        var host = that.hosts[i];
+        if (host.hostId == hostId) {
+          that.hosts.splice(i, 1);
+          resolve(undefined);
+          return;
+        }
       }
-    }
-    console.error('DELETE request for unknown host: ' + hostId);
-    onError(remoting.Error.unexpected());
-  };
-  remoting.mockIdentity.validateTokenAndCall(onTokenValid, onError, []);
+      console.error('DELETE request for unknown host: ' + hostId);
+      reject(remoting.Error.unexpected());
+    };
+    remoting.mockIdentity.validateTokenAndCall(onTokenValid, reject, []);
+  });
 };
 
 /**
diff --git a/remoting/webapp/crd/js/mock_signal_strategy.js b/remoting/webapp/crd/js/mock_signal_strategy.js
index 56b41c0..8fee7ad 100644
--- a/remoting/webapp/crd/js/mock_signal_strategy.js
+++ b/remoting/webapp/crd/js/mock_signal_strategy.js
@@ -35,6 +35,10 @@
 
 /** @override */
 remoting.MockSignalStrategy.prototype.connect = function() {
+  var that = this;
+  Promise.resolve().then(function() {
+    that.setStateForTesting(remoting.SignalStrategy.State.CONNECTED);
+  });
 };
 
 /** @override */
@@ -65,6 +69,11 @@
                                : function() {};
 };
 
+/** @param {Element} stanza */
+remoting.MockSignalStrategy.prototype.mock$onIncomingStanza = function(stanza) {
+  this.onIncomingStanzaCallback_(stanza);
+};
+
 /** @return {remoting.SignalStrategy.State} */
 remoting.MockSignalStrategy.prototype.getState = function() {
   return this.state_;
diff --git a/remoting/webapp/crd/js/xhr.js b/remoting/webapp/crd/js/xhr.js
index 1366a99..1b7fa34 100644
--- a/remoting/webapp/crd/js/xhr.js
+++ b/remoting/webapp/crd/js/xhr.js
@@ -9,11 +9,13 @@
  * Note: a mock version of this API exists in mock_xhr.js.
  */
 
-'use strict';
-
 /** @suppress {duplicate} */
 var remoting = remoting || {};
 
+(function() {
+
+'use strict';
+
 /**
  * @constructor
  * @param {remoting.Xhr.Params} params
@@ -78,54 +80,6 @@
 };
 
 /**
- * Parameters for the 'start' function.  Unless otherwise noted, all
- * parameters are optional.
- *
- * method: (required) The HTTP method to use.
- *
- * url: (required) The URL to request.
- *
- * urlParams: Parameters to be appended to the URL.  Null-valued
- *     parameters are omitted.
- *
- * textContent: Text to be sent as the request body.
- *
- * formContent: Data to be URL-encoded and sent as the request body.
- *     Causes Content-type header to be set appropriately.
- *
- * jsonContent: Data to be JSON-encoded and sent as the request body.
- *     Causes Content-type header to be set appropriately.
- *
- * headers: Additional request headers to be sent.  Null-valued
- *     headers are omitted.
- *
- * withCredentials: Value of the XHR's withCredentials field.
- *
- * oauthToken: An OAuth2 token used to construct an Authentication
- *     header.
- *
- * useIdentity: Use identity API to get an OAuth2 token.
- *
- * acceptJson: If true, send an Accept header indicating that a JSON
- *     response is expected.
- *
- * @typedef {{
- *   method: string,
- *   url:string,
- *   urlParams:(string|Object<string,?string>|undefined),
- *   textContent:(string|undefined),
- *   formContent:(Object|undefined),
- *   jsonContent:(*|undefined),
- *   headers:(Object<string,?string>|undefined),
- *   withCredentials:(boolean|undefined),
- *   oauthToken:(string|undefined),
- *   useIdentity:(boolean|undefined),
- *   acceptJson:(boolean|undefined)
- * }}
- */
-remoting.Xhr.Params;
-
-/**
  * Starts and HTTP request and gets a promise that is resolved when
  * the request completes.
  *
@@ -160,11 +114,37 @@
 };
 
 /**
+ * The set of possible fields in remoting.Xhr.Params.
+ * @const
+ */
+var ALLOWED_PARAMS = [
+  'method',
+  'url',
+  'urlParams',
+  'textContent',
+  'formContent',
+  'jsonContent',
+  'headers',
+  'withCredentials',
+  'oauthToken',
+  'useIdentity',
+  'acceptJson'
+];
+
+/**
  * @param {remoting.Xhr.Params} params
  * @throws {Error} if params are invalid
  * @private
  */
 remoting.Xhr.checkParams_ = function(params) {
+  // Provide a sensible error message when the user misspells a
+  // parameter name, since the compiler won't catch it.
+  for (var field in params) {
+    if (ALLOWED_PARAMS.indexOf(field) == -1) {
+      throw new Error('unknow parameter: ' + field);
+    }
+  }
+
   if (params.urlParams) {
     if (params.url.indexOf('?') != -1) {
       throw new Error('URL may not contain "?" when urlParams is set');
@@ -363,3 +343,53 @@
   }
   return '';
 };
+
+})();
+
+/**
+ * Parameters for the 'start' function.  Unless otherwise noted, all
+ * parameters are optional.
+ *
+ * method: (required) The HTTP method to use.
+ *
+ * url: (required) The URL to request.
+ *
+ * urlParams: Parameters to be appended to the URL.  Null-valued
+ *     parameters are omitted.
+ *
+ * textContent: Text to be sent as the request body.
+ *
+ * formContent: Data to be URL-encoded and sent as the request body.
+ *     Causes Content-type header to be set appropriately.
+ *
+ * jsonContent: Data to be JSON-encoded and sent as the request body.
+ *     Causes Content-type header to be set appropriately.
+ *
+ * headers: Additional request headers to be sent.  Null-valued
+ *     headers are omitted.
+ *
+ * withCredentials: Value of the XHR's withCredentials field.
+ *
+ * oauthToken: An OAuth2 token used to construct an Authentication
+ *     header.
+ *
+ * useIdentity: Use identity API to get an OAuth2 token.
+ *
+ * acceptJson: If true, send an Accept header indicating that a JSON
+ *     response is expected.
+ *
+ * @typedef {{
+ *   method: string,
+ *   url:string,
+ *   urlParams:(string|Object<string,?string>|undefined),
+ *   textContent:(string|undefined),
+ *   formContent:(Object|undefined),
+ *   jsonContent:(*|undefined),
+ *   headers:(Object<string,?string>|undefined),
+ *   withCredentials:(boolean|undefined),
+ *   oauthToken:(string|undefined),
+ *   useIdentity:(boolean|undefined),
+ *   acceptJson:(boolean|undefined)
+ * }}
+ */
+remoting.Xhr.Params;
\ No newline at end of file
diff --git a/remoting/webapp/crd/js/xhr_unittest.js b/remoting/webapp/crd/js/xhr_unittest.js
index f5cb772..fc711ad 100644
--- a/remoting/webapp/crd/js/xhr_unittest.js
+++ b/remoting/webapp/crd/js/xhr_unittest.js
@@ -172,6 +172,17 @@
   });
 });
 
+
+QUnit.test('unexpected parameters', function(assert) {
+  assert.throws(function() {
+    new remoting.Xhr({
+      method: 'POST',
+      url: 'http://foo.com',
+      xyzzy: 'not a real parameter'
+    });
+  });
+});
+
 //
 // The typical case.
 //
diff --git a/remoting/webapp/files.gni b/remoting/webapp/files.gni
index 8cb49e7..1a006c04 100644
--- a/remoting/webapp/files.gni
+++ b/remoting/webapp/files.gni
@@ -72,6 +72,7 @@
   "base/js/ipc_unittest.js",
   "base/js/protocol_extension_manager_unittest.js",
   "crd/js/apps_v2_migration_unittest.js",
+  "crd/js/client_session_unittest.js",
   "crd/js/desktop_viewport_unittest.js",
   "crd/js/dns_blackhole_checker_unittest.js",
   "crd/js/error_unittest.js",
@@ -154,6 +155,7 @@
 
 # Client JavaScript files.
 remoting_webapp_js_client_files = [
+  "crd/js/activity.js",
   "crd/js/client_plugin.js",
   "crd/js/client_plugin_host_desktop_impl.js",
   "crd/js/client_plugin_impl.js",
@@ -290,8 +292,8 @@
   "crd/js/crd_event_handlers.js",
   "crd/js/crd_experimental.js",
   "crd/js/crd_main.js",
-  "crd/js/activity.js",
   "crd/js/desktop_remoting.js",
+  "crd/js/desktop_remoting_activity.js",
   "crd/js/it2me_activity.js",
   "crd/js/me2me_activity.js",
 ]
@@ -326,45 +328,44 @@
 # Webapp background.html generation files.
 #
 
-remoting_webapp_template_background =
-    "<(DEPTH)/remoting/webapp/crd/html/template_background.html"
+remoting_webapp_template_background = "crd/html/template_background.html"
 
 # These JS files are specific to the background page and are not part of
 # the main JS files.
 remoting_webapp_background_html_js_files = [
-  "webapp/base/js/message_window_helper.js",
-  "webapp/base/js/message_window_manager.js",
-  "webapp/crd/js/activation_handler.js",
-  "webapp/crd/js/app_launcher.js",
-  "webapp/crd/js/background.js",
+  "base/js/message_window_helper.js",
+  "base/js/message_window_manager.js",
+  "crd/js/activation_handler.js",
+  "crd/js/app_launcher.js",
+  "crd/js/background.js",
 ]
 
 # All the JavaScript files required by background.html.
-remoting_webapp_background_html_all_js_files = [
-  "<@(remoting_webapp_background_html_js_files)",
-  "webapp/base/js/base.js",
-  "webapp/base/js/ipc.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/identity.js",
-  "webapp/crd/js/it2me_host_facade.js",
-  "webapp/crd/js/l10n.js",
-  "webapp/crd/js/oauth2.js",
-  "webapp/crd/js/oauth2_api.js",
-  "webapp/crd/js/oauth2_api_impl.js",
-  "webapp/crd/js/plugin_settings.js",
-  "webapp/crd/js/typecheck.js",
-  "webapp/crd/js/xhr.js",
+remoting_webapp_background_html_all_js_files =
+    remoting_webapp_background_html_js_files
+remoting_webapp_background_html_all_js_files += [
+  "base/js/base.js",
+  "base/js/ipc.js",
+  "crd/js/client_session.js",
+  "crd/js/error.js",
+  "crd/js/host_installer.js",
+  "crd/js/host_session.js",
+  "crd/js/identity.js",
+  "crd/js/it2me_host_facade.js",
+  "crd/js/l10n.js",
+  "crd/js/oauth2.js",
+  "crd/js/oauth2_api.js",
+  "crd/js/oauth2_api_impl.js",
+  "crd/js/plugin_settings.js",
+  "crd/js/typecheck.js",
+  "crd/js/xhr.js",
 ]
 
 #
 # Webapp wcs_sandbox.html generation files.
 #
 
-remoting_webapp_template_wcs_sandbox =
-    "<(DEPTH)/remoting/webapp/base/html/template_wcs_sandbox.html"
+remoting_webapp_template_wcs_sandbox = "base/html/template_wcs_sandbox.html"
 
 # These JS files are specific to the WCS sandbox page and are not part of
 # the main JS files.
@@ -376,8 +377,9 @@
 ]
 
 # All the JavaScript files required by wcs_sandbox.html.
-remoting_webapp_wcs_sandbox_html_all_js_files = [
-  "<@(remoting_webapp_wcs_sandbox_html_js_files)",
+remoting_webapp_wcs_sandbox_html_all_js_files =
+    remoting_webapp_wcs_sandbox_html_js_files
+remoting_webapp_wcs_sandbox_html_all_js_files += [
   "crd/js/error.js",
   "crd/js/plugin_settings.js",
 ]
@@ -387,86 +389,76 @@
 #
 
 remoting_webapp_template_message_window =
-    "<(DEPTH)/remoting/webapp/base/html/template_message_window.html"
+    "base/html/template_message_window.html"
 
 # These JS files are specific to the message window page and are not part of
 # the main JS files.
-remoting_webapp_message_window_html_js_files =
-    [ "webapp/base/js/message_window.js" ]
+remoting_webapp_message_window_html_js_files = [ "base/js/message_window.js" ]
 
 # All the JavaScript files required by message_window.html.
-remoting_webapp_message_window_html_all_js_files = [
-  "<@(remoting_webapp_message_window_html_js_files)",
-  "webapp/base/js/base.js",
-]
+remoting_webapp_message_window_html_all_js_files =
+    remoting_webapp_message_window_html_js_files + [ "base/js/base.js" ]
 
 #
 # Complete webapp JS and resource files.
 #
 
 # All the JavaScript files that are shared by webapps.
-remoting_webapp_shared_js_files = [
-  "<@(remoting_webapp_shared_main_html_js_files)",
-  "<@(remoting_webapp_background_html_js_files)",
-  "<@(remoting_webapp_message_window_html_js_files)",
-  "<@(remoting_webapp_wcs_sandbox_html_js_files)",
-
-  # JS files referenced in manifest.json.
-  "<@(remoting_webapp_js_auth_v1_files)",
-]
+remoting_webapp_shared_js_files = remoting_webapp_shared_main_html_js_files +
+                                  remoting_webapp_background_html_js_files +
+                                  remoting_webapp_message_window_html_js_files +
+                                  remoting_webapp_wcs_sandbox_html_js_files +
+                                  # JS files referenced in manifest.json.
+                                  remoting_webapp_js_auth_v1_files
 
 # All the JavaScript files required by DesktopRemoting.
-remoting_webapp_crd_js_files = [
-  "<@(remoting_webapp_shared_js_files)",
-  "<@(remoting_webapp_crd_main_html_all_js_files)",
-]
+remoting_webapp_crd_js_files =
+    remoting_webapp_shared_js_files + remoting_webapp_crd_main_html_all_js_files
 
 remoting_webapp_info_files = [
-  "resources/chromoting16.webp",
-  "resources/chromoting48.webp",
-  "resources/chromoting128.webp",
+  "../resources/chromoting16.webp",
+  "../resources/chromoting48.webp",
+  "../resources/chromoting128.webp",
 ]
 
 # All the resource files required by DesktopRemoting.
 remoting_webapp_resource_files = [
-  "resources/disclosure_arrow_down.webp",
-  "resources/disclosure_arrow_right.webp",
-  "resources/drag.webp",
-  "resources/host_setup_instructions.webp",
-  "resources/icon_close.webp",
-  "resources/icon_cross.webp",
-  "resources/icon_disconnect.webp",
-  "resources/icon_fullscreen.webp",
-  "resources/icon_help.webp",
-  "resources/icon_host.webp",
-  "resources/icon_maximize_restore.webp",
-  "resources/icon_minimize.webp",
-  "resources/icon_options.webp",
-  "resources/icon_pencil.webp",
-  "resources/icon_warning.webp",
-  "resources/infographic_my_computers.webp",
-  "resources/infographic_remote_assistance.webp",
-  "resources/plus.webp",
-  "resources/reload.webp",
-  "resources/tick.webp",
-  "webapp/base/html/connection_stats.css",
-  "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/butter_bar.css",
-  "webapp/crd/html/toolbar.css",
-  "webapp/crd/html/menu_button.css",
-  "webapp/crd/html/window_frame.css",
-  "webapp/crd/resources/scale-to-fit.webp",
+  "../resources/disclosure_arrow_down.webp",
+  "../resources/disclosure_arrow_right.webp",
+  "../resources/drag.webp",
+  "../resources/host_setup_instructions.webp",
+  "../resources/icon_close.webp",
+  "../resources/icon_cross.webp",
+  "../resources/icon_disconnect.webp",
+  "../resources/icon_fullscreen.webp",
+  "../resources/icon_help.webp",
+  "../resources/icon_host.webp",
+  "../resources/icon_maximize_restore.webp",
+  "../resources/icon_minimize.webp",
+  "../resources/icon_options.webp",
+  "../resources/icon_pencil.webp",
+  "../resources/icon_warning.webp",
+  "../resources/infographic_my_computers.webp",
+  "../resources/infographic_remote_assistance.webp",
+  "../resources/plus.webp",
+  "../resources/reload.webp",
+  "../resources/tick.webp",
+  "base/html/connection_stats.css",
+  "base/html/main.css",
+  "base/html/message_window.css",
+  "base/resources/open_sans.css",
+  "base/resources/open_sans.woff",
+  "base/resources/spinner.gif",
+  "crd/html/butter_bar.css",
+  "crd/html/toolbar.css",
+  "crd/html/menu_button.css",
+  "crd/html/window_frame.css",
+  "crd/resources/scale-to-fit.webp",
 ]
 
-remoting_webapp_crd_files = [
-  "<@(remoting_webapp_info_files)",
-  "<@(remoting_webapp_crd_js_files)",
-  "<@(remoting_webapp_resource_files)",
-]
+remoting_webapp_crd_files =
+    remoting_webapp_info_files + remoting_webapp_crd_js_files +
+    remoting_webapp_resource_files
 
 # Files that contain localizable strings.
 desktop_remoting_webapp_localizable_files = [
diff --git a/remoting/webapp/unittests/spy_promise.js b/remoting/webapp/unittests/spy_promise.js
index 3429d276..bb76799b 100644
--- a/remoting/webapp/unittests/spy_promise.js
+++ b/remoting/webapp/unittests/spy_promise.js
@@ -245,7 +245,7 @@
   if (Promise === base.SpyPromise) {
     throw Error('base.SpyPromise is already active');
   }
-  Promise = base.SpyPromise;
+  Promise = /** @type {function(new:Promise)} */(base.SpyPromise);
 };
 
 /**
@@ -291,4 +291,4 @@
     });
   }
 };
-})();
\ No newline at end of file
+})();
diff --git a/sandbox/sandbox_nacl_nonsfi.gyp b/sandbox/sandbox_nacl_nonsfi.gyp
index c757ec5..781df423 100644
--- a/sandbox/sandbox_nacl_nonsfi.gyp
+++ b/sandbox/sandbox_nacl_nonsfi.gyp
@@ -39,7 +39,6 @@
           },
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl_nonsfi',
-            '../native_client/tools.gyp:prep_toolchain',
           ],
         },
       ],
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
index f23d431..01c7cdd 100644
--- a/sandbox/win/src/broker_services.cc
+++ b/sandbox/win/src/broker_services.cc
@@ -404,6 +404,12 @@
 
   // Initialize the startup information from the policy.
   base::win::StartupInformation startup_info;
+  // The liftime of |mitigations| and |inherit_handle_list| have to be at least
+  // as long as |startup_info| because |UpdateProcThreadAttribute| requires that
+  // its |lpValue| parameter persist until |DeleteProcThreadAttributeList| is
+  // called; StartupInformation's destructor makes such a call.
+  DWORD64 mitigations;
+  HANDLE inherit_handle_list[2];
   base::string16 desktop = policy_base->GetAlternateDesktop();
   if (!desktop.empty()) {
     startup_info.startup_info()->lpDesktop =
@@ -418,7 +424,6 @@
     if (app_container)
       ++attribute_count;
 
-    DWORD64 mitigations;
     size_t mitigations_size;
     ConvertProcessMitigationsToPolicy(policy->GetProcessMitigations(),
                                       &mitigations, &mitigations_size);
@@ -427,7 +432,6 @@
 
     HANDLE stdout_handle = policy_base->GetStdoutHandle();
     HANDLE stderr_handle = policy_base->GetStderrHandle();
-    HANDLE inherit_handle_list[2];
     int inherit_handle_count = 0;
     if (stdout_handle != INVALID_HANDLE_VALUE)
       inherit_handle_list[inherit_handle_count++] = stdout_handle;
diff --git a/sql/connection.cc b/sql/connection.cc
index d94b4d8..ba799a90 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -340,7 +340,7 @@
     preload_size = file_size;
 
   scoped_ptr<char[]> buf(new char[page_size]);
-  for (sqlite3_int64 pos = 0; pos < file_size; pos += page_size) {
+  for (sqlite3_int64 pos = 0; pos < preload_size; pos += page_size) {
     rc = file->pMethods->xRead(file, buf.get(), page_size, pos);
     if (rc != SQLITE_OK)
       return;
diff --git a/sync/android/java/src/org/chromium/sync/AndroidSyncSettings.java b/sync/android/java/src/org/chromium/sync/AndroidSyncSettings.java
index d24366c..3587e76b 100644
--- a/sync/android/java/src/org/chromium/sync/AndroidSyncSettings.java
+++ b/sync/android/java/src/org/chromium/sync/AndroidSyncSettings.java
@@ -160,6 +160,7 @@
     public void updateAccount(Account account) {
         synchronized (mLock) {
             mAccount = account;
+            updateSyncability();
         }
         if (updateCachedSettings()) {
             notifyObservers();
@@ -193,8 +194,8 @@
 
     private void setChromeSyncEnabled(boolean value) {
         synchronized (mLock) {
+            updateSyncability();
             if (value == mChromeSyncEnabled || mAccount == null) return;
-            ensureSyncable();
             mChromeSyncEnabled = value;
 
             StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
@@ -205,18 +206,22 @@
     }
 
     /**
-     * Ensure Chrome is registered with the Android Sync Manager.
+     * Ensure Chrome is registered with the Android Sync Manager iff signed in.
      *
      * This is what causes the "Chrome" option to appear in Settings -> Accounts -> Sync .
      * This function must be called within a synchronized block.
      */
-    private void ensureSyncable() {
-        if (mIsSyncable || mAccount == null) return;
+    private void updateSyncability() {
+        boolean shouldBeSyncable = mAccount != null;
+        if (mIsSyncable == shouldBeSyncable) return;
 
-        mIsSyncable = true;
+        mIsSyncable = shouldBeSyncable;
 
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        mSyncContentResolverDelegate.setIsSyncable(mAccount, mContractAuthority, 1);
+        // Make account syncable if there is one.
+        if (shouldBeSyncable) {
+            mSyncContentResolverDelegate.setIsSyncable(mAccount, mContractAuthority, 1);
+        }
 
         // 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
diff --git a/sync/android/javatests/src/org/chromium/sync/AndroidSyncSettingsTest.java b/sync/android/javatests/src/org/chromium/sync/AndroidSyncSettingsTest.java
index aeba67f..13c43f64 100644
--- a/sync/android/javatests/src/org/chromium/sync/AndroidSyncSettingsTest.java
+++ b/sync/android/javatests/src/org/chromium/sync/AndroidSyncSettingsTest.java
@@ -12,6 +12,9 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
+import org.chromium.sync.signin.AccountManagerHelper;
+import org.chromium.sync.test.util.AccountHolder;
+import org.chromium.sync.test.util.MockAccountManager;
 import org.chromium.sync.test.util.MockSyncContentResolverDelegate;
 
 /**
@@ -81,16 +84,17 @@
     private Account mAccount;
     private Account mAlternateAccount;
     private MockSyncSettingsObserver mSyncSettingsObserver;
+    private MockAccountManager mAccountManager;
 
     @Override
     protected void setUp() throws Exception {
         mSyncContentResolverDelegate = new CountingMockSyncContentResolverDelegate();
         Context context = getInstrumentation().getTargetContext();
+        setupTestAccounts(context);
+
         AndroidSyncSettings.overrideForTests(context, mSyncContentResolverDelegate);
         mAndroid = AndroidSyncSettings.get(context);
         mAuthority = mAndroid.getContractAuthority();
-        mAccount = new Account("account@example.com", "com.google");
-        mAlternateAccount = new Account("alternateAccount@example.com", "com.google");
         mAndroid.updateAccount(mAccount);
 
         mSyncSettingsObserver = new MockSyncSettingsObserver();
@@ -99,6 +103,21 @@
         super.setUp();
     }
 
+    private void setupTestAccounts(Context context) {
+        mAccountManager = new MockAccountManager(context, context);
+        AccountManagerHelper.overrideAccountManagerHelperForTests(context, mAccountManager);
+        mAccount = setupTestAccount("account@example.com");
+        mAlternateAccount = setupTestAccount("alternate@example.com");
+    }
+
+    private Account setupTestAccount(String accountName) {
+        Account account = AccountManagerHelper.createAccountFromName(accountName);
+        AccountHolder.Builder accountHolder =
+                AccountHolder.create().account(account).password("password").alwaysAccept(true);
+        mAccountManager.addAccountHolderExplicitly(accountHolder.build());
+        return account;
+    }
+
     private void enableChromeSyncOnUiThread() {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -294,4 +313,39 @@
         assertFalse("disableChromeSync shouldn't observers",
                 mSyncSettingsObserver.receivedNotification());
     }
+
+    @SmallTest
+    @Feature({"Sync"})
+    public void testIsSyncableOnSigninAndNotOnSignout() throws InterruptedException {
+        assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthority) == 1);
+        mAndroid.updateAccount(null);
+        assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthority) == 0);
+        mAndroid.updateAccount(mAccount);
+        assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthority) == 1);
+    }
+
+    /**
+     * Regression test for crbug.com/475299.
+     */
+    @SmallTest
+    @Feature({"Sync"})
+    public void testSyncableIsAlwaysSetWhenEnablingSync() throws InterruptedException {
+        // Setup bad state.
+        mSyncContentResolverDelegate.setMasterSyncAutomatically(true);
+        mSyncContentResolverDelegate.waitForLastNotificationCompleted();
+        mSyncContentResolverDelegate.setIsSyncable(mAccount, mAuthority, 1);
+        mSyncContentResolverDelegate.waitForLastNotificationCompleted();
+        mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mAuthority, true);
+        mSyncContentResolverDelegate.waitForLastNotificationCompleted();
+        mSyncContentResolverDelegate.setIsSyncable(mAccount, mAuthority, 0);
+        mSyncContentResolverDelegate.waitForLastNotificationCompleted();
+        assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthority) == 0);
+        assertTrue(mSyncContentResolverDelegate.getSyncAutomatically(mAccount, mAuthority));
+
+        // Ensure bug is fixed.
+        mAndroid.enableChromeSync();
+        assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthority) == 1);
+        // Should still be enabled.
+        assertTrue(mSyncContentResolverDelegate.getSyncAutomatically(mAccount, mAuthority));
+    }
 }
diff --git a/sync/api/attachments/attachment_store.cc b/sync/api/attachments/attachment_store.cc
index 76378357..9f09de3 100644
--- a/sync/api/attachments/attachment_store.cc
+++ b/sync/api/attachments/attachment_store.cc
@@ -33,7 +33,7 @@
 
 void AttachmentStore::Read(const AttachmentIdList& ids,
                            const ReadCallback& callback) {
-  frontend_->Read(ids, callback);
+  frontend_->Read(component_, ids, callback);
 }
 
 void AttachmentStore::Write(const AttachmentList& attachments,
@@ -46,13 +46,13 @@
   frontend_->DropReference(component_, ids, callback);
 }
 
-void AttachmentStore::ReadMetadata(const AttachmentIdList& ids,
-                                   const ReadMetadataCallback& callback) {
-  frontend_->ReadMetadata(ids, callback);
+void AttachmentStore::ReadMetadataById(const AttachmentIdList& ids,
+                                       const ReadMetadataCallback& callback) {
+  frontend_->ReadMetadataById(component_, ids, callback);
 }
 
-void AttachmentStore::ReadAllMetadata(const ReadMetadataCallback& callback) {
-  frontend_->ReadAllMetadata(component_, callback);
+void AttachmentStore::ReadMetadata(const ReadMetadataCallback& callback) {
+  frontend_->ReadMetadata(component_, callback);
 }
 
 scoped_ptr<AttachmentStoreForSync>
@@ -124,14 +124,19 @@
   frontend()->SetReference(sync_component_, ids);
 }
 
+void AttachmentStoreForSync::SetModelTypeReference(
+    const AttachmentIdList& ids) {
+  frontend()->SetReference(component(), ids);
+}
+
 void AttachmentStoreForSync::DropSyncReference(const AttachmentIdList& ids) {
   frontend()->DropReference(sync_component_, ids,
                             base::Bind(&NoOpDropCallback));
 }
 
-void AttachmentStoreForSync::ReadSyncMetadata(
+void AttachmentStoreForSync::ReadMetadataForSync(
     const ReadMetadataCallback& callback) {
-  frontend()->ReadAllMetadata(sync_component_, callback);
+  frontend()->ReadMetadata(sync_component_, callback);
 }
 
 }  // namespace syncer
diff --git a/sync/api/attachments/attachment_store.h b/sync/api/attachments/attachment_store.h
index b29a0924..14fd0fc 100644
--- a/sync/api/attachments/attachment_store.h
+++ b/sync/api/attachments/attachment_store.h
@@ -110,15 +110,15 @@
   // read metadata for all attachments specified in ids. If any of the
   // metadata entries do not exist or could not be read, |callback|'s Result
   // will be UNSPECIFIED_ERROR.
-  void ReadMetadata(const AttachmentIdList& ids,
-                    const ReadMetadataCallback& callback);
+  void ReadMetadataById(const AttachmentIdList& ids,
+                        const ReadMetadataCallback& callback);
 
   // Asynchronously reads metadata for all attachments with |component_|
   // reference in the store.
   //
   // |callback| will be invoked when finished. If any of the metadata entries
   // could not be read, |callback|'s Result will be UNSPECIFIED_ERROR.
-  void ReadAllMetadata(const ReadMetadataCallback& callback);
+  void ReadMetadata(const ReadMetadataCallback& callback);
 
   // Given current AttachmentStore (this) creates separate AttachmentStore that
   // will be used by sync components (AttachmentService). Resulting
@@ -152,6 +152,7 @@
                   Component component);
 
   const scoped_refptr<AttachmentStoreFrontend>& frontend() { return frontend_; }
+  Component component() const { return component_; }
 
  private:
   scoped_refptr<AttachmentStoreFrontend> frontend_;
@@ -174,6 +175,11 @@
   // Asynchronously adds reference from sync to attachments.
   void SetSyncReference(const AttachmentIdList& ids);
 
+  // Asynchronously adds reference from model type to attachments.
+  // Needed in GetOrDownloadAttachments when attachment is in local store but
+  // doesn't have model type reference.
+  void SetModelTypeReference(const AttachmentIdList& ids);
+
   // Asynchronously drops sync reference from attachments.
   void DropSyncReference(const AttachmentIdList& ids);
 
@@ -182,7 +188,7 @@
   //
   // |callback| will be invoked when finished. If any of the metadata entries
   // could not be read, |callback|'s Result will be UNSPECIFIED_ERROR.
-  void ReadSyncMetadata(const ReadMetadataCallback& callback);
+  void ReadMetadataForSync(const ReadMetadataCallback& callback);
 
  private:
   friend class AttachmentStore;
diff --git a/sync/api/attachments/attachment_store_backend.h b/sync/api/attachments/attachment_store_backend.h
index 73bc0fb..14f1de7d 100644
--- a/sync/api/attachments/attachment_store_backend.h
+++ b/sync/api/attachments/attachment_store_backend.h
@@ -34,7 +34,8 @@
       const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner);
   virtual ~AttachmentStoreBackend();
   virtual void Init(const AttachmentStore::InitCallback& callback) = 0;
-  virtual void Read(const AttachmentIdList& ids,
+  virtual void Read(AttachmentStore::Component component,
+                    const AttachmentIdList& ids,
                     const AttachmentStore::ReadCallback& callback) = 0;
   virtual void Write(AttachmentStore::Component component,
                      const AttachmentList& attachments,
@@ -44,10 +45,11 @@
   virtual void DropReference(AttachmentStore::Component component,
                              const AttachmentIdList& ids,
                              const AttachmentStore::DropCallback& callback) = 0;
-  virtual void ReadMetadata(
+  virtual void ReadMetadataById(
+      AttachmentStore::Component component,
       const AttachmentIdList& ids,
       const AttachmentStore::ReadMetadataCallback& callback) = 0;
-  virtual void ReadAllMetadata(
+  virtual void ReadMetadata(
       AttachmentStore::Component component,
       const AttachmentStore::ReadMetadataCallback& callback) = 0;
 
diff --git a/sync/internal_api/attachments/attachment_service_impl.cc b/sync/internal_api/attachments/attachment_service_impl.cc
index fb65172..be5af274 100644
--- a/sync/internal_api/attachments/attachment_service_impl.cc
+++ b/sync/internal_api/attachments/attachment_service_impl.cc
@@ -164,6 +164,10 @@
   DCHECK(CalledOnValidThread());
   scoped_refptr<GetOrDownloadState> state(
       new GetOrDownloadState(attachment_ids, callback));
+  // SetModelTypeReference() makes attachments visible for model type.
+  // Needed when attachment doesn't have model type reference, but still
+  // available in local store.
+  attachment_store_->SetModelTypeReference(attachment_ids);
   attachment_store_->Read(attachment_ids,
                           base::Bind(&AttachmentServiceImpl::ReadDone,
                                      weak_ptr_factory_.GetWeakPtr(), state));
diff --git a/sync/internal_api/attachments/attachment_service_impl_unittest.cc b/sync/internal_api/attachments/attachment_service_impl_unittest.cc
index f619b75..0ca4007 100644
--- a/sync/internal_api/attachments/attachment_service_impl_unittest.cc
+++ b/sync/internal_api/attachments/attachment_service_impl_unittest.cc
@@ -33,7 +33,8 @@
 
   void Init(const AttachmentStore::InitCallback& callback) override {}
 
-  void Read(const AttachmentIdList& ids,
+  void Read(AttachmentStore::Component component,
+            const AttachmentIdList& ids,
             const AttachmentStore::ReadCallback& callback) override {
     read_ids.push_back(ids);
     read_callbacks.push_back(callback);
@@ -48,7 +49,7 @@
 
   void SetReference(AttachmentStore::Component component,
                     const AttachmentIdList& ids) override {
-    set_reference_ids.push_back(ids);
+    set_reference_ids.push_back(std::make_pair(component, ids));
   }
 
   void DropReference(AttachmentStore::Component component,
@@ -58,13 +59,14 @@
     drop_ids.push_back(ids);
   }
 
-  void ReadMetadata(
+  void ReadMetadataById(
+      AttachmentStore::Component component,
       const AttachmentIdList& ids,
       const AttachmentStore::ReadMetadataCallback& callback) override {
     NOTREACHED();
   }
 
-  void ReadAllMetadata(
+  void ReadMetadata(
       AttachmentStore::Component component,
       const AttachmentStore::ReadMetadataCallback& callback) override {
     NOTREACHED();
@@ -116,7 +118,8 @@
   std::vector<AttachmentStore::ReadCallback> read_callbacks;
   std::vector<AttachmentList> write_attachments;
   std::vector<AttachmentStore::WriteCallback> write_callbacks;
-  std::vector<AttachmentIdList> set_reference_ids;
+  std::vector<std::pair<AttachmentStore::Component, AttachmentIdList>>
+      set_reference_ids;
   std::vector<AttachmentIdList> drop_ids;
 
  private:
@@ -339,6 +342,8 @@
   AttachmentIdSet local_attachments;
   local_attachments.insert(attachment_ids[0]);
   RunLoop();
+  EXPECT_EQ(1U, store()->set_reference_ids.size());
+  EXPECT_EQ(AttachmentStore::MODEL_TYPE, store()->set_reference_ids[0].first);
   store()->RespondToRead(local_attachments);
 
   RunLoop();
@@ -443,7 +448,8 @@
   }
   attachment_service()->UploadAttachments(attachment_ids);
   RunLoop();
-  EXPECT_FALSE(store()->set_reference_ids.empty());
+  ASSERT_EQ(1U, store()->set_reference_ids.size());
+  EXPECT_EQ(AttachmentStore::SYNC, store()->set_reference_ids[0].first);
   for (unsigned i = 0; i < num_attachments; ++i) {
     RunLoopAndFireTimer();
     // See that the service has issued a read for at least one of the
diff --git a/sync/internal_api/attachments/attachment_store_frontend.cc b/sync/internal_api/attachments/attachment_store_frontend.cc
index b9d69950..f1d1ffe42 100644
--- a/sync/internal_api/attachments/attachment_store_frontend.cc
+++ b/sync/internal_api/attachments/attachment_store_frontend.cc
@@ -47,12 +47,14 @@
 }
 
 void AttachmentStoreFrontend::Read(
+    AttachmentStore::Component component,
     const AttachmentIdList& ids,
     const AttachmentStore::ReadCallback& callback) {
   DCHECK(CalledOnValidThread());
   backend_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentStoreBackend::Read,
-                            base::Unretained(backend_.get()), ids, callback));
+      FROM_HERE,
+      base::Bind(&AttachmentStoreBackend::Read,
+                 base::Unretained(backend_.get()), component, ids, callback));
 }
 
 void AttachmentStoreFrontend::Write(
@@ -85,22 +87,24 @@
                  base::Unretained(backend_.get()), component, ids, callback));
 }
 
-void AttachmentStoreFrontend::ReadMetadata(
+void AttachmentStoreFrontend::ReadMetadataById(
+    AttachmentStore::Component component,
     const AttachmentIdList& ids,
     const AttachmentStore::ReadMetadataCallback& callback) {
   DCHECK(CalledOnValidThread());
   backend_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentStoreBackend::ReadMetadata,
-                            base::Unretained(backend_.get()), ids, callback));
+      FROM_HERE,
+      base::Bind(&AttachmentStoreBackend::ReadMetadataById,
+                 base::Unretained(backend_.get()), component, ids, callback));
 }
 
-void AttachmentStoreFrontend::ReadAllMetadata(
+void AttachmentStoreFrontend::ReadMetadata(
     AttachmentStore::Component component,
     const AttachmentStore::ReadMetadataCallback& callback) {
   DCHECK(CalledOnValidThread());
   backend_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&AttachmentStoreBackend::ReadAllMetadata,
+      base::Bind(&AttachmentStoreBackend::ReadMetadata,
                  base::Unretained(backend_.get()), component, callback));
 }
 
diff --git a/sync/internal_api/attachments/attachment_store_frontend_unittest.cc b/sync/internal_api/attachments/attachment_store_frontend_unittest.cc
index a1e8740..590eee8 100644
--- a/sync/internal_api/attachments/attachment_store_frontend_unittest.cc
+++ b/sync/internal_api/attachments/attachment_store_frontend_unittest.cc
@@ -27,8 +27,8 @@
                       const base::Closure& write_called,
                       const base::Closure& set_reference_called,
                       const base::Closure& drop_reference_called,
+                      const base::Closure& read_metadata_by_id_called,
                       const base::Closure& read_metadata_called,
-                      const base::Closure& read_all_metadata_called,
                       const base::Closure& dtor_called)
       : AttachmentStoreBackend(nullptr),
         init_called_(init_called),
@@ -36,8 +36,8 @@
         write_called_(write_called),
         set_reference_called_(set_reference_called),
         drop_reference_called_(drop_reference_called),
+        read_metadata_by_id_called_(read_metadata_by_id_called),
         read_metadata_called_(read_metadata_called),
-        read_all_metadata_called_(read_all_metadata_called),
         dtor_called_(dtor_called) {}
 
   ~MockAttachmentStore() override { dtor_called_.Run(); }
@@ -46,7 +46,8 @@
     init_called_.Run();
   }
 
-  void Read(const AttachmentIdList& ids,
+  void Read(AttachmentStore::Component component,
+            const AttachmentIdList& ids,
             const AttachmentStore::ReadCallback& callback) override {
     read_called_.Run();
   }
@@ -68,16 +69,17 @@
     drop_reference_called_.Run();
   }
 
-  void ReadMetadata(
+  void ReadMetadataById(
+      AttachmentStore::Component component,
       const AttachmentIdList& ids,
       const AttachmentStore::ReadMetadataCallback& callback) override {
-    read_metadata_called_.Run();
+    read_metadata_by_id_called_.Run();
   }
 
-  void ReadAllMetadata(
+  void ReadMetadata(
       AttachmentStore::Component component,
       const AttachmentStore::ReadMetadataCallback& callback) override {
-    read_all_metadata_called_.Run();
+    read_metadata_called_.Run();
   }
 
   base::Closure init_called_;
@@ -85,8 +87,8 @@
   base::Closure write_called_;
   base::Closure set_reference_called_;
   base::Closure drop_reference_called_;
+  base::Closure read_metadata_by_id_called_;
   base::Closure read_metadata_called_;
-  base::Closure read_all_metadata_called_;
   base::Closure dtor_called_;
 };
 
@@ -100,8 +102,8 @@
         write_call_count_(0),
         add_component_call_count_(0),
         drop_call_count_(0),
+        read_metadata_by_id_call_count_(0),
         read_metadata_call_count_(0),
-        read_all_metadata_call_count_(0),
         dtor_call_count_(0) {}
 
   void SetUp() override {
@@ -116,9 +118,9 @@
                    base::Unretained(this)),
         base::Bind(&AttachmentStoreFrontendTest::DropReferenceCalled,
                    base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::ReadMetadataCalled,
+        base::Bind(&AttachmentStoreFrontendTest::ReadMetadataByIdCalled,
                    base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::ReadAllMetadataCalled,
+        base::Bind(&AttachmentStoreFrontendTest::ReadMetadataCalled,
                    base::Unretained(this)),
         base::Bind(&AttachmentStoreFrontendTest::DtorCalled,
                    base::Unretained(this))));
@@ -151,9 +153,9 @@
 
   void DropReferenceCalled() { ++drop_call_count_; }
 
-  void ReadMetadataCalled() { ++read_metadata_call_count_; }
+  void ReadMetadataByIdCalled() { ++read_metadata_by_id_call_count_; }
 
-  void ReadAllMetadataCalled() { ++read_all_metadata_call_count_; }
+  void ReadMetadataCalled() { ++read_metadata_call_count_; }
 
   void DtorCalled() { ++dtor_call_count_; }
 
@@ -169,8 +171,8 @@
   int write_call_count_;
   int add_component_call_count_;
   int drop_call_count_;
+  int read_metadata_by_id_call_count_;
   int read_metadata_call_count_;
-  int read_all_metadata_call_count_;
   int dtor_call_count_;
 };
 
@@ -186,7 +188,8 @@
   EXPECT_EQ(init_call_count_, 1);
 
   attachment_store_frontend_->Read(
-      id_list, base::Bind(&AttachmentStoreFrontendTest::ReadDone));
+      AttachmentStore::SYNC, id_list,
+      base::Bind(&AttachmentStoreFrontendTest::ReadDone));
   EXPECT_EQ(read_call_count_, 0);
   RunMessageLoop();
   EXPECT_EQ(read_call_count_, 1);
@@ -207,19 +210,20 @@
   RunMessageLoop();
   EXPECT_EQ(drop_call_count_, 1);
 
+  attachment_store_frontend_->ReadMetadataById(
+      AttachmentStore::SYNC, id_list,
+      base::Bind(&AttachmentStoreFrontendTest::ReadMetadataDone));
+  EXPECT_EQ(read_metadata_by_id_call_count_, 0);
+  RunMessageLoop();
+  EXPECT_EQ(read_metadata_by_id_call_count_, 1);
+
   attachment_store_frontend_->ReadMetadata(
-      id_list, base::Bind(&AttachmentStoreFrontendTest::ReadMetadataDone));
+      AttachmentStore::SYNC,
+      base::Bind(&AttachmentStoreFrontendTest::ReadMetadataDone));
   EXPECT_EQ(read_metadata_call_count_, 0);
   RunMessageLoop();
   EXPECT_EQ(read_metadata_call_count_, 1);
 
-  attachment_store_frontend_->ReadAllMetadata(
-      AttachmentStore::SYNC,
-      base::Bind(&AttachmentStoreFrontendTest::ReadMetadataDone));
-  EXPECT_EQ(read_all_metadata_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(read_all_metadata_call_count_, 1);
-
   // Releasing referehce to AttachmentStoreFrontend should result in
   // MockAttachmentStore being deleted on backend loop.
   attachment_store_frontend_ = NULL;
diff --git a/sync/internal_api/attachments/attachment_store_test_template.h b/sync/internal_api/attachments/attachment_store_test_template.h
index e8c44192..86ea20e 100644
--- a/sync/internal_api/attachments/attachment_store_test_template.h
+++ b/sync/internal_api/attachments/attachment_store_test_template.h
@@ -311,7 +311,7 @@
 }
 
 // Verify getting metadata for specific attachments.
-TYPED_TEST_P(AttachmentStoreTest, ReadMetadata) {
+TYPED_TEST_P(AttachmentStoreTest, ReadMetadataById) {
   Attachment attachment1 = Attachment::Create(this->some_data1);
   Attachment attachment2 = Attachment::Create(this->some_data2);
 
@@ -326,7 +326,7 @@
   AttachmentIdList ids;
   ids.push_back(attachment1.GetId());
   ids.push_back(attachment2.GetId());
-  this->store->ReadMetadata(ids, this->read_metadata_callback);
+  this->store->ReadMetadataById(ids, this->read_metadata_callback);
   this->ClearAndPumpLoop();
 
   // See that only one entry was read.
@@ -340,7 +340,7 @@
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
 
   // Try to read metadata for both attachment1 and attachment2 again.
-  this->store->ReadMetadata(ids, this->read_metadata_callback);
+  this->store->ReadMetadataById(ids, this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(2U, this->attachment_metadata->size());
@@ -353,11 +353,11 @@
   EXPECT_EQ(attachment2.GetId(), iter->GetId());
 }
 
-// Verify that ReadAllMetadata/ReadSyncMetadata returns metadata for correct
+// Verify that ReadMetadata/ReadMetadataForSync returns metadata for correct
 // set of attachments.
-TYPED_TEST_P(AttachmentStoreTest, ReadAllMetadata) {
+TYPED_TEST_P(AttachmentStoreTest, ReadMetadata) {
   // Try to read all metadata from an empty store.
-  this->store->ReadAllMetadata(this->read_metadata_callback);
+  this->store->ReadMetadata(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(0U, this->attachment_metadata->size());
@@ -385,49 +385,54 @@
   this->store->Drop(ids, this->drop_callback);
   this->ClearAndPumpLoop();
 
-  // Calling ReadMetadata for above three attachments should return all of them.
+  // Calling ReadMetadataById for above three attachments should only return
+  // attachments with model type reference.
   ids.clear();
-  ids.push_back(attachment_sync.GetId());
+  ids.push_back(attachment_mt.GetId());
   ids.push_back(attachment_sync.GetId());
   ids.push_back(attachment_both.GetId());
-  this->store->ReadMetadata(ids, this->read_metadata_callback);
+  this->store->ReadMetadataById(ids, this->read_metadata_callback);
   this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(3U, this->attachment_metadata->size());
+  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
+  EXPECT_EQ(2U, this->attachment_metadata->size());
+  AttachmentIdSet model_type_id_set;
+  model_type_id_set.insert(attachment_mt.GetId());
+  model_type_id_set.insert(attachment_both.GetId());
+  EXPECT_THAT(model_type_id_set,
+              testing::Contains((*this->attachment_metadata)[0].GetId()));
+  EXPECT_THAT(model_type_id_set,
+              testing::Contains((*this->attachment_metadata)[1].GetId()));
 
-  // Call to ReadAllMetadata() should only return attachments with model type
+  // Call to ReadMetadata() should only return attachments with model type
   // reference.
-  this->store->ReadAllMetadata(this->read_metadata_callback);
+  this->store->ReadMetadata(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(2U, this->attachment_metadata->size());
 
   // Verify that we get all attachments back (the order is undefined).
-  AttachmentIdSet id_set;
-  id_set.insert(attachment_mt.GetId());
-  id_set.insert(attachment_both.GetId());
-  EXPECT_THAT(id_set,
+  EXPECT_THAT(model_type_id_set,
               testing::Contains((*this->attachment_metadata)[0].GetId()));
-  EXPECT_THAT(id_set,
+  EXPECT_THAT(model_type_id_set,
               testing::Contains((*this->attachment_metadata)[1].GetId()));
 
-  // Call to ReadSyncMetadata() should only return attachments with sync
+  // Call to ReadMetadataForSync() should only return attachments with sync
   // reference.
-  this->store_for_sync->ReadSyncMetadata(this->read_metadata_callback);
+  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(2U, this->attachment_metadata->size());
 
-  id_set.clear();
-  id_set.insert(attachment_sync.GetId());
-  id_set.insert(attachment_both.GetId());
-  EXPECT_THAT(id_set,
+  AttachmentIdSet sync_id_set;
+  sync_id_set.insert(attachment_sync.GetId());
+  sync_id_set.insert(attachment_both.GetId());
+  EXPECT_THAT(sync_id_set,
               testing::Contains((*this->attachment_metadata)[0].GetId()));
-  EXPECT_THAT(id_set,
+  EXPECT_THAT(sync_id_set,
               testing::Contains((*this->attachment_metadata)[1].GetId()));
 }
 
-// Verify that setting/droping references gets reflected in ReadAllMetadata and
+// Verify that setting/droping references gets reflected in ReadMetadata and
 // that attachment is only deleted after last reference is droped.
 TYPED_TEST_P(AttachmentStoreTest, SetSyncReference_DropSyncReference) {
   Attachment attachment = Attachment::Create(this->some_data1);
@@ -439,22 +444,22 @@
   // When writing attachment to store only model type reference should be set.
   this->store->Write(attachments, this->write_callback);
 
-  this->store->ReadAllMetadata(this->read_metadata_callback);
+  this->store->ReadMetadata(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(1U, this->attachment_metadata->size());
   EXPECT_EQ(attachment.GetId(), this->attachment_metadata->begin()->GetId());
 
-  this->store_for_sync->ReadSyncMetadata(this->read_metadata_callback);
+  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(0U, this->attachment_metadata->size());
 
-  // After call to SetSyncReference() ReadSyncMetadata should start returning
+  // After call to SetSyncReference() ReadMetadataForSync should start returning
   // attachment.
   this->store_for_sync->SetSyncReference(ids);
 
-  this->store_for_sync->ReadSyncMetadata(this->read_metadata_callback);
+  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(1U, this->attachment_metadata->size());
@@ -469,22 +474,22 @@
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
 
-  this->store->ReadAllMetadata(this->read_metadata_callback);
+  this->store->ReadMetadata(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(0U, this->attachment_metadata->size());
 
-  this->store_for_sync->ReadSyncMetadata(this->read_metadata_callback);
+  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(1U, this->attachment_metadata->size());
 
-  // ReadMetadata should still return this attachment even though it does not
-  // have model type reference.
-  this->store->ReadMetadata(ids, this->read_metadata_callback);
+  // ReadMetadataById should return UNSPECIFIED_ERROR, attachment doesn't have
+  // model type reference.
+  this->store->ReadMetadataById(ids, this->read_metadata_callback);
   this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(1U, this->attachment_metadata->size());
+  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
+  EXPECT_EQ(0U, this->attachment_metadata->size());
 
   // Call Drop() again to ensure it doesn't fail.
   this->store->Drop(ids, this->drop_callback);
@@ -492,18 +497,13 @@
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
 
   // After droping sync reference attachment should be deleted from store.
-  // ReadMetadata should return UNSPECIFIED_ERROR.
+  // ReadMetadataForSync should return empty result.
   this->store_for_sync->DropSyncReference(ids);
 
-  this->store_for_sync->ReadSyncMetadata(this->read_metadata_callback);
+  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
   this->ClearAndPumpLoop();
   EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
   EXPECT_EQ(0U, this->attachment_metadata->size());
-
-  this->store->ReadMetadata(ids, this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(0U, this->attachment_metadata->size());
 }
 
 REGISTER_TYPED_TEST_CASE_P(AttachmentStoreTest,
@@ -513,8 +513,8 @@
                            Read_OneNotFound,
                            Drop_DropTwoButOnlyOneExists,
                            Drop_DoesNotExist,
+                           ReadMetadataById,
                            ReadMetadata,
-                           ReadAllMetadata,
                            SetSyncReference_DropSyncReference);
 
 }  // namespace syncer
diff --git a/sync/internal_api/attachments/in_memory_attachment_store.cc b/sync/internal_api/attachments/in_memory_attachment_store.cc
index f69f102c..340daae 100644
--- a/sync/internal_api/attachments/in_memory_attachment_store.cc
+++ b/sync/internal_api/attachments/in_memory_attachment_store.cc
@@ -39,6 +39,7 @@
 }
 
 void InMemoryAttachmentStore::Read(
+    AttachmentStore::Component component,
     const AttachmentIdList& ids,
     const AttachmentStore::ReadCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -47,9 +48,10 @@
   scoped_ptr<AttachmentIdList> unavailable_attachments(new AttachmentIdList);
 
   for (const auto& id : ids) {
-    AttachmentEntryMap::iterator attachment_iter = attachments_.find(id);
-    if (attachment_iter != attachments_.end()) {
-      const Attachment& attachment = attachment_iter->second.attachment;
+    AttachmentEntryMap::iterator iter = attachments_.find(id);
+    if (iter != attachments_.end() &&
+        iter->second.components.count(component) > 0) {
+      const Attachment& attachment = iter->second.attachment;
       result_map->insert(std::make_pair(id, attachment));
     } else {
       unavailable_attachments->push_back(id);
@@ -104,7 +106,8 @@
   PostCallback(base::Bind(callback, result));
 }
 
-void InMemoryAttachmentStore::ReadMetadata(
+void InMemoryAttachmentStore::ReadMetadataById(
+    AttachmentStore::Component component,
     const AttachmentIdList& ids,
     const AttachmentStore::ReadMetadataCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -113,19 +116,22 @@
       new AttachmentMetadataList());
 
   for (const auto& id : ids) {
-    // TODO(pavely): ReadMetadata should only return attachments with component
-    // reference similarly to ReadAllMetadata behavior.
-    AttachmentEntryMap::iterator attachments_iter = attachments_.find(id);
-    if (attachments_iter != attachments_.end()) {
-      AppendMetadata(metadata_list.get(), attachments_iter->second.attachment);
-    } else {
+    AttachmentEntryMap::iterator iter = attachments_.find(id);
+    if (iter == attachments_.end()) {
       result_code = AttachmentStore::UNSPECIFIED_ERROR;
+      continue;
     }
+    DCHECK(iter->second.components.size() > 0);
+    if (iter->second.components.count(component) == 0) {
+      result_code = AttachmentStore::UNSPECIFIED_ERROR;
+      continue;
+    }
+    AppendMetadata(metadata_list.get(), iter->second.attachment);
   }
   PostCallback(base::Bind(callback, result_code, base::Passed(&metadata_list)));
 }
 
-void InMemoryAttachmentStore::ReadAllMetadata(
+void InMemoryAttachmentStore::ReadMetadata(
     AttachmentStore::Component component,
     const AttachmentStore::ReadMetadataCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -135,6 +141,7 @@
 
   for (AttachmentEntryMap::const_iterator iter = attachments_.begin();
        iter != attachments_.end(); ++iter) {
+    DCHECK(iter->second.components.size() > 0);
     if (iter->second.components.count(component) > 0) {
       AppendMetadata(metadata_list.get(), iter->second.attachment);
     }
diff --git a/sync/internal_api/attachments/on_disk_attachment_store.cc b/sync/internal_api/attachments/on_disk_attachment_store.cc
index 00b4019..a2973234 100644
--- a/sync/internal_api/attachments/on_disk_attachment_store.cc
+++ b/sync/internal_api/attachments/on_disk_attachment_store.cc
@@ -132,6 +132,17 @@
   return component_removed;
 }
 
+bool AttachmentHasReferenceFromComponent(
+    const attachment_store_pb::RecordMetadata& record_metadata,
+    attachment_store_pb::RecordMetadata::Component proto_component) {
+  for (const auto& reference_component : record_metadata.component()) {
+    if (reference_component == proto_component) {
+      return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace
 
 OnDiskAttachmentStore::OnDiskAttachmentStore(
@@ -153,6 +164,7 @@
 }
 
 void OnDiskAttachmentStore::Read(
+    AttachmentStore::Component component,
     const AttachmentIdList& ids,
     const AttachmentStore::ReadCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -164,15 +176,13 @@
 
   if (db_) {
     result_code = AttachmentStore::SUCCESS;
-    AttachmentIdList::const_iterator iter = ids.begin();
-    const AttachmentIdList::const_iterator end = ids.end();
-    for (; iter != end; ++iter) {
+    for (const auto& id : ids) {
       scoped_ptr<Attachment> attachment;
-      attachment = ReadSingleAttachment(*iter);
+      attachment = ReadSingleAttachment(id, component);
       if (attachment) {
-        result_map->insert(std::make_pair(*iter, *attachment));
+        result_map->insert(std::make_pair(id, *attachment));
       } else {
-        unavailable_attachments->push_back(*iter);
+        unavailable_attachments->push_back(id);
       }
     }
     result_code = unavailable_attachments->empty()
@@ -262,7 +272,8 @@
   PostCallback(base::Bind(callback, result_code));
 }
 
-void OnDiskAttachmentStore::ReadMetadata(
+void OnDiskAttachmentStore::ReadMetadataById(
+    AttachmentStore::Component component,
     const AttachmentIdList& ids,
     const AttachmentStore::ReadMetadataCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -272,21 +283,24 @@
       new AttachmentMetadataList());
   if (db_) {
     result_code = AttachmentStore::SUCCESS;
-    // TODO(pavely): ReadMetadata should only return attachments with component
-    // reference similarly to ReadAllMetadata behavior.
     for (const auto& id : ids) {
       attachment_store_pb::RecordMetadata record_metadata;
-      if (ReadSingleRecordMetadata(id, &record_metadata)) {
-        metadata_list->push_back(MakeAttachmentMetadata(id, record_metadata));
-      } else {
+      if (!ReadSingleRecordMetadata(id, &record_metadata)) {
         result_code = AttachmentStore::UNSPECIFIED_ERROR;
+        continue;
       }
+      if (!AttachmentHasReferenceFromComponent(record_metadata,
+                                               ComponentToProto(component))) {
+        result_code = AttachmentStore::UNSPECIFIED_ERROR;
+        continue;
+      }
+      metadata_list->push_back(MakeAttachmentMetadata(id, record_metadata));
     }
   }
   PostCallback(base::Bind(callback, result_code, base::Passed(&metadata_list)));
 }
 
-void OnDiskAttachmentStore::ReadAllMetadata(
+void OnDiskAttachmentStore::ReadMetadata(
     AttachmentStore::Component component,
     const AttachmentStore::ReadMetadataCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -320,15 +334,8 @@
         result_code = AttachmentStore::UNSPECIFIED_ERROR;
         continue;
       }
-      // Check if attachment has reference from component.
-      bool has_reference_from_component = false;
-      for (const auto& reference_component : record_metadata.component()) {
-        if (reference_component == proto_component) {
-          has_reference_from_component = true;
-          break;
-        }
-      }
-      if (has_reference_from_component)
+      DCHECK(record_metadata.component_size() > 0);
+      if (AttachmentHasReferenceFromComponent(record_metadata, proto_component))
         metadata_list->push_back(MakeAttachmentMetadata(id, record_metadata));
     }
 
@@ -393,12 +400,17 @@
 }
 
 scoped_ptr<Attachment> OnDiskAttachmentStore::ReadSingleAttachment(
-    const AttachmentId& attachment_id) {
+    const AttachmentId& attachment_id,
+    AttachmentStore::Component component) {
   scoped_ptr<Attachment> attachment;
   attachment_store_pb::RecordMetadata record_metadata;
   if (!ReadSingleRecordMetadata(attachment_id, &record_metadata)) {
     return attachment.Pass();
   }
+  if (!AttachmentHasReferenceFromComponent(record_metadata,
+                                           ComponentToProto(component)))
+    return attachment.Pass();
+
   const std::string key = MakeDataKeyFromAttachmentId(attachment_id);
   std::string data_str;
   leveldb::Status status = db_->Get(
@@ -484,6 +496,7 @@
     DVLOG(1) << "RecordMetadata::ParseFromString failed";
     return false;
   }
+  DCHECK(record_metadata->component_size() > 0);
   return true;
 }
 
diff --git a/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc b/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc
index 2f45b208..e145172 100644
--- a/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc
+++ b/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc
@@ -442,7 +442,7 @@
 
 // Ensure that attachment store handles the case of having an unexpected
 // record at the end without crashing.
-TEST_F(OnDiskAttachmentStoreSpecificTest, ReadAllMetadataWithUnexpectedRecord) {
+TEST_F(OnDiskAttachmentStoreSpecificTest, ReadMetadataWithUnexpectedRecord) {
   // Write a bogus entry at the end of the database.
   UpdateRecord("zzz", "foobar");
 
@@ -455,7 +455,7 @@
   // Read all metadata. Should be getting no error and zero entries.
   AttachmentStore::Result metadata_result = AttachmentStore::UNSPECIFIED_ERROR;
   scoped_ptr<AttachmentMetadataList> metadata_list;
-  store_->ReadAllMetadata(
+  store_->ReadMetadata(
       base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultMetadata,
                  base::Unretained(this), &metadata_result, &metadata_list));
   RunLoop();
@@ -479,7 +479,7 @@
                            base::Unretained(this), &write_result));
 
   // Read all metadata back. We should be getting 3 entries.
-  store_->ReadAllMetadata(
+  store_->ReadMetadata(
       base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultMetadata,
                  base::Unretained(this), &metadata_result, &metadata_list));
   RunLoop();
@@ -506,7 +506,7 @@
 
   // Read all metadata back. We should be getting a failure and
   // only 2 entries now.
-  store_->ReadAllMetadata(
+  store_->ReadMetadata(
       base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultMetadata,
                  base::Unretained(this), &metadata_result, &metadata_list));
   RunLoop();
diff --git a/sync/internal_api/public/attachments/attachment_store_frontend.h b/sync/internal_api/public/attachments/attachment_store_frontend.h
index 682cb4c..051920d 100644
--- a/sync/internal_api/public/attachments/attachment_store_frontend.h
+++ b/sync/internal_api/public/attachments/attachment_store_frontend.h
@@ -37,7 +37,8 @@
 
   void Init(const AttachmentStore::InitCallback& callback);
 
-  void Read(const AttachmentIdList& ids,
+  void Read(AttachmentStore::Component component,
+            const AttachmentIdList& ids,
             const AttachmentStore::ReadCallback& callback);
 
   void Write(AttachmentStore::Component component,
@@ -49,11 +50,12 @@
                      const AttachmentIdList& ids,
                      const AttachmentStore::DropCallback& callback);
 
-  void ReadMetadata(const AttachmentIdList& ids,
-                    const AttachmentStore::ReadMetadataCallback& callback);
+  void ReadMetadataById(AttachmentStore::Component component,
+                        const AttachmentIdList& ids,
+                        const AttachmentStore::ReadMetadataCallback& callback);
 
-  void ReadAllMetadata(AttachmentStore::Component component,
-                       const AttachmentStore::ReadMetadataCallback& callback);
+  void ReadMetadata(AttachmentStore::Component component,
+                    const AttachmentStore::ReadMetadataCallback& callback);
 
  private:
   friend class base::RefCounted<AttachmentStoreFrontend>;
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 3e53ab1b..d0c7643 100644
--- a/sync/internal_api/public/attachments/in_memory_attachment_store.h
+++ b/sync/internal_api/public/attachments/in_memory_attachment_store.h
@@ -31,7 +31,8 @@
 
   // AttachmentStoreBackend implementation.
   void Init(const AttachmentStore::InitCallback& callback) override;
-  void Read(const AttachmentIdList& ids,
+  void Read(AttachmentStore::Component component,
+            const AttachmentIdList& ids,
             const AttachmentStore::ReadCallback& callback) override;
   void Write(AttachmentStore::Component component,
              const AttachmentList& attachments,
@@ -41,10 +42,11 @@
   void DropReference(AttachmentStore::Component component,
                      const AttachmentIdList& ids,
                      const AttachmentStore::DropCallback& callback) override;
-  void ReadMetadata(
+  void ReadMetadataById(
+      AttachmentStore::Component component,
       const AttachmentIdList& ids,
       const AttachmentStore::ReadMetadataCallback& callback) override;
-  void ReadAllMetadata(
+  void ReadMetadata(
       AttachmentStore::Component component,
       const AttachmentStore::ReadMetadataCallback& callback) override;
 
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 3432853..77159f8 100644
--- a/sync/internal_api/public/attachments/on_disk_attachment_store.h
+++ b/sync/internal_api/public/attachments/on_disk_attachment_store.h
@@ -41,7 +41,8 @@
 
   // AttachmentStoreBackend implementation.
   void Init(const AttachmentStore::InitCallback& callback) override;
-  void Read(const AttachmentIdList& ids,
+  void Read(AttachmentStore::Component component,
+            const AttachmentIdList& ids,
             const AttachmentStore::ReadCallback& callback) override;
   void Write(AttachmentStore::Component component,
              const AttachmentList& attachments,
@@ -51,10 +52,11 @@
   void DropReference(AttachmentStore::Component component,
                      const AttachmentIdList& ids,
                      const AttachmentStore::DropCallback& callback) override;
-  void ReadMetadata(
+  void ReadMetadataById(
+      AttachmentStore::Component component,
       const AttachmentIdList& ids,
       const AttachmentStore::ReadMetadataCallback& callback) override;
-  void ReadAllMetadata(
+  void ReadMetadata(
       AttachmentStore::Component component,
       const AttachmentStore::ReadMetadataCallback& callback) override;
 
@@ -67,7 +69,8 @@
   AttachmentStore::Result OpenOrCreate(const base::FilePath& path);
   // Reads single attachment from store. Returns nullptr in case of errors.
   scoped_ptr<Attachment> ReadSingleAttachment(
-      const AttachmentId& attachment_id);
+      const AttachmentId& attachment_id,
+      AttachmentStore::Component component);
   // Writes single attachment to store. Returns false in case of errors.
   bool WriteSingleAttachment(const Attachment& attachment,
                              AttachmentStore::Component component);
diff --git a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockSyncContentResolverDelegate.java b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockSyncContentResolverDelegate.java
index be2622c4..ea0b003b 100644
--- a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockSyncContentResolverDelegate.java
+++ b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockSyncContentResolverDelegate.java
@@ -114,10 +114,6 @@
         synchronized (mSyncableMapLock) {
             switch (syncable) {
                 case 0:
-                    if (mSyncAutomaticallySet.contains(key)) {
-                        mSyncAutomaticallySet.remove(key);
-                    }
-
                     mIsSyncableMap.put(key, false);
                     break;
                 case 1:
@@ -141,7 +137,7 @@
         String key = createKey(account, authority);
         synchronized (mSyncableMapLock) {
             if (mIsSyncableMap.containsKey(key)) {
-                return mIsSyncableMap.containsKey(key) ? 1 : 0;
+                return mIsSyncableMap.get(key) ? 1 : 0;
             } else {
                 return -1;
             }
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 604cc25..f1cc8d6 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -9,6 +9,16 @@
       }
     ]
   },
+  "Linux ChromiumOS GN (dbg)": {
+    "additional_compile_targets": [
+      "net_unittests"
+    ],
+    "gtest_tests": [
+      {
+        "test": "base_unittests"
+      }
+    ]
+  },
   "Linux ChromiumOS Ozone Tests (1)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index b0903de4..3b3c8fe 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -4,14 +4,14 @@
       {
         "args": [
           "--enable-browser-side-navigation",
-          "--gtest_filter=-BatteryMonitorImplTest.BatteryManagerDefaultValues:BatteryMonitorImplTest.BatteryManagerResolvePromise:BatteryMonitorImplTest.BatteryManagerWithEventListener:BookmarkletTest.DocumentWrite:BookmarkletTest.NonEmptyResult:BookmarkletTest.Redirect:BookmarkletTest.RedirectVoided:ChildProcessLauncherBrowserTest.ChildSpawnFail:CrossProcessFrameTreeBrowserTest.CreateCrossProcessSubframeProxies:CrossProcessFrameTreeBrowserTest.OriginSetOnCrossProcessNavigations:CrossSiteRedirectorBrowserTest.VerifyCrossSiteRedirectURL:CrossSiteTransferTest.NoLeakOnCrossSiteCancel:CrossSiteTransferTest.ReplaceEntryCrossProcessThenTransfer:CrossSiteTransferTest.ReplaceEntryCrossProcessTwice:CrossSiteTransferTest.ReplaceEntryInProcessThenTranfers:DatabaseTest.ReloadPage:DeviceInertialSensorBrowserTest.LightOneOffInfintyTest:DeviceInertialSensorBrowserTest.LightTest:DeviceInertialSensorBrowserTest.MotionNullTest:DeviceInertialSensorBrowserTest.MotionTest:DeviceInertialSensorBrowserTest.OrientationNullTest:DeviceInertialSensorBrowserTest.OrientationTest:DomSerializerTests.SerializeDocumentWithDownloadedIFrame:DOMStorageBrowserTest.SanityCheck:DOMStorageBrowserTest.SanityCheckIncognito:DownloadContentTest.CancelAtFinalRename:DownloadContentTest.CancelAtRelease:DownloadContentTest.CancelInterruptedDownload:DownloadContentTest.CancelResumingDownload:DownloadContentTest.DownloadCancelled:DownloadContentTest.DownloadGZipWithNoContent:DownloadContentTest.DownloadOctetStream:DownloadContentTest.MultiDownload:DownloadContentTest.RemoveDownload:DownloadContentTest.RemoveResumingDownload:DownloadContentTest.ResumeInterruptedDownload:DownloadContentTest.ResumeInterruptedDownloadBadPrecondition:DownloadContentTest.ResumeInterruptedDownloadNoRange:DownloadContentTest.ResumeInterruptedDownloadNoVerifiers:DownloadContentTest.ResumeWithDeletedFile:DownloadContentTest.ResumeWithFileFinalRenameError:DownloadContentTest.ResumeWithFileInitError:DownloadContentTest.ResumeWithFileIntermediateRenameError:DownloadContentTest.ShutdownAtRelease:DownloadContentTest.ShutdownInProgress:File/MediaTest.VideoBearOpusOgg/0:File/MediaTest.VideoBearOpusWebm/0:File/MediaTest.VideoBearSilentTheora/0:File/MediaTest.VideoBearSilentWebm/0:File/MediaTest.VideoBearTheora/0:File/MediaTest.VideoBearWavAlaw/0:File/MediaTest.VideoBearWavMulaw/0:File/MediaTest.VideoBearWavPcm/0:File/MediaTest.VideoBearWavPcm192kHz/0:File/MediaTest.VideoBearWavPcm3kHz/0:File/MediaTest.VideoBearWebm/0:File/MediaTest.VideoTulipWebm/0:FileSystemBrowserTest.CreateTest:FileSystemBrowserTest.RequestTest:FileSystemBrowserTestWithLowQuota.QuotaTest:FrameTreeBrowserTest.FrameTreeAfterCrash:FrameTreeBrowserTest.SandboxFlagsSetForChildFrames:GinBrowserTest.GinAndGarbageCollection:HostZoomMapImplBrowserTest.GetZoomForView_Host:HostZoomMapImplBrowserTest.GetZoomForView_HostAndScheme:IndexedDBBrowserTest.BlobsCountAgainstQuota:IndexedDBBrowserTest.CallbackAccounting:IndexedDBBrowserTest.CanDeleteWhenOverQuotaTest:IndexedDBBrowserTest.ConnectionsClosedOnTabClose:IndexedDBBrowserTest.CursorPrefetch:IndexedDBBrowserTest.CursorTest:IndexedDBBrowserTest.CursorTestIncognito:IndexedDBBrowserTest.DatabaseTest:IndexedDBBrowserTest.DeleteCompactsBackingStore:IndexedDBBrowserTest.DeleteForOriginDeletesBlobs:IndexedDBBrowserTest.DiskFullOnCommit:IndexedDBBrowserTest.DoesntHangTest:IndexedDBBrowserTest.EmptyBlob:IndexedDBBrowserTest.ForceCloseEventTest:IndexedDBBrowserTest.IndexTest:IndexedDBBrowserTest.KeyPathTest:IndexedDBBrowserTest.KeyTypesTest:IndexedDBBrowserTest.LevelDBLogFileTest:IndexedDBBrowserTest.NullKeyPathPersistence:IndexedDBBrowserTest.ObjectStoreTest:IndexedDBBrowserTest.PRE_NullKeyPathPersistence:IndexedDBBrowserTest.PRE_PRE_VersionChangeCrashResilience:IndexedDBBrowserTest.PRE_VersionChangeCrashResilience:IndexedDBBrowserTest.TransactionGetTest:IndexedDBBrowserTest.TransactionTest:IndexedDBBrowserTest.VersionChangeCrashResilience:IndexedDBBrowserTestSingleProcess.RenderThreadShutdownTest:IndexedDBBrowserTestWithCorruptLevelDB.DestroyTest:IndexedDBBrowserTestWithGCExposed.BlobDidAck:IndexedDBBrowserTestWithGCExposed.BlobDidAckPrefetch:IndexedDBBrowserTestWithGCExposed.DatabaseCallbacksTest:IndexedDBBrowserTestWithLowQuota.QuotaTest:IndexedDBBrowserTestWithMissingSSTFile.DestroyTest:IndexedDBBrowserTestWithVersion0Schema.MigrationTest:IndexedDBBrowserTestWithVersion123456Schema.DestroyTest:IndexedDBBrowserTestWithVersion987654SSVData.DestroyTest:ManifestBrowserTest.DummyManifest:ManifestBrowserTest.DynamicManifest:ManifestBrowserTest.ParseErrorManifest:ManifestBrowserTest.ParsingErrorsManifest:MediaCanPlayTypeTest.CodecSupportTest_Avc1Variants:MediaCanPlayTypeTest.CodecSupportTest_Avc3Variants:MediaCanPlayTypeTest.CodecSupportTest_AvcLevels:MediaCanPlayTypeTest.CodecSupportTest_HLS:MediaCanPlayTypeTest.CodecSupportTest_mp3:MediaCanPlayTypeTest.CodecSupportTest_mp4:MediaCanPlayTypeTest.CodecSupportTest_Mp4aVariants:MediaCanPlayTypeTest.CodecSupportTest_ogg:MediaCanPlayTypeTest.CodecSupportTest_wav:MediaCanPlayTypeTest.CodecSupportTest_webm:MediaTest.Navigate:NavigationControllerBrowserTest.CorrectLengthWithCurrentItemReplacement:NavigationControllerBrowserTest.CorrectLengthWithNewTabNavigatingFromWebUI:NavigationControllerBrowserTest.DontIgnoreBackAfterNavEntryLimit:NavigationControllerBrowserTest.ErrorPageReplacement:NavigationControllerBrowserTest.NavigationTypeClassification_ClientSideRedirect:NavigationControllerBrowserTest.NavigationTypeClassification_ExistingPage:NavigationControllerBrowserTest.NavigationTypeClassification_InPage:NavigationControllerBrowserTest.NavigationTypeClassification_NewAndAutoSubframe:NavigationControllerBrowserTest.NavigationTypeClassification_NewPage:NavigationControllerBrowserTest.SubframeOnEmptyPage:OutOfProcessPPAPITest.InputEvent:OutOfProcessPPAPITest.MediaStreamAudioTrack:OutOfProcessPPAPITest.MediaStreamVideoTrack:PluginPowerSaverHelperTest.ClearWhitelistOnNavigate:RendererAccessibilityTest.AccessibilityMessagesQueueWhileSwappedOut:RendererAccessibilityTest.DetachAccessibilityObject:RendererAccessibilityTest.EventOnObjectNotInTree:RendererAccessibilityTest.HideAccessibilityObject:RendererAccessibilityTest.SendFullAccessibilityTreeOnReload:RendererAccessibilityTest.ShowAccessibilityObject:RenderFrameHostImplBrowserTest.IsFocused_AtLoad:RenderFrameHostImplBrowserTest.IsFocused_Widget:RenderFrameHostManagerTest.BackForwardNotStale:RenderFrameHostManagerTest.ClickLinkAfter204Error:RenderFrameHostManagerTest.DisownSubframeOpener:RenderFrameHostManagerTest.DontPreemptNavigationWithFrameTreeUpdate:RenderFrameHostManagerTest.ForceSwapAfterWebUIBindings:RenderFrameHostManagerTest.IgnoreRendererDebugURLsWhenCrashed:RenderFrameHostManagerTest.NoScriptAccessAfterSwapOut:RenderFrameHostManagerTest.RendererDebugURLsDontSwap:RenderFrameHostManagerTest.RestoreFileAccessForHistoryNavigation:RenderFrameHostManagerTest.RestoreSubframeFileAccessForHistoryNavigation:RenderFrameHostManagerTest.ShowLoadingURLUntilSpoof:RenderProcessHostTest.AllProcessExitedCallsBeforeAnyHostDestroyedCalls:RenderViewBrowserTest.ConfirmCacheInformationPlumbed:RenderViewImplTest.DecideNavigationPolicy:RenderViewImplTest.InsertCharacters:RenderViewImplTest.NavigateFrame:RenderViewImplTest.OnHandleKeyboardEvent:RenderViewImplTest.OnNavigationHttpPost:RenderViewImplTest.ReloadWhileSwappedOut:RenderViewImplTest.StaleNavigationsIgnored:RenderViewImplTest.TestBackForward:ResourceDispatcherHostBrowserTest.CrossSiteAfterCrash:ResourceDispatcherHostBrowserTest.CrossSiteFailedRequest:ResourceDispatcherHostBrowserTest.CrossSiteNavigationErrorPage2:ResourceDispatcherHostBrowserTest.CrossSiteNoUnloadOn204:ResourceFetcherTests.ResourceFetcher404:ResourceFetcherTests.ResourceFetcherDeletedInCallback:ResourceFetcherTests.ResourceFetcherDidFail:ResourceFetcherTests.ResourceFetcherDownload:ResourceFetcherTests.ResourceFetcherPost:ResourceFetcherTests.ResourceFetcherSetHeader:ResourceFetcherTests.ResourceFetcherTimeout:SecurityExploitBrowserTest.AttemptDuplicateRenderViewHost:SecurityExploitBrowserTest.AttemptDuplicateRenderWidgetHost:SecurityExploitBrowserTest.InterstitialCommandFromUnderlyingContent:ServiceWorkerBrowserTest.CrossSiteTransfer:ServiceWorkerBrowserTest.ImportsBustMemcache:ServiceWorkerBrowserTest.Reload:ServiceWorkerBrowserTest.ResponseFromHTTPServiceWorkerIsNotMarkedAsSecure:ServiceWorkerBrowserTest.ResponseFromHTTPSServiceWorkerIsMarkedAsSecure:SessionHistoryTest.BasicBackForward:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FragmentBackForward:SessionHistoryTest.FrameBackForward:SessionHistoryTest.FrameFormBackForward:SessionHistoryTest.HistoryLength:SessionHistoryTest.JavascriptHistory:SessionHistoryTest.LocationChangeInSubframe:SessionHistoryTest.LocationReplace:SitePerProcessAccessibilityBrowserTest.CrossSiteIframeAccessibility:SitePerProcessBrowserTest.CleanupCrossSiteIframe:SitePerProcessBrowserTest.CompositorFrameSwapped:SitePerProcessBrowserTest.CreateProxiesForNewFrames:SitePerProcessBrowserTest.CrossSiteDidStopLoading:SitePerProcessBrowserTest.CrossSiteIframe:SitePerProcessBrowserTest.DynamicSandboxFlags:SitePerProcessBrowserTest.DynamicSandboxFlagsRemoteToLocal:SitePerProcessBrowserTest.KillingRendererClearsDescendantProxies:SitePerProcessBrowserTest.NavigateRemoteFrame:SitePerProcessBrowserTest.NavigateRemoteFrameToBlankAndDataURLs:SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcess:SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcessWithSubtree:SitePerProcessBrowserTest.NavigateWithSiblingRemoteFrame:SitePerProcessBrowserTest.OriginReplication:SitePerProcessBrowserTest.ProxyCreationSkipsSubtree:SitePerProcessBrowserTest.RestrictFrameDetach:SitePerProcessBrowserTest.SandboxFlagsReplication:SitePerProcessBrowserTest.SubframePostMessage:SitePerProcessDevToolsBrowserTest.CrossSiteIframeAgentHost:SpeechRecognitionBrowserTest.OneShotRecognition:StatsTableBrowserTest.StartWithStatTable:TracingControllerTest.EnableAndDisableRecording:TracingControllerTest.EnableAndDisableRecordingWithEmptyFileAndNullCallback:TracingControllerTest.EnableAndDisableRecordingWithFilePath:TracingControllerTest.EnableCaptureAndDisableMonitoring:TracingControllerTest.EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback:TracingControllerTest.EnableCaptureAndDisableMonitoringWithFilePath:TracingControllerTest.GetCategories:TransitionBrowserTest.NormalNavigationNotDeferred:TransitionBrowserTest.TransitionNavigationDataIsCleared:TransitionBrowserTest.TransitionNavigationIsDeferred:WebContentsImplBrowserTest.ClearNonVisiblePendingOnFail:WebContentsImplBrowserTest.GetSizeForNewRenderView:WebContentsViewAuraTest.ScreenshotForSwappedOutRenderViews:WebRtcAecDumpBrowserTest.CallWithAecDump:WebRtcAecDumpBrowserTest.CallWithAecDumpEnabledThenDisabled:WebRtcAecDumpBrowserTest.TwoCallsWithAecDump:WebUIMojoTest.EndToEndPing:WorkerTest.IncognitoSharedWorkers:WorkerTest.MultipleSharedWorkers:WorkerTest.MultipleWorkers:WorkerTest.PassMessagePortToSharedWorker:WorkerTest.PassMessagePortToSharedWorkerDontWaitForConnect:WorkerTest.SharedWorkerTlsClientAuth:WorkerTest.SingleSharedWorker:WorkerTest.SingleWorker:WorkerTest.WorkerTlsClientAuth"
+          "--gtest_filter=-BatteryMonitorImplTest.BatteryManagerDefaultValues:BatteryMonitorImplTest.BatteryManagerResolvePromise:BatteryMonitorImplTest.BatteryManagerWithEventListener:BookmarkletTest.DocumentWrite:BookmarkletTest.NonEmptyResult:BookmarkletTest.Redirect:BookmarkletTest.RedirectVoided:ChildProcessLauncherBrowserTest.ChildSpawnFail:CrossProcessFrameTreeBrowserTest.CreateCrossProcessSubframeProxies:CrossProcessFrameTreeBrowserTest.OriginSetOnCrossProcessNavigations:CrossSiteRedirectorBrowserTest.VerifyCrossSiteRedirectURL:CrossSiteTransferTest.NoLeakOnCrossSiteCancel:CrossSiteTransferTest.ReplaceEntryCrossProcessThenTransfer:CrossSiteTransferTest.ReplaceEntryCrossProcessTwice:CrossSiteTransferTest.ReplaceEntryInProcessThenTranfers:DatabaseTest.ReloadPage:DeviceInertialSensorBrowserTest.LightOneOffInfintyTest:DeviceInertialSensorBrowserTest.LightTest:DeviceInertialSensorBrowserTest.MotionNullTest:DeviceInertialSensorBrowserTest.MotionTest:DeviceInertialSensorBrowserTest.OrientationNullTest:DeviceInertialSensorBrowserTest.OrientationTest:DOMStorageBrowserTest.SanityCheck:DOMStorageBrowserTest.SanityCheckIncognito:DownloadContentTest.CancelAtFinalRename:DownloadContentTest.CancelAtRelease:DownloadContentTest.CancelInterruptedDownload:DownloadContentTest.CancelResumingDownload:DownloadContentTest.DownloadCancelled:DownloadContentTest.DownloadGZipWithNoContent:DownloadContentTest.DownloadOctetStream:DownloadContentTest.MultiDownload:DownloadContentTest.RemoveDownload:DownloadContentTest.RemoveResumingDownload:DownloadContentTest.ResumeInterruptedDownload:DownloadContentTest.ResumeInterruptedDownloadBadPrecondition:DownloadContentTest.ResumeInterruptedDownloadNoRange:DownloadContentTest.ResumeInterruptedDownloadNoVerifiers:DownloadContentTest.ResumeWithDeletedFile:DownloadContentTest.ResumeWithFileFinalRenameError:DownloadContentTest.ResumeWithFileInitError:DownloadContentTest.ResumeWithFileIntermediateRenameError:DownloadContentTest.ShutdownAtRelease:DownloadContentTest.ShutdownInProgress:File/MediaTest.VideoBearOpusOgg/0:File/MediaTest.VideoBearOpusWebm/0:File/MediaTest.VideoBearSilentTheora/0:File/MediaTest.VideoBearSilentWebm/0:File/MediaTest.VideoBearTheora/0:File/MediaTest.VideoBearWavAlaw/0:File/MediaTest.VideoBearWavMulaw/0:File/MediaTest.VideoBearWavPcm/0:File/MediaTest.VideoBearWavPcm192kHz/0:File/MediaTest.VideoBearWavPcm3kHz/0:File/MediaTest.VideoBearWebm/0:File/MediaTest.VideoTulipWebm/0:FileSystemBrowserTest.CreateTest:FileSystemBrowserTest.RequestTest:FileSystemBrowserTestWithLowQuota.QuotaTest:FrameTreeBrowserTest.FrameTreeAfterCrash:FrameTreeBrowserTest.SandboxFlagsSetForChildFrames:IndexedDBBrowserTest.BlobsCountAgainstQuota:IndexedDBBrowserTest.CallbackAccounting:IndexedDBBrowserTest.CanDeleteWhenOverQuotaTest:IndexedDBBrowserTest.ConnectionsClosedOnTabClose:IndexedDBBrowserTest.CursorPrefetch:IndexedDBBrowserTest.CursorTest:IndexedDBBrowserTest.CursorTestIncognito:IndexedDBBrowserTest.DatabaseTest:IndexedDBBrowserTest.DeleteCompactsBackingStore:IndexedDBBrowserTest.DeleteForOriginDeletesBlobs:IndexedDBBrowserTest.DiskFullOnCommit:IndexedDBBrowserTest.DoesntHangTest:IndexedDBBrowserTest.EmptyBlob:IndexedDBBrowserTest.ForceCloseEventTest:IndexedDBBrowserTest.IndexTest:IndexedDBBrowserTest.KeyPathTest:IndexedDBBrowserTest.KeyTypesTest:IndexedDBBrowserTest.LevelDBLogFileTest:IndexedDBBrowserTest.NullKeyPathPersistence:IndexedDBBrowserTest.ObjectStoreTest:IndexedDBBrowserTest.PRE_NullKeyPathPersistence:IndexedDBBrowserTest.PRE_PRE_VersionChangeCrashResilience:IndexedDBBrowserTest.PRE_VersionChangeCrashResilience:IndexedDBBrowserTest.TransactionGetTest:IndexedDBBrowserTest.TransactionTest:IndexedDBBrowserTest.VersionChangeCrashResilience:IndexedDBBrowserTestSingleProcess.RenderThreadShutdownTest:IndexedDBBrowserTestWithCorruptLevelDB.DestroyTest:IndexedDBBrowserTestWithGCExposed.BlobDidAck:IndexedDBBrowserTestWithGCExposed.BlobDidAckPrefetch:IndexedDBBrowserTestWithGCExposed.DatabaseCallbacksTest:IndexedDBBrowserTestWithLowQuota.QuotaTest:IndexedDBBrowserTestWithMissingSSTFile.DestroyTest:IndexedDBBrowserTestWithVersion0Schema.MigrationTest:IndexedDBBrowserTestWithVersion123456Schema.DestroyTest:IndexedDBBrowserTestWithVersion987654SSVData.DestroyTest:ManifestBrowserTest.DummyManifest:ManifestBrowserTest.DynamicManifest:ManifestBrowserTest.ParseErrorManifest:ManifestBrowserTest.ParsingErrorsManifest:MediaCanPlayTypeTest.CodecSupportTest_Avc1Variants:MediaCanPlayTypeTest.CodecSupportTest_Avc3Variants:MediaCanPlayTypeTest.CodecSupportTest_AvcLevels:MediaCanPlayTypeTest.CodecSupportTest_HLS:MediaCanPlayTypeTest.CodecSupportTest_mp3:MediaCanPlayTypeTest.CodecSupportTest_mp4:MediaCanPlayTypeTest.CodecSupportTest_Mp4aVariants:MediaCanPlayTypeTest.CodecSupportTest_ogg:MediaCanPlayTypeTest.CodecSupportTest_wav:MediaCanPlayTypeTest.CodecSupportTest_webm:MediaTest.Navigate:NavigationControllerBrowserTest.CorrectLengthWithCurrentItemReplacement:NavigationControllerBrowserTest.CorrectLengthWithNewTabNavigatingFromWebUI:NavigationControllerBrowserTest.DontIgnoreBackAfterNavEntryLimit:NavigationControllerBrowserTest.ErrorPageReplacement:NavigationControllerBrowserTest.NavigationTypeClassification_ClientSideRedirect:NavigationControllerBrowserTest.NavigationTypeClassification_ExistingPage:NavigationControllerBrowserTest.NavigationTypeClassification_InPage:NavigationControllerBrowserTest.NavigationTypeClassification_NewAndAutoSubframe:NavigationControllerBrowserTest.NavigationTypeClassification_NewPage:NavigationControllerBrowserTest.SubframeOnEmptyPage:OutOfProcessPPAPITest.InputEvent:OutOfProcessPPAPITest.MediaStreamAudioTrack:OutOfProcessPPAPITest.MediaStreamVideoTrack:RendererAccessibilityTest.AccessibilityMessagesQueueWhileSwappedOut:RenderFrameHostImplBrowserTest.IsFocused_AtLoad:RenderFrameHostImplBrowserTest.IsFocused_Widget:RenderFrameHostManagerTest.BackForwardNotStale:RenderFrameHostManagerTest.ClickLinkAfter204Error:RenderFrameHostManagerTest.DisownSubframeOpener:RenderFrameHostManagerTest.DontPreemptNavigationWithFrameTreeUpdate:RenderFrameHostManagerTest.ForceSwapAfterWebUIBindings:RenderFrameHostManagerTest.IgnoreRendererDebugURLsWhenCrashed:RenderFrameHostManagerTest.NoScriptAccessAfterSwapOut:RenderFrameHostManagerTest.RendererDebugURLsDontSwap:RenderFrameHostManagerTest.RestoreFileAccessForHistoryNavigation:RenderFrameHostManagerTest.RestoreSubframeFileAccessForHistoryNavigation:RenderFrameHostManagerTest.ShowLoadingURLUntilSpoof:RenderViewImplTest.DecideNavigationPolicy:RenderViewImplTest.InsertCharacters:RenderViewImplTest.NavigateFrame:RenderViewImplTest.NavigationStartOverride:RenderViewImplTest.OnHandleKeyboardEvent:RenderViewImplTest.OnNavigationHttpPost:RenderViewImplTest.ReloadWhileSwappedOut:RenderViewImplTest.StaleNavigationsIgnored:RenderViewImplTest.TestBackForward:ResourceDispatcherHostBrowserTest.CrossSiteAfterCrash:ResourceDispatcherHostBrowserTest.CrossSiteNoUnloadOn204:ResourceFetcherTests.ResourceFetcher404:ResourceFetcherTests.ResourceFetcherDeletedInCallback:ResourceFetcherTests.ResourceFetcherDidFail:ResourceFetcherTests.ResourceFetcherDownload:ResourceFetcherTests.ResourceFetcherPost:ResourceFetcherTests.ResourceFetcherSetHeader:ResourceFetcherTests.ResourceFetcherTimeout:SecurityExploitBrowserTest.AttemptDuplicateRenderViewHost:SecurityExploitBrowserTest.AttemptDuplicateRenderWidgetHost:SecurityExploitBrowserTest.InterstitialCommandFromUnderlyingContent:ServiceWorkerBrowserTest.CrossSiteTransfer:ServiceWorkerBrowserTest.ImportsBustMemcache:ServiceWorkerBrowserTest.Reload:ServiceWorkerBrowserTest.ResponseFromHTTPServiceWorkerIsNotMarkedAsSecure:ServiceWorkerBrowserTest.ResponseFromHTTPSServiceWorkerIsMarkedAsSecure:SessionHistoryTest.BasicBackForward:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FragmentBackForward:SessionHistoryTest.FrameBackForward:SessionHistoryTest.FrameFormBackForward:SessionHistoryTest.HistoryLength:SessionHistoryTest.JavascriptHistory:SessionHistoryTest.LocationChangeInSubframe:SessionHistoryTest.LocationReplace:SitePerProcessAccessibilityBrowserTest.CrossSiteIframeAccessibility:SitePerProcessBrowserTest.CleanupCrossSiteIframe:SitePerProcessBrowserTest.CompositorFrameSwapped:SitePerProcessBrowserTest.CreateProxiesForNewFrames:SitePerProcessBrowserTest.CrossSiteDidStopLoading:SitePerProcessBrowserTest.CrossSiteIframe:SitePerProcessBrowserTest.DynamicSandboxFlags:SitePerProcessBrowserTest.DynamicSandboxFlagsRemoteToLocal:SitePerProcessBrowserTest.KillingRendererClearsDescendantProxies:SitePerProcessBrowserTest.NavigateRemoteFrame:SitePerProcessBrowserTest.NavigateRemoteFrameToBlankAndDataURLs:SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcess:SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcessWithSubtree:SitePerProcessBrowserTest.NavigateWithSiblingRemoteFrame:SitePerProcessBrowserTest.OriginReplication:SitePerProcessBrowserTest.ProxyCreationSkipsSubtree:SitePerProcessBrowserTest.RFPHDestruction:SitePerProcessBrowserTest.RestrictFrameDetach:SitePerProcessBrowserTest.SandboxFlagsReplication:SitePerProcessBrowserTest.SubframePostMessage:SitePerProcessDevToolsBrowserTest.CrossSiteIframeAgentHost:SpeechRecognitionBrowserTest.OneShotRecognition:StatsTableBrowserTest.StartWithStatTable:TransitionBrowserTest.NormalNavigationNotDeferred:TransitionBrowserTest.TransitionNavigationDataIsCleared:TransitionBrowserTest.TransitionNavigationIsDeferred:WebContentsImplBrowserTest.ClearNonVisiblePendingOnFail:WebContentsImplBrowserTest.GetSizeForNewRenderView:WebContentsViewAuraTest.ScreenshotForSwappedOutRenderViews:WebUIMojoTest.EndToEndPing:WorkerTest.IncognitoSharedWorkers:WorkerTest.MultipleSharedWorkers:WorkerTest.MultipleWorkers:WorkerTest.PassMessagePortToSharedWorker:WorkerTest.PassMessagePortToSharedWorkerDontWaitForConnect:WorkerTest.SharedWorkerTlsClientAuth:WorkerTest.SingleSharedWorker:WorkerTest.SingleWorker:WorkerTest.WorkerTlsClientAuth"
         ],
         "test": "content_browsertests"
       },
       {
         "args": [
           "--enable-browser-side-navigation",
-          "--gtest_filter=-NavigationControllerTest.CopyRestoredStateAndNavigate:NavigationControllerTest.LoadURL_AbortDoesntCancelPending:NavigationControllerTest.LoadURL_IgnorePreemptsPending:NavigationControllerTest.ShowRendererURLAfterFailUntilModified:NavigationControllerTest.ShowRendererURLInNewTabUntilModified:OverscrollNavigationOverlayTest.LoadUpdateWithoutNonEmptyPaint:RenderFrameHostManagerTest.CancelPendingProperlyDeletesOrSwaps:RenderFrameHostManagerTest.DetachPendingChild:RenderFrameHostManagerTest.PageDoesBackAndReload:RenderViewHostTest.ResetUnloadOnReload:ResourceDispatcherHostTest.TransferNavigationHtml:ResourceDispatcherHostTest.TransferNavigationText:ResourceDispatcherHostTest.TransferNavigationWithProcessCrash:ResourceDispatcherHostTest.TransferNavigationWithTwoRedirects:ResourceDispatcherHostTest.TransferTwoNavigationsHtml:WebContentsImplTest.CrossSiteNavigationBackPreempted:WebContentsImplTest.CrossSiteNavigationPreempted:WebContentsImplTest.CrossSiteNotPreemptedDuringBeforeUnload:WebContentsImplTest.NoEarlyStop"
+          "--gtest_filter=-NavigationControllerTest.CopyRestoredStateAndNavigate:NavigationControllerTest.LoadURL_AbortDoesntCancelPending:NavigationControllerTest.LoadURL_IgnorePreemptsPending:NavigationControllerTest.ShowRendererURLAfterFailUntilModified:NavigationControllerTest.ShowRendererURLInNewTabUntilModified:RenderFrameHostManagerTest.CancelPendingProperlyDeletesOrSwaps:RenderFrameHostManagerTest.NavigateWithEarlyClose:RenderFrameHostManagerTest.PageDoesBackAndReload:RenderViewHostTest.ResetUnloadOnReload:ResourceDispatcherHostTest.TransferNavigationHtml:ResourceDispatcherHostTest.TransferNavigationText:ResourceDispatcherHostTest.TransferNavigationWithProcessCrash:ResourceDispatcherHostTest.TransferNavigationWithTwoRedirects:ResourceDispatcherHostTest.TransferTwoNavigationsHtml:WebContentsImplTest.ActiveContentsCountChangeBrowsingInstance:WebContentsImplTest.CrossSiteNavigationBackPreempted:WebContentsImplTest.CrossSiteNavigationPreempted:WebContentsImplTest.CrossSiteNotPreemptedDuringBeforeUnload:WebContentsImplTest.NoEarlyStop:WebContentsImplTest.ShowInterstitialCrashRendererThenGoBack:WebContentsImplTest.ShowInterstitialFromBrowserNewNavigationProceed:WebContentsImplTest.ShowInterstitialThenGoBack"
         ],
         "test": "content_unittests"
       }
@@ -26,6 +26,9 @@
         "test": "cacheinvalidation_unittests"
       },
       {
+        "test": "cast_base_unittests"
+      },
+      {
         "test": "cast_media_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 26feb19..f3ad4ca 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -192,7 +192,7 @@
         "args": [
           "performance_browser_tests",
           "--test-launcher-print-test-stdio=always",
-          "--gtest_filter=TabCapturePerformanceTest.*",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
           "--test-launcher-jobs=1",
           "--enable-gpu"
         ],
@@ -227,7 +227,37 @@
         "args": [
           "performance_browser_tests",
           "--test-launcher-print-test-stdio=always",
-          "--gtest_filter=TabCapturePerformanceTest.*",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
+          "--test-launcher-jobs=1",
+          "--enable-gpu"
+        ],
+        "name": "performance_browser_tests",
+        "script": "gtest_perf_test.py"
+      }
+    ]
+  },
+  "Win 7 ATI GPU Perf": {
+    "scripts": [
+      {
+        "args": [
+          "performance_browser_tests",
+          "--test-launcher-print-test-stdio=always",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
+          "--test-launcher-jobs=1",
+          "--enable-gpu"
+        ],
+        "name": "performance_browser_tests",
+        "script": "gtest_perf_test.py"
+      }
+    ]
+  },
+  "Win 7 Intel GPU Perf": {
+    "scripts": [
+      {
+        "args": [
+          "performance_browser_tests",
+          "--test-launcher-print-test-stdio=always",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
           "--test-launcher-jobs=1",
           "--enable-gpu"
         ],
@@ -242,7 +272,7 @@
         "args": [
           "performance_browser_tests",
           "--test-launcher-print-test-stdio=always",
-          "--gtest_filter=TabCapturePerformanceTest.*",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
           "--test-launcher-jobs=1",
           "--enable-gpu"
         ],
@@ -262,6 +292,17 @@
         ],
         "name": "angle_perftests",
         "script": "gtest_perf_test.py"
+      },
+      {
+        "args": [
+          "performance_browser_tests",
+          "--test-launcher-print-test-stdio=always",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
+          "--test-launcher-jobs=1",
+          "--enable-gpu"
+        ],
+        "name": "performance_browser_tests",
+        "script": "gtest_perf_test.py"
       }
     ]
   },
@@ -271,7 +312,7 @@
         "args": [
           "performance_browser_tests",
           "--test-launcher-print-test-stdio=always",
-          "--gtest_filter=TabCapturePerformanceTest.*",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
           "--test-launcher-jobs=1",
           "--enable-gpu"
         ],
@@ -286,7 +327,7 @@
         "args": [
           "performance_browser_tests",
           "--test-launcher-print-test-stdio=always",
-          "--gtest_filter=TabCapturePerformanceTest.*",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
           "--test-launcher-jobs=1",
           "--enable-gpu"
         ],
@@ -296,6 +337,18 @@
     ]
   },
   "Win 8 Perf (2)": {
-    "scripts": []
+    "scripts": [
+      {
+        "args": [
+          "performance_browser_tests",
+          "--test-launcher-print-test-stdio=always",
+          "--gtest_filter=TabCapturePerformanceTest.*:CastV2PerformanceTest.*",
+          "--test-launcher-jobs=1",
+          "--enable-gpu"
+        ],
+        "name": "performance_browser_tests",
+        "script": "gtest_perf_test.py"
+      }
+    ]
   }
 }
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index 002e188..493461c 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -211,16 +211,7 @@
         "test": "wm_unittests"
       }
     ],
-    "scripts": [
-      {
-        "name": "telemetry_unittests",
-        "script": "telemetry_unittests.py"
-      },
-      {
-        "name": "telemetry_perf_unittests",
-        "script": "telemetry_perf_unittests.py"
-      }
-    ]
+    "scripts": []
   },
   "Win 7 Tests x64 (1)": {
     "gtest_tests": [
@@ -476,6 +467,26 @@
       }
     ]
   },
+  "Win x64 GN": {
+    "additional_compile_targets": [
+      "net_unittests"
+    ],
+    "gtest_tests": [
+      {
+        "test": "base_unittests"
+      }
+    ]
+  },
+  "Win x64 GN (dbg)": {
+    "additional_compile_targets": [
+      "net_unittests"
+    ],
+    "gtest_tests": [
+      {
+        "test": "base_unittests"
+      }
+    ]
+  },
   "Win7 Tests (1)": {
     "gtest_tests": [
       {
@@ -985,7 +996,59 @@
   },
   "Win8 GN": {
     "additional_compile_targets": [
-      "all"
+      "accessibility_unittests",
+      "app_list_unittests",
+      "app_shell_unittests",
+      "ash_unittests",
+      "aura_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chrome",
+      "chrome_elf_unittests",
+      "chromedriver_unittests",
+      "components_browsertests",
+      "components_unittests",
+      "compositor_unittests",
+      "content_browsertests",
+      "content_unittests",
+      "courgette_unittests",
+      "crypto_unittests",
+      "device_unittests",
+      "events_unittests",
+      "extensions_browsertests",
+      "extensions_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "interactive_ui_tests",
+      "ipc_mojo_unittests",
+      "ipc_tests",
+      "jingle_unittests",
+      "keyboard_unittests",
+      "media_unittests",
+      "message_center_unittests",
+      "mojo_common_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_system_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "sbox_integration_tests",
+      "sbox_unittests",
+      "sbox_validation_tests",
+      "skia_unittests",
+      "sql_unittests",
+      "sync_integration_tests",
+      "sync_unit_tests",
+      "ui_base_unittests",
+      "ui_touch_selection_unittests",
+      "url_unittests",
+      "views_unittests",
+      "wm_unittests"
     ],
     "gtest_tests": [
       {
@@ -995,7 +1058,59 @@
   },
   "Win8 GN (dbg)": {
     "additional_compile_targets": [
-      "all"
+      "accessibility_unittests",
+      "app_list_unittests",
+      "app_shell_unittests",
+      "ash_unittests",
+      "aura_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chrome",
+      "chrome_elf_unittests",
+      "chromedriver_unittests",
+      "components_browsertests",
+      "components_unittests",
+      "compositor_unittests",
+      "content_browsertests",
+      "content_unittests",
+      "courgette_unittests",
+      "crypto_unittests",
+      "device_unittests",
+      "events_unittests",
+      "extensions_browsertests",
+      "extensions_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "interactive_ui_tests",
+      "ipc_mojo_unittests",
+      "ipc_tests",
+      "jingle_unittests",
+      "keyboard_unittests",
+      "media_unittests",
+      "message_center_unittests",
+      "mojo_common_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_system_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "sbox_integration_tests",
+      "sbox_unittests",
+      "sbox_validation_tests",
+      "skia_unittests",
+      "sql_unittests",
+      "sync_integration_tests",
+      "sync_unit_tests",
+      "ui_base_unittests",
+      "ui_touch_selection_unittests",
+      "url_unittests",
+      "views_unittests",
+      "wm_unittests"
     ],
     "gtest_tests": [
       {
diff --git a/testing/buildbot/client.v8.json b/testing/buildbot/client.v8.json
new file mode 100644
index 0000000..f18c6b92
--- /dev/null
+++ b/testing/buildbot/client.v8.json
@@ -0,0 +1,14 @@
+{
+  "V8 Android GN (dbg)": {
+    "additional_compile_targets": [
+      "chrome_shell_apk"
+    ],
+    "gtest_tests": []
+  },
+  "V8 Linux GN": {
+    "additional_compile_targets": [
+      "all"
+    ],
+    "gtest_tests": []
+  }
+}
diff --git a/testing/buildbot/tryserver.chromium.win.json b/testing/buildbot/tryserver.chromium.win.json
index 60650fa2..29e5e233 100644
--- a/testing/buildbot/tryserver.chromium.win.json
+++ b/testing/buildbot/tryserver.chromium.win.json
@@ -1,7 +1,59 @@
 {
   "win8_chromium_gn_dbg": {
     "additional_compile_targets": [
-      "all"
+      "accessibility_unittests",
+      "app_list_unittests",
+      "app_shell_unittests",
+      "ash_unittests",
+      "aura_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chrome",
+      "chrome_elf_unittests",
+      "chromedriver_unittests",
+      "components_browsertests",
+      "components_unittests",
+      "compositor_unittests",
+      "content_browsertests",
+      "content_unittests",
+      "courgette_unittests",
+      "crypto_unittests",
+      "device_unittests",
+      "events_unittests",
+      "extensions_browsertests",
+      "extensions_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "interactive_ui_tests",
+      "ipc_mojo_unittests",
+      "ipc_tests",
+      "jingle_unittests",
+      "keyboard_unittests",
+      "media_unittests",
+      "message_center_unittests",
+      "mojo_common_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_system_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "sbox_integration_tests",
+      "sbox_unittests",
+      "sbox_validation_tests",
+      "skia_unittests",
+      "sql_unittests",
+      "sync_integration_tests",
+      "sync_unit_tests",
+      "ui_base_unittests",
+      "ui_touch_selection_unittests",
+      "url_unittests",
+      "views_unittests",
+      "wm_unittests"
     ],
     "gtest_tests": [
       {
@@ -11,7 +63,59 @@
   },
   "win8_chromium_gn_rel": {
     "additional_compile_targets": [
-      "all"
+      "accessibility_unittests",
+      "app_list_unittests",
+      "app_shell_unittests",
+      "ash_unittests",
+      "aura_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chrome",
+      "chrome_elf_unittests",
+      "chromedriver_unittests",
+      "components_browsertests",
+      "components_unittests",
+      "compositor_unittests",
+      "content_browsertests",
+      "content_unittests",
+      "courgette_unittests",
+      "crypto_unittests",
+      "device_unittests",
+      "events_unittests",
+      "extensions_browsertests",
+      "extensions_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "interactive_ui_tests",
+      "ipc_mojo_unittests",
+      "ipc_tests",
+      "jingle_unittests",
+      "keyboard_unittests",
+      "media_unittests",
+      "message_center_unittests",
+      "mojo_common_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_system_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "sbox_integration_tests",
+      "sbox_unittests",
+      "sbox_validation_tests",
+      "skia_unittests",
+      "sql_unittests",
+      "sync_integration_tests",
+      "sync_unit_tests",
+      "ui_base_unittests",
+      "ui_touch_selection_unittests",
+      "url_unittests",
+      "views_unittests",
+      "wm_unittests"
     ],
     "gtest_tests": [
       {
diff --git a/testing/buildbot/tryserver.v8.json b/testing/buildbot/tryserver.v8.json
new file mode 100644
index 0000000..aa8e50d
--- /dev/null
+++ b/testing/buildbot/tryserver.v8.json
@@ -0,0 +1,14 @@
+{
+  "v8_android_chromium_gn_dbg": {
+    "additional_compile_targets": [
+      "chrome_shell_apk"
+    ],
+    "gtest_tests": []
+  },
+  "v8_linux_chromium_gn_rel": {
+    "additional_compile_targets": [
+      "all"
+    ],
+    "gtest_tests": []
+  }
+}
diff --git a/testing/chromoting/browser_tests_launcher.py b/testing/chromoting/browser_tests_launcher.py
index 053ea5e..2fceb7c 100644
--- a/testing/chromoting/browser_tests_launcher.py
+++ b/testing/chromoting/browser_tests_launcher.py
@@ -50,9 +50,8 @@
     results = subprocess.check_output(cmd_line, stderr=subprocess.STDOUT,
                                       shell=True)
   except subprocess.CalledProcessError, e:
-    raise Exception('Exception %s running command %s\n' %
-                    (e, command))
-  else:
+    results = e.output
+  finally:
     print results
   return results
 
@@ -196,7 +195,7 @@
   # Was there any test failure?
   if TEST_FAILURE:
     print '++++++++++AT LEAST 1 TEST FAILED++++++++++'
-    print FAILING_TESTS
+    print FAILING_TESTS.rstrip('\n')
     print '++++++++++++++++++++++++++++++++++++++++++'
     raise Exception('At least one test failed.')
 
diff --git a/testing/iossim/OWNERS b/testing/iossim/OWNERS
index 7f8c2f83..1b3348e7 100644
--- a/testing/iossim/OWNERS
+++ b/testing/iossim/OWNERS
@@ -1,3 +1,2 @@
-lliabraa@chromium.org
 rohitrao@chromium.org
 stuartmorgan@chromium.org
diff --git a/third_party/boringssl/boringssl_nacl.gyp b/third_party/boringssl/boringssl_nacl.gyp
index 6ab4b9d..cfd43b9 100644
--- a/third_party/boringssl/boringssl_nacl.gyp
+++ b/third_party/boringssl/boringssl_nacl.gyp
@@ -16,7 +16,6 @@
         'build_pnacl_newlib': 1,
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
       ],
       'includes': [
diff --git a/third_party/closure_compiler/compiler/compiler.jar b/third_party/closure_compiler/compiler/compiler.jar
index 61d06bc9..252ac9eb 100644
--- a/third_party/closure_compiler/compiler/compiler.jar
+++ b/third_party/closure_compiler/compiler/compiler.jar
Binary files differ
diff --git a/third_party/closure_compiler/externs/chrome_extensions.js b/third_party/closure_compiler/externs/chrome_extensions.js
index e7f1320a..06198b4c1 100644
--- a/third_party/closure_compiler/externs/chrome_extensions.js
+++ b/third_party/closure_compiler/externs/chrome_extensions.js
@@ -7550,29 +7550,33 @@
 
 
 /**
- * @param {string} notificationId
- * @param {!chrome.notifications.NotificationOptions} options
- * @param {function(string): void} callback
+ * @param {string|!chrome.notifications.NotificationOptions}
+ *     notificationIdOrOptions
+ * @param {(!chrome.notifications.NotificationOptions|function(string): void)=}
+ *     opt_optionsOrCallback
+ * @param {(function(string): void)=} opt_callback
  * @see http://developer.chrome.com/extensions/notifications.html#method-create
  */
-chrome.notifications.create = function(notificationId, options, callback) {};
+chrome.notifications.create = function(notificationIdOrOptions,
+    opt_optionsOrCallback, opt_callback) {};
 
 
 /**
  * @param {string} notificationId
  * @param {!chrome.notifications.NotificationOptions} options
- * @param {!chrome.notifications.BooleanCallback} callback
+ * @param {chrome.notifications.BooleanCallback=} opt_callback
  * @see http://developer.chrome.com/extensions/notifications.html#method-update
  */
-chrome.notifications.update = function(notificationId, options, callback) {};
+chrome.notifications.update =
+    function(notificationId, options, opt_callback) {};
 
 
 /**
  * @param {string} notificationId
- * @param {!chrome.notifications.BooleanCallback} callback
+ * @param {!chrome.notifications.BooleanCallback=} opt_callback
  * @see http://developer.chrome.com/extensions/notifications.html#method-clear
  */
-chrome.notifications.clear = function(notificationId, callback) {};
+chrome.notifications.clear = function(notificationId, opt_callback) {};
 
 
 /**
@@ -8605,7 +8609,7 @@
 /**
  * @type {number|undefined}
  */
-chrome.networkingPrivate.WiFiStateProperties.prototype.SignalStrength;
+chrome.networkingPrivate.WiMAXStateProperties.prototype.SignalStrength;
 
 
 /**
diff --git a/third_party/closure_compiler/externs/developer_private.js b/third_party/closure_compiler/externs/developer_private.js
index 2dbf1db..b098b243 100644
--- a/third_party/closure_compiler/externs/developer_private.js
+++ b/third_party/closure_compiler/externs/developer_private.js
@@ -386,6 +386,7 @@
   VIEW_REGISTERED: 'VIEW_REGISTERED',
   VIEW_UNREGISTERED: 'VIEW_UNREGISTERED',
   ERROR_ADDED: 'ERROR_ADDED',
+  PREFS_CHANGED: 'PREFS_CHANGED',
 };
 
 /**
diff --git a/third_party/closure_compiler/runner/runner.jar b/third_party/closure_compiler/runner/runner.jar
index 2412698..eadbd1d 100644
--- a/third_party/closure_compiler/runner/runner.jar
+++ b/third_party/closure_compiler/runner/runner.jar
Binary files differ
diff --git a/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java b/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
index 274f0f8..8a4d814 100644
--- a/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
+++ b/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
@@ -155,7 +155,7 @@
     private void setJsDocWithType(Node target, Node type) {
         JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
         builder.recordType(new JSTypeExpression(type, ""));
-        target.setJSDocInfo(builder.build(target));
+        target.setJSDocInfo(builder.build());
     }
 
     private boolean visitMakePublic(Node call, Node exprResult) {
diff --git a/third_party/jsoncpp/jsoncpp_nacl.gyp b/third_party/jsoncpp/jsoncpp_nacl.gyp
index d60510c..565cb38 100644
--- a/third_party/jsoncpp/jsoncpp_nacl.gyp
+++ b/third_party/jsoncpp/jsoncpp_nacl.gyp
@@ -24,9 +24,6 @@
             # overrides/src/lib_json/json_value.cpp:38.
             '-fno-strict-aliasing',
           ],
-          'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-          ],
         },
       ],
     }],
diff --git a/third_party/libevent/libevent_nacl_nonsfi.gyp b/third_party/libevent/libevent_nacl_nonsfi.gyp
index 704de105..37a78ad6 100644
--- a/third_party/libevent/libevent_nacl_nonsfi.gyp
+++ b/third_party/libevent/libevent_nacl_nonsfi.gyp
@@ -40,9 +40,6 @@
             'build_pnacl_newlib': 0,
             'build_nonsfi_helper': 1,
           },
-          'dependencies': [
-            '../../native_client/tools.gyp:prep_toolchain',
-          ],
         },
       ],
     }],
diff --git a/third_party/libjingle/BUILD.gn b/third_party/libjingle/BUILD.gn
index 99fadfb..f3991238 100644
--- a/third_party/libjingle/BUILD.gn
+++ b/third_party/libjingle/BUILD.gn
@@ -99,10 +99,7 @@
     defines += [ "ANDROID" ]
   }
   if (is_posix) {
-    defines += [
-      "POSIX",
-      "WEBRTC_POSIX",
-    ]
+    defines += [ "WEBRTC_POSIX" ]
   }
 
   # TODO(GYP): Support these in GN.
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index 9b8891c..50c79fc 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@
 Name: libjingle
 URL: http://code.google.com/p/webrtc/
 Version: unknown
-Revision: 9029
+Revision: 9040
 License: BSD
 License File: source/talk/COPYING
 Security Critical: yes
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp
index 6b72ac2..7cda1966 100644
--- a/third_party/libjingle/libjingle.gyp
+++ b/third_party/libjingle/libjingle.gyp
@@ -130,7 +130,6 @@
         }],
         ['os_posix==1', {
           'defines': [
-            'POSIX',
             'WEBRTC_POSIX',
           ],
         }],
@@ -241,7 +240,6 @@
       }],
       ['os_posix == 1', {
         'defines': [
-          'POSIX',
           'WEBRTC_POSIX',
         ],
       }],
diff --git a/third_party/libjingle/libjingle_nacl.gyp b/third_party/libjingle/libjingle_nacl.gyp
index 6848b29..c7049ec4 100644
--- a/third_party/libjingle/libjingle_nacl.gyp
+++ b/third_party/libjingle/libjingle_nacl.gyp
@@ -25,7 +25,6 @@
         'use_openssl': 1,
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
         '<(DEPTH)/third_party/expat/expat_nacl.gyp:expat_nacl',
         '<(DEPTH)/third_party/boringssl/boringssl_nacl.gyp:boringssl_nacl',
@@ -38,7 +37,6 @@
         'HAVE_OPENSSL_SSL_H',
         'NO_MAIN_THREAD_WRAPPING',
         'NO_SOUND_SYSTEM',
-        'POSIX',
         'WEBRTC_POSIX',
         'SRTP_RELATIVE_PATH',
         'SSL_USE_OPENSSL',
@@ -287,7 +285,6 @@
           'GTEST_RELATIVE_PATH',
           'NO_MAIN_THREAD_WRAPPING',
           'NO_SOUND_SYSTEM',
-          'POSIX',
           'WEBRTC_POSIX',
           'SRTP_RELATIVE_PATH',
           'SSL_USE_OPENSSL',
diff --git a/third_party/liblouis/liblouis_nacl.gyp b/third_party/liblouis/liblouis_nacl.gyp
index 081658f..478252af 100644
--- a/third_party/liblouis/liblouis_nacl.gyp
+++ b/third_party/liblouis/liblouis_nacl.gyp
@@ -65,9 +65,6 @@
             'src/liblouis/transcommon.ci',
             'src/liblouis/wrappers.c',
           ],
-          'dependencies': [
-            '../../native_client/tools.gyp:prep_toolchain',
-          ],
         },
         {
           'target_name': 'liblouis_nacl_wrapper_nacl',
@@ -119,7 +116,6 @@
           ],
           'dependencies': [
             '../../native_client/src/untrusted/nacl/nacl.gyp:nacl_lib',
-            '../../native_client/tools.gyp:prep_toolchain',
             '../../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
             '../../ppapi/native_client/native_client.gyp:ppapi_lib',
             '../../ppapi/ppapi_nacl.gyp:ppapi_cpp_lib',
diff --git a/third_party/libusb/README.chromium b/third_party/libusb/README.chromium
index fc81c05..e74344c 100644
--- a/third_party/libusb/README.chromium
+++ b/third_party/libusb/README.chromium
@@ -19,3 +19,4 @@
 - upstream-tick147.patch has been applied.
 - linux-udev.patch has been applied.
 - composite-hid-close.patch has been applied.
+- assign-endpoints-checks.patch has been applied.
\ No newline at end of file
diff --git a/third_party/libusb/assign-endpoints-checks.patch b/third_party/libusb/assign-endpoints-checks.patch
new file mode 100644
index 0000000..7ed09bdb
--- /dev/null
+++ b/third_party/libusb/assign-endpoints-checks.patch
@@ -0,0 +1,17 @@
+diff --git a/third_party/libusb/src/libusb/os/windows_usb.c b/third_party/libusb/src/libusb/os/windows_usb.c
+index 259897e..4469992 100644
+--- a/third_party/libusb/src/libusb/os/windows_usb.c
++++ b/third_party/libusb/src/libusb/os/windows_usb.c
+@@ -663,6 +663,12 @@ static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int
+ 		return r;
+ 	}
+ 
++	if (iface >= conf_desc->bNumInterfaces ||
++	    altsetting >= conf_desc->interface[iface].num_altsetting) {
++		usbi_dbg("interface %d, altsetting %d out of range", iface, altsetting);
++		return LIBUSB_ERROR_INVALID_PARAM;
++	}
++
+ 	if_desc = &conf_desc->interface[iface].altsetting[altsetting];
+ 	safe_free(priv->usb_interface[iface].endpoint);
+ 
diff --git a/third_party/libusb/src/libusb/os/windows_usb.c b/third_party/libusb/src/libusb/os/windows_usb.c
index 259897e..4469992 100644
--- a/third_party/libusb/src/libusb/os/windows_usb.c
+++ b/third_party/libusb/src/libusb/os/windows_usb.c
@@ -663,6 +663,12 @@
 		return r;
 	}
 
+	if (iface >= conf_desc->bNumInterfaces ||
+	    altsetting >= conf_desc->interface[iface].num_altsetting) {
+		usbi_dbg("interface %d, altsetting %d out of range", iface, altsetting);
+		return LIBUSB_ERROR_INVALID_PARAM;
+	}
+
 	if_desc = &conf_desc->interface[iface].altsetting[altsetting];
 	safe_free(priv->usb_interface[iface].endpoint);
 
diff --git a/third_party/modp_b64/modp_b64_nacl.gyp b/third_party/modp_b64/modp_b64_nacl.gyp
index cd0d210d..e2f4a254 100644
--- a/third_party/modp_b64/modp_b64_nacl.gyp
+++ b/third_party/modp_b64/modp_b64_nacl.gyp
@@ -16,9 +16,6 @@
         'build_newlib': 1,
         'build_pnacl_newlib': 1,
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
       'sources': [
         'modp_b64.cc',
         'modp_b64.h',
diff --git a/third_party/mojo/src/mojo/edk/embedder/simple_platform_shared_buffer_win.cc b/third_party/mojo/src/mojo/edk/embedder/simple_platform_shared_buffer_win.cc
index 0737465..49b82d86 100644
--- a/third_party/mojo/src/mojo/edk/embedder/simple_platform_shared_buffer_win.cc
+++ b/third_party/mojo/src/mojo/edk/embedder/simple_platform_shared_buffer_win.cc
@@ -48,9 +48,8 @@
     ScopedPlatformHandle platform_handle) {
   DCHECK(!handle_.is_valid());
 
-  // TODO(vtl): Implement.
-  NOTIMPLEMENTED();
-  return false;
+  handle_ = platform_handle.Pass();
+  return true;
 }
 
 scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::MapImpl(
diff --git a/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc b/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc
index 4417937..a422c9e 100644
--- a/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc
+++ b/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc
@@ -15,6 +15,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
+#include "base/process/process.h"
 #include "base/synchronization/lock.h"
 #include "base/win/windows_version.h"
 #include "mojo/edk/embedder/platform_handle.h"
@@ -360,8 +361,7 @@
 }
 
 size_t RawChannelWin::GetSerializedPlatformHandleSize() const {
-  // TODO(vtl): Implement.
-  return 0;
+  return sizeof(DWORD) + sizeof(HANDLE);
 }
 
 RawChannel::IOResult RawChannelWin::Read(size_t* bytes_read) {
@@ -437,9 +437,37 @@
 embedder::ScopedPlatformHandleVectorPtr RawChannelWin::GetReadPlatformHandles(
     size_t num_platform_handles,
     const void* platform_handle_table) {
-  // TODO(vtl): Implement.
-  NOTIMPLEMENTED();
-  return embedder::ScopedPlatformHandleVectorPtr();
+  // TODO(jam): this code will have to be updated once it's used in a sandbox
+  // and the receiving process doesn't have duplicate permission for the
+  // receiver. Once there's a broker and we have a connection to it (possibly
+  // through ConnectionManager), then we can make a sync IPC to it here to get a
+  // token for this handle, and it will duplicate the handle to is process. Then
+  // we pass the token to the receiver, which will then make a sync call to the
+  // broker to get a duplicated handle. This will also allow us to avoid leaks
+  // of the handle if the receiver dies, since the broker can notice that.
+  DCHECK_GT(num_platform_handles, 0u);
+  embedder::ScopedPlatformHandleVectorPtr rv(
+      new embedder::PlatformHandleVector());
+
+  const char* serialization_data =
+      static_cast<const char*>(platform_handle_table);
+  for (size_t i = 0; i < num_platform_handles; i++) {
+    DWORD pid = *reinterpret_cast<const DWORD*>(serialization_data);
+    serialization_data += sizeof(DWORD);
+    HANDLE source_handle = *reinterpret_cast<const HANDLE*>(serialization_data);
+    serialization_data += sizeof(HANDLE);
+    base::Process sender =
+        base::Process::OpenWithAccess(pid, PROCESS_DUP_HANDLE);
+    DCHECK(sender.IsValid());
+    HANDLE target_handle = NULL;
+    BOOL dup_result =
+        DuplicateHandle(sender.Handle(), source_handle,
+                        base::GetCurrentProcessHandle(), &target_handle, 0,
+                        FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+    DCHECK(dup_result);
+    rv->push_back(embedder::PlatformHandle(target_handle));
+  }
+  return rv.Pass();
 }
 
 RawChannel::IOResult RawChannelWin::WriteNoLock(
@@ -450,9 +478,28 @@
   DCHECK(io_handler_);
   DCHECK(!io_handler_->pending_write_no_lock());
 
+  size_t num_platform_handles = 0;
   if (write_buffer_no_lock()->HavePlatformHandlesToSend()) {
-    // TODO(vtl): Implement.
-    NOTIMPLEMENTED();
+    // Since we're not sure which process might ultimately deserialize this
+    // message, we can't duplicate the handle now. Instead, write the process ID
+    // and handle now and let the receiver duplicate it.
+    embedder::PlatformHandle* platform_handles;
+    void* serialization_data_temp;
+    write_buffer_no_lock()->GetPlatformHandlesToSend(
+        &num_platform_handles, &platform_handles, &serialization_data_temp);
+    char* serialization_data = static_cast<char*>(serialization_data_temp);
+    DCHECK_GT(num_platform_handles, 0u);
+    DCHECK(platform_handles);
+
+    DWORD current_process_id = base::GetCurrentProcId();
+    for (size_t i = 0; i < num_platform_handles; i++) {
+      *reinterpret_cast<DWORD*>(serialization_data) = current_process_id;
+      serialization_data += sizeof(DWORD);
+      *reinterpret_cast<HANDLE*>(serialization_data) =
+          platform_handles[i].handle;
+      serialization_data += sizeof(HANDLE);
+      platform_handles[i] = embedder::PlatformHandle();
+    }
   }
 
   std::vector<WriteBuffer::Buffer> buffers;
@@ -476,7 +523,7 @@
   }
 
   if (result && skip_completion_port_on_success_) {
-    *platform_handles_written = 0;
+    *platform_handles_written = num_platform_handles;
     *bytes_written = bytes_written_dword;
     return IO_SUCCEEDED;
   }
diff --git a/third_party/mojo_services/src/surfaces/public/cpp/BUILD.gn b/third_party/mojo_services/src/surfaces/public/cpp/BUILD.gn
deleted file mode 100644
index 9cf48b33..0000000
--- a/third_party/mojo_services/src/surfaces/public/cpp/BUILD.gn
+++ /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.
-
-import("//build/module_args/mojo.gni")
-import("$mojo_sdk_root/mojo/public/mojo_sdk.gni")
-
-mojo_sdk_source_set("cpp") {
-  restrict_external_deps = false
-  public_configs = [ "../../../public/build/config:mojo_services" ]
-  sources = [
-    "surfaces_utils.cc",
-    "surfaces_utils.h",
-  ]
-
-  deps = [
-    "../../../geometry/public/interfaces",
-    "../../../surfaces/public/interfaces",
-  ]
-}
diff --git a/third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.cc b/third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.cc
deleted file mode 100644
index 2e52fd26..0000000
--- a/third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.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 "surfaces/public/cpp/surfaces_utils.h"
-
-#include "geometry/public/interfaces/geometry.mojom.h"
-
-namespace mojo {
-
-namespace {
-TransformPtr GetIdentityTransform() {
-  TransformPtr transform(Transform::New());
-  transform->matrix.resize(16);
-  transform->matrix[0] = 1.f;
-  transform->matrix[5] = 1.f;
-  transform->matrix[10] = 1.f;
-  transform->matrix[15] = 1.f;
-  return transform.Pass();
-}
-}
-
-SharedQuadStatePtr CreateDefaultSQS(const Size& size) {
-  SharedQuadStatePtr sqs = SharedQuadState::New();
-  sqs->content_to_target_transform = GetIdentityTransform();
-  sqs->content_bounds = size.Clone();
-  Rect rect;
-  rect.width = size.width;
-  rect.height = size.height;
-  sqs->visible_content_rect = rect.Clone();
-  sqs->clip_rect = rect.Clone();
-  sqs->is_clipped = false;
-  sqs->opacity = 1.f;
-  sqs->blend_mode = mojo::SK_XFERMODE_kSrc_Mode;
-  sqs->sorting_context_id = 0;
-  return sqs.Pass();
-}
-
-PassPtr CreateDefaultPass(int id, const Rect& rect) {
-  PassPtr pass = Pass::New();
-  pass->id = id;
-  pass->output_rect = rect.Clone();
-  pass->damage_rect = rect.Clone();
-  pass->transform_to_root_target = GetIdentityTransform();
-  pass->has_transparent_background = false;
-  return pass.Pass();
-}
-
-}  // namespace mojo
diff --git a/third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.h b/third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.h
deleted file mode 100644
index f74731e..0000000
--- a/third_party/mojo_services/src/surfaces/public/cpp/surfaces_utils.h
+++ /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.
-
-#ifndef MOJO_SERVICES_SURFACES_PUBLIC_CPP_SURFACES_UTILS_H_
-#define MOJO_SERVICES_SURFACES_PUBLIC_CPP_SURFACES_UTILS_H_
-
-#include "surfaces/public/interfaces/quads.mojom.h"
-
-namespace mojo {
-class Rect;
-class Size;
-
-SharedQuadStatePtr CreateDefaultSQS(const Size& size);
-
-// Constructs a pass with the given id, output_rect and damage_rect set to rect,
-// transform_to_root_target set to identity and has_transparent_background set
-// to false.
-PassPtr CreateDefaultPass(int id, const Rect& rect);
-
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_SURFACES_PUBLIC_CPP_SURFACES_UTILS_H_
diff --git a/third_party/mojo_services/src/surfaces/public/interfaces/quads.mojom b/third_party/mojo_services/src/surfaces/public/interfaces/quads.mojom
index 2418d51..3022df0a 100644
--- a/third_party/mojo_services/src/surfaces/public/interfaces/quads.mojom
+++ b/third_party/mojo_services/src/surfaces/public/interfaces/quads.mojom
@@ -202,7 +202,7 @@
 };
 
 struct Pass {
-  int32 id;
+  RenderPassId id;
   Rect output_rect;
   Rect damage_rect;
   Transform transform_to_root_target;
diff --git a/third_party/opus/opus_nacl.gyp b/third_party/opus/opus_nacl.gyp
index c4287c27..27dc55c 100644
--- a/third_party/opus/opus_nacl.gyp
+++ b/third_party/opus/opus_nacl.gyp
@@ -16,9 +16,6 @@
         'build_newlib': 0,
         'build_pnacl_newlib': 1,
       },
-      'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-      ],
       'defines': [
         'OPUS_BUILD',
         'OPUS_EXPORT=',
diff --git a/third_party/protobuf/protobuf_nacl.gyp b/third_party/protobuf/protobuf_nacl.gyp
index e8741c2..ae37f2f 100644
--- a/third_party/protobuf/protobuf_nacl.gyp
+++ b/third_party/protobuf/protobuf_nacl.gyp
@@ -17,9 +17,6 @@
         'build_pnacl_newlib': 1,
         'config_h_dir': '.',
       },
-      'dependencies': [
-        '../../native_client/tools.gyp:prep_toolchain',
-      ],
       'pnacl_compile_flags': [
         # This disables #warning in hash_map/hash_set headers which are
         # deprecated but still used in protobuf.
diff --git a/third_party/re2/README.chromium b/third_party/re2/README.chromium
index 34c6d5e..56a3f811 100644
--- a/third_party/re2/README.chromium
+++ b/third_party/re2/README.chromium
@@ -18,7 +18,6 @@
 - Support for Windows (patches/re2-msvc9-chrome.patch)
 - Support Android (patches/re2-android.patch)
 - Remove static initializers (patches/remove-static-initializers.patch)
-- Rename POSIX configuration (patches/rename-posix-option.patch)
 - Support libcxx (patches/re2-libcxx.patch)
   https://code.google.com/p/re2/issues/detail?id=76
 - Memory optimization for filtered trees
@@ -30,3 +29,4 @@
 - Remove comparisons of this with NULL, merges upstream b92ce81f1e25
 - Let COMPILE_ASSERT use static_assert if available, merges upstream
   2225f94df8ec
+- Merge upstream cc56ba02d9d2bdafa614ad5ebf564dde287625bb.
diff --git a/third_party/re2/patches/re2-memory-optimization.patch b/third_party/re2/patches/re2-memory-optimization.patch
deleted file mode 100644
index 05299b39..0000000
--- a/third_party/re2/patches/re2-memory-optimization.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-diff --git a/re2/prefilter_tree.cc b/re2/prefilter_tree.cc
---- a/re2/prefilter_tree.cc
-+++ b/re2/prefilter_tree.cc
-@@ -107,21 +107,23 @@ void PrefilterTree::Compile(vector<string>* atom_vec) {
-   // not miss out on any regexps triggering by getting rid of a
-   // prefilter node.
-   for (int i = 0; i < entries_.size(); i++) {
--    IntMap* parents = entries_[i].parents;
-+    StdIntMap* parents = entries_[i].parents;
-     if (parents->size() > 8) {
-       // This one triggers too many things. If all the parents are AND
-       // nodes and have other things guarding them, then get rid of
-       // this trigger. TODO(vsri): Adjust the threshold appropriately,
-       // make it a function of total number of nodes?
-       bool have_other_guard = true;
--      for (IntMap::iterator it = parents->begin(); it != parents->end(); ++it)
-+      for (StdIntMap::iterator it = parents->begin();
-+           it != parents->end(); ++it) {
-         have_other_guard = have_other_guard &&
--            (entries_[it->index()].propagate_up_at_count > 1);
-+            (entries_[it->first].propagate_up_at_count > 1);
-+      }
- 
-       if (have_other_guard) {
--        for (IntMap::iterator it = parents->begin();
-+        for (StdIntMap::iterator it = parents->begin();
-              it != parents->end(); ++it)
--          entries_[it->index()].propagate_up_at_count -= 1;
-+          entries_[it->first].propagate_up_at_count -= 1;
- 
-         parents->clear();  // Forget the parents
-       }
-@@ -213,7 +215,7 @@ void PrefilterTree::AssignUniqueIds(vector<string>* atom_vec) {
-   }
-   entries_.resize(node_map_.size());
- 
--  // Create parent IntMap for the entries.
-+  // Create parent StdIntMap for the entries.
-   for (int i = v.size()  - 1; i >= 0; i--) {
-     Prefilter* prefilter = v[i];
-     if (prefilter == NULL)
-@@ -223,7 +225,7 @@ void PrefilterTree::AssignUniqueIds(vector<string>* atom_vec) {
-       continue;
- 
-     Entry* entry = &entries_[prefilter->unique_id()];
--    entry->parents = new IntMap(node_map_.size());
-+    entry->parents = new StdIntMap();
-   }
- 
-   // Fill the entries.
-@@ -249,7 +251,7 @@ void PrefilterTree::AssignUniqueIds(vector<string>* atom_vec) {
- 
-       case Prefilter::OR:
-       case Prefilter::AND: {
--        IntMap uniq_child(node_map_.size());
-+        std::set<int> uniq_child;
-         for (int j = 0; j < prefilter->subs()->size() ; j++) {
-           Prefilter* child = (*prefilter->subs())[j];
-           Prefilter* canonical = CanonicalNode(child);
-@@ -258,12 +260,12 @@ void PrefilterTree::AssignUniqueIds(vector<string>* atom_vec) {
-             return;
-           }
-           int child_id = canonical->unique_id();
--          if (!uniq_child.has_index(child_id))
--            uniq_child.set_new(child_id, 1);
-+          uniq_child.insert(child_id);
-           // To the child, we want to add to parent indices.
-           Entry* child_entry = &entries_[child_id];
--          if (!child_entry->parents->has_index(prefilter->unique_id()))
--            child_entry->parents->set_new(prefilter->unique_id(), 1);
-+          if (child_entry->parents->find(prefilter->unique_id()) ==
-+              child_entry->parents->end())
-+            (*child_entry->parents)[prefilter->unique_id()] = 1;
-         }
-         entry->propagate_up_at_count =
-             prefilter->op() == Prefilter::AND ? uniq_child.size() : 1;
-@@ -329,10 +331,10 @@ void PrefilterTree::PropagateMatch(const vector<int>& atom_ids,
-     }
-     int c;
-     // Pass trigger up to parents.
--    for (IntMap::iterator it = entry.parents->begin();
-+    for (StdIntMap::iterator it = entry.parents->begin();
-          it != entry.parents->end();
-          ++it) {
--      int j = it->index();
-+      int j = it->first;
-       const Entry& parent = entries_[j];
-       VLOG(10) << " parent= " << j << " trig= " << parent.propagate_up_at_count;
-       // Delay until all the children have succeeded.
-@@ -364,12 +366,12 @@ void PrefilterTree::PrintDebugInfo() {
-   VLOG(10) << "#Unique Nodes: " << entries_.size();
- 
-   for (int i = 0; i < entries_.size(); ++i) {
--    IntMap* parents = entries_[i].parents;
-+    StdIntMap* parents = entries_[i].parents;
-     const vector<int>& regexps = entries_[i].regexps;
-     VLOG(10) << "EntryId: " << i
-             << " N: " << parents->size() << " R: " << regexps.size();
--    for (IntMap::iterator it = parents->begin(); it != parents->end(); ++it)
--      VLOG(10) << it->index();
-+    for (StdIntMap::iterator it = parents->begin(); it != parents->end(); ++it)
-+      VLOG(10) << it->first;
-   }
-   VLOG(10) << "Map:";
-   for (map<string, Prefilter*>::const_iterator iter = node_map_.begin();
-diff --git a/re2/prefilter_tree.h b/re2/prefilter_tree.h
---- a/re2/prefilter_tree.h
-+++ b/re2/prefilter_tree.h
-@@ -16,12 +16,15 @@
- #ifndef RE2_PREFILTER_TREE_H_
- #define RE2_PREFILTER_TREE_H_
- 
-+#include <map>
-+
- #include "util/util.h"
- #include "util/sparse_array.h"
- 
- namespace re2 {
- 
- typedef SparseArray<int> IntMap;
-+typedef std::map<int, int> StdIntMap;
- 
- class Prefilter;
- 
-@@ -71,7 +74,7 @@ class PrefilterTree {
-     // are two different nodes, but they share the atom 'def'. So when
-     // 'def' matches, it triggers two parents, corresponding to the two
-     // different OR nodes.
--    IntMap* parents;
-+    StdIntMap* parents;
- 
-     // When this node is ready to trigger the parent, what are the
-     // regexps that are triggered.
diff --git a/third_party/re2/patches/remove-static-initializers.patch b/third_party/re2/patches/remove-static-initializers.patch
deleted file mode 100644
index c9ef9e3..0000000
--- a/third_party/re2/patches/remove-static-initializers.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-diff --git a/re2/compile.cc b/re2/compile.cc
-index adb45fd..14e401a 100644
---- a/re2/compile.cc
-+++ b/re2/compile.cc
-@@ -44,7 +44,7 @@ struct PatchList {
-   static PatchList Append(Prog::Inst *inst0, PatchList l1, PatchList l2);
- };
- 
--static PatchList nullPatchList;
-+static PatchList nullPatchList = { 0 };
- 
- // Returns patch list containing just p.
- PatchList PatchList::Mk(uint32 p) {
-@@ -106,12 +106,13 @@ struct Frag {
-   uint32 begin;
-   PatchList end;
- 
--  explicit Frag(LinkerInitialized) {}
-   Frag() : begin(0) { end.p = 0; }  // needed so Frag can go in vector
-   Frag(uint32 begin, PatchList end) : begin(begin), end(end) {}
- };
- 
--static Frag kNullFrag(LINKER_INITIALIZED);
-+static Frag NullFrag() {
-+  return Frag();
-+}
- 
- // Input encodings.
- enum Encoding {
-@@ -684,13 +685,13 @@ Frag Compiler::PreVisit(Regexp* re, Frag, bool* stop) {
-   if (failed_)
-     *stop = true;
- 
--  return kNullFrag;  // not used by caller
-+  return NullFrag();  // not used by caller
- }
- 
- Frag Compiler::Literal(Rune r, bool foldcase) {
-   switch (encoding_) {
-     default:
--      return kNullFrag;
-+      return NullFrag();
- 
-     case kEncodingLatin1:
-       return ByteRange(r, r, foldcase);
-@@ -1006,7 +1007,7 @@ Prog* Compiler::Compile(Regexp* re, bool reversed, int64 max_mem) {
-   bool is_anchor_end = IsAnchorEnd(&sre, 0);
- 
-   // Generate fragment for entire regexp.
--  Frag f = c.WalkExponential(sre, kNullFrag, 2*c.max_inst_);
-+  Frag f = c.WalkExponential(sre, NullFrag(), 2*c.max_inst_);
-   sre->Decref();
-   if (c.failed_)
-     return NULL;
-@@ -1097,7 +1098,7 @@ Prog* Compiler::CompileSet(const RE2::Options& options, RE2::Anchor anchor,
-   c.Setup(pf, options.max_mem(), anchor);
- 
-   // Compile alternation of fragments.
--  Frag all = c.WalkExponential(re, kNullFrag, 2*c.max_inst_);
-+  Frag all = c.WalkExponential(re, NullFrag(), 2*c.max_inst_);
-   re->Decref();
-   if (c.failed_)
-     return NULL;
-diff --git a/re2/re2.cc b/re2/re2.cc
-index 0da886d..b9e44fc 100644
---- a/re2/re2.cc
-+++ b/re2/re2.cc
-@@ -32,10 +32,10 @@ namespace re2 {
- static const int kMaxArgs = 16;
- static const int kVecSize = 1+kMaxArgs;
- 
--const VariadicFunction2<bool, const StringPiece&, const RE2&, RE2::Arg, RE2::FullMatchN> RE2::FullMatch;
--const VariadicFunction2<bool, const StringPiece&, const RE2&, RE2::Arg, RE2::PartialMatchN> RE2::PartialMatch;
--const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::ConsumeN> RE2::Consume;
--const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::FindAndConsumeN> RE2::FindAndConsume;
-+const VariadicFunction2<bool, const StringPiece&, const RE2&, RE2::Arg, RE2::FullMatchN> RE2::FullMatch = {};
-+const VariadicFunction2<bool, const StringPiece&, const RE2&, RE2::Arg, RE2::PartialMatchN> RE2::PartialMatch = {};
-+const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::ConsumeN> RE2::Consume = {};
-+const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::FindAndConsumeN> RE2::FindAndConsume = {};
- 
- #define kDefaultMaxMem (8<<20)
- 
-diff --git a/re2/variadic_function.h b/re2/variadic_function.h
-index 8d2b763..7c7d6d5 100644
---- a/re2/variadic_function.h
-+++ b/re2/variadic_function.h
-@@ -11,8 +11,6 @@ template <typename Result, typename Param0, typename Param1, typename Arg,
-           Result (*Func)(Param0, Param1, const Arg* const [], int count)>
- class VariadicFunction2 {
-  public:
--  VariadicFunction2() {}
--
-   Result operator()(Param0 p0, Param1 p1) const {
-     return Func(p0, p1, 0, 0);
-   }
diff --git a/third_party/re2/patches/rename-posix-option.patch b/third_party/re2/patches/rename-posix-option.patch
deleted file mode 100644
index 47caa63..0000000
--- a/third_party/re2/patches/rename-posix-option.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/re2/re2.cc b/re2/re2.cc
-index b9e44fc..fb43abf 100644
---- a/re2/re2.cc
-+++ b/re2/re2.cc
-@@ -56,8 +56,8 @@ RE2::Options::Options()
- 
- RE2::Options::Options(RE2::CannedOptions opt)
-   : encoding_(opt == RE2::Latin1 ? EncodingLatin1 : EncodingUTF8),
--    posix_syntax_(opt == RE2::POSIX),
--    longest_match_(opt == RE2::POSIX),
-+    posix_syntax_(opt == RE2::POSIX_SYNTAX),
-+    longest_match_(opt == RE2::POSIX_SYNTAX),
-     log_errors_(opt != RE2::Quiet),
-     max_mem_(kDefaultMaxMem),
-     literal_(false),
-diff --git a/re2/re2.h b/re2/re2.h
-index c509853..98b06b8 100644
---- a/re2/re2.h
-+++ b/re2/re2.h
-@@ -251,7 +251,7 @@ class RE2 {
-   enum CannedOptions {
-     DefaultOptions = 0,
-     Latin1, // treat input as Latin-1 (default UTF-8)
--    POSIX, // POSIX syntax, leftmost-longest match
-+    POSIX_SYNTAX, // POSIX syntax, leftmost-longest match
-     Quiet // do not log about regexp parse errors
-   };
- 
diff --git a/third_party/re2/re2/compile.cc b/third_party/re2/re2/compile.cc
index 14e401a..9a59f13 100644
--- a/third_party/re2/re2/compile.cc
+++ b/third_party/re2/re2/compile.cc
@@ -110,10 +110,6 @@
   Frag(uint32 begin, PatchList end) : begin(begin), end(end) {}
 };
 
-static Frag NullFrag() {
-  return Frag();
-}
-
 // Input encodings.
 enum Encoding {
   kEncodingUTF8 = 1,  // UTF-8 (0-10FFFF)
@@ -685,13 +681,13 @@
   if (failed_)
     *stop = true;
 
-  return NullFrag();  // not used by caller
+  return Frag();  // not used by caller
 }
 
 Frag Compiler::Literal(Rune r, bool foldcase) {
   switch (encoding_) {
     default:
-      return NullFrag();
+      return Frag();
 
     case kEncodingLatin1:
       return ByteRange(r, r, foldcase);
@@ -1007,7 +1003,7 @@
   bool is_anchor_end = IsAnchorEnd(&sre, 0);
 
   // Generate fragment for entire regexp.
-  Frag f = c.WalkExponential(sre, NullFrag(), 2*c.max_inst_);
+  Frag f = c.WalkExponential(sre, Frag(), 2*c.max_inst_);
   sre->Decref();
   if (c.failed_)
     return NULL;
@@ -1098,7 +1094,7 @@
   c.Setup(pf, options.max_mem(), anchor);
 
   // Compile alternation of fragments.
-  Frag all = c.WalkExponential(re, NullFrag(), 2*c.max_inst_);
+  Frag all = c.WalkExponential(re, Frag(), 2*c.max_inst_);
   re->Decref();
   if (c.failed_)
     return NULL;
diff --git a/third_party/re2/re2/re2.cc b/third_party/re2/re2/re2.cc
index fb43abf..b9e44fc 100644
--- a/third_party/re2/re2/re2.cc
+++ b/third_party/re2/re2/re2.cc
@@ -56,8 +56,8 @@
 
 RE2::Options::Options(RE2::CannedOptions opt)
   : encoding_(opt == RE2::Latin1 ? EncodingLatin1 : EncodingUTF8),
-    posix_syntax_(opt == RE2::POSIX_SYNTAX),
-    longest_match_(opt == RE2::POSIX_SYNTAX),
+    posix_syntax_(opt == RE2::POSIX),
+    longest_match_(opt == RE2::POSIX),
     log_errors_(opt != RE2::Quiet),
     max_mem_(kDefaultMaxMem),
     literal_(false),
diff --git a/third_party/re2/re2/re2.h b/third_party/re2/re2/re2.h
index 98b06b86..c509853 100644
--- a/third_party/re2/re2/re2.h
+++ b/third_party/re2/re2/re2.h
@@ -251,7 +251,7 @@
   enum CannedOptions {
     DefaultOptions = 0,
     Latin1, // treat input as Latin-1 (default UTF-8)
-    POSIX_SYNTAX, // POSIX syntax, leftmost-longest match
+    POSIX, // POSIX syntax, leftmost-longest match
     Quiet // do not log about regexp parse errors
   };
 
diff --git a/third_party/re2/util/util.h b/third_party/re2/util/util.h
index 8350445..21439e97 100644
--- a/third_party/re2/util/util.h
+++ b/third_party/re2/util/util.h
@@ -46,8 +46,7 @@
 using std::swap;
 using std::make_pair;
 
-#if defined(__GNUC__) && !defined(USE_CXX0X) && !defined(OS_ANDROID) && \
-    !defined(_LIBCPP_ABI_VERSION)
+#if defined(__GNUC__) && !defined(USE_CXX0X) && !defined(_LIBCPP_ABI_VERSION) && !defined(OS_ANDROID)
 
 #include <tr1/unordered_set>
 using std::tr1::unordered_set;
diff --git a/build/secondary/third_party/sfntly/BUILD.gn b/third_party/sfntly/BUILD.gn
similarity index 100%
rename from build/secondary/third_party/sfntly/BUILD.gn
rename to third_party/sfntly/BUILD.gn
diff --git a/third_party/usrsctp/usrsctp_nacl.gyp b/third_party/usrsctp/usrsctp_nacl.gyp
index bf5c84f9..7cce5e7 100644
--- a/third_party/usrsctp/usrsctp_nacl.gyp
+++ b/third_party/usrsctp/usrsctp_nacl.gyp
@@ -16,7 +16,6 @@
         'build_pnacl_newlib': 1,
       },
       'dependencies': [
-        '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
         '<(DEPTH)/native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
         '<(DEPTH)/third_party/boringssl/boringssl_nacl.gyp:boringssl_nacl',
       ],
diff --git a/third_party/win_toolchain/LICENSE b/third_party/win_toolchain/LICENSE
deleted file mode 100644
index 3d0f7d3e..0000000
--- a/third_party/win_toolchain/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/win_toolchain/README.chromium b/third_party/win_toolchain/README.chromium
deleted file mode 100644
index e32ec766..0000000
--- a/third_party/win_toolchain/README.chromium
+++ /dev/null
@@ -1,6 +0,0 @@
-Name: SHA1 for Windows toolchain that is built from external sources.

-Short Name: win_toolchain

-URL: http://msdn.microsoft.com/

-License: BSD 3-Clause License

-License File: LICENSE

-Security Critical: yes

diff --git a/third_party/win_toolchain/toolchain.sha1 b/third_party/win_toolchain/toolchain.sha1
deleted file mode 100644
index 31489690..0000000
--- a/third_party/win_toolchain/toolchain.sha1
+++ /dev/null
@@ -1 +0,0 @@
-1b78fa680523f420bbfb75371ea76959eabafffa

diff --git a/tools/clang/blink_gc_plugin/Edge.h b/tools/clang/blink_gc_plugin/Edge.h
index 7659968..2ea8e54 100644
--- a/tools/clang/blink_gc_plugin/Edge.h
+++ b/tools/clang/blink_gc_plugin/Edge.h
@@ -39,14 +39,14 @@
 class RecursiveEdgeVisitor : public EdgeVisitor {
  public:
   // Overrides that recursively walk the edges and record the path.
-  virtual void VisitValue(Value*) override;
-  virtual void VisitRawPtr(RawPtr*) override;
-  virtual void VisitRefPtr(RefPtr*) override;
-  virtual void VisitOwnPtr(OwnPtr*) override;
-  virtual void VisitMember(Member*) override;
-  virtual void VisitWeakMember(WeakMember*) override;
-  virtual void VisitPersistent(Persistent*) override;
-  virtual void VisitCollection(Collection*) override;
+  void VisitValue(Value*) override;
+  void VisitRawPtr(RawPtr*) override;
+  void VisitRefPtr(RefPtr*) override;
+  void VisitOwnPtr(OwnPtr*) override;
+  void VisitMember(Member*) override;
+  void VisitWeakMember(WeakMember*) override;
+  void VisitPersistent(Persistent*) override;
+  void VisitCollection(Collection*) override;
 
  protected:
   typedef std::deque<Edge*> Context;
diff --git a/tools/clang/blink_gc_plugin/JsonWriter.h b/tools/clang/blink_gc_plugin/JsonWriter.h
index 3fe7910..09504b3 100644
--- a/tools/clang/blink_gc_plugin/JsonWriter.h
+++ b/tools/clang/blink_gc_plugin/JsonWriter.h
@@ -7,12 +7,24 @@
 
 #include "llvm/Support/raw_ostream.h"
 
+// TODO(hans): Remove this #ifdef after Clang is rolled past r234897.
+#ifdef LLVM_FORCE_HEAD_REVISION
+#define JSON_WRITER_STREAM std::unique_ptr<llvm::raw_ostream>
+#else
+#define JSON_WRITER_STREAM llvm::raw_fd_ostream*
+#endif
+
 // Helper to write information for the points-to graph.
 class JsonWriter {
  public:
-  static JsonWriter* from(std::unique_ptr<llvm::raw_ostream> os) {
+  static JsonWriter* from(JSON_WRITER_STREAM os) {
     return os ? new JsonWriter(std::move(os)) : 0;
   }
+#ifndef LLVM_FORCE_HEAD_REVISION
+  ~JsonWriter() {
+    delete os_;
+  }
+#endif
   void OpenList() {
     Separator();
     *os_ << "[";
@@ -53,7 +65,7 @@
     *os_ << "\"" << key << "\":\"" << val << "\"";
   }
  private:
-  JsonWriter(std::unique_ptr<llvm::raw_ostream> os) : os_(std::move(os)) {}
+  JsonWriter(JSON_WRITER_STREAM os) : os_(std::move(os)) {}
   void Separator() {
     if (state_.empty())
       return;
@@ -63,7 +75,7 @@
     }
     state_.top() = true;
   }
-  std::unique_ptr<llvm::raw_ostream> os_;
+  JSON_WRITER_STREAM os_;
   std::stack<bool> state_;
 };
 
diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp
index b9d49c3..931da02 100644
--- a/tools/clang/plugins/ChromeClassTester.cpp
+++ b/tools/clang/plugins/ChromeClassTester.cpp
@@ -107,6 +107,55 @@
   DiagnosticBuilder builder = diagnostic().Report(full, id);
 }
 
+bool ChromeClassTester::InBannedDirectory(SourceLocation loc) {
+  if (instance().getSourceManager().isInSystemHeader(loc))
+    return true;
+
+  std::string filename;
+  if (!GetFilename(loc, &filename)) {
+    // If the filename cannot be determined, simply treat this as a banned
+    // location, instead of going through the full lookup process.
+    return true;
+  }
+
+  // We need to special case scratch space; which is where clang does its
+  // macro expansion. We explicitly want to allow people to do otherwise bad
+  // things through macros that were defined due to third party libraries.
+  if (filename == "<scratch space>")
+    return true;
+
+  // Don't complain about autogenerated protobuf files.
+  if (ends_with(filename, ".pb.h")) {
+    return true;
+  }
+
+#if defined(LLVM_ON_UNIX)
+  // We need to munge the paths so that they are relative to the repository
+  // srcroot. We first resolve the symlinktastic relative path and then
+  // remove our known srcroot from it if needed.
+  char resolvedPath[MAXPATHLEN];
+  if (realpath(filename.c_str(), resolvedPath)) {
+    filename = resolvedPath;
+  }
+#endif
+
+#if defined(LLVM_ON_WIN32)
+  std::replace(filename.begin(), filename.end(), '\\', '/');
+#endif
+
+  for (const std::string& banned_dir : banned_directories_) {
+    // If any of the banned directories occur as a component in filename,
+    // this file is rejected.
+    assert(banned_dir.front() == '/' && "Banned dir must start with '/'");
+    assert(banned_dir.back() == '/' && "Banned dir must end with '/'");
+
+    if (filename.find(banned_dir) != std::string::npos)
+      return true;
+  }
+
+  return false;
+}
+
 bool ChromeClassTester::InBannedNamespace(const Decl* record) {
   std::string n = GetNamespace(record);
   if (!n.empty()) {
@@ -237,55 +286,6 @@
   }
 }
 
-bool ChromeClassTester::InBannedDirectory(SourceLocation loc) {
-  if (instance().getSourceManager().isInSystemHeader(loc))
-    return true;
-
-  std::string filename;
-  if (!GetFilename(loc, &filename)) {
-    // If the filename cannot be determined, simply treat this as a banned
-    // location, instead of going through the full lookup process.
-    return true;
-  }
-
-  // We need to special case scratch space; which is where clang does its
-  // macro expansion. We explicitly want to allow people to do otherwise bad
-  // things through macros that were defined due to third party libraries.
-  if (filename == "<scratch space>")
-    return true;
-
-  // Don't complain about autogenerated protobuf files.
-  if (ends_with(filename, ".pb.h")) {
-    return true;
-  }
-
-#if defined(LLVM_ON_UNIX)
-  // We need to munge the paths so that they are relative to the repository
-  // srcroot. We first resolve the symlinktastic relative path and then
-  // remove our known srcroot from it if needed.
-  char resolvedPath[MAXPATHLEN];
-  if (realpath(filename.c_str(), resolvedPath)) {
-    filename = resolvedPath;
-  }
-#endif
-
-#if defined(LLVM_ON_WIN32)
-  std::replace(filename.begin(), filename.end(), '\\', '/');
-#endif
-
-  for (const std::string& banned_dir : banned_directories_) {
-    // If any of the banned directories occur as a component in filename,
-    // this file is rejected.
-    assert(banned_dir.front() == '/' && "Banned dir must start with '/'");
-    assert(banned_dir.back() == '/' && "Banned dir must end with '/'");
-
-    if (filename.find(banned_dir) != std::string::npos)
-      return true;
-  }
-
-  return false;
-}
-
 bool ChromeClassTester::IsIgnoredType(const std::string& base_name) {
   return ignored_record_names_.find(base_name) != ignored_record_names_.end();
 }
diff --git a/tools/clang/plugins/ChromeClassTester.h b/tools/clang/plugins/ChromeClassTester.h
index 963b90f..ed65050 100644
--- a/tools/clang/plugins/ChromeClassTester.h
+++ b/tools/clang/plugins/ChromeClassTester.h
@@ -37,6 +37,10 @@
   // namespace.
   bool InBannedNamespace(const clang::Decl* record);
 
+  // Utility method for subclasses to check if the source location is in a
+  // directory the plugin should ignore.
+  bool InBannedDirectory(clang::SourceLocation loc);
+
   // Utility method for subclasses to determine the namespace of the
   // specified record, if any. Unnamed namespaces will be identified as
   // "<anonymous namespace>".
@@ -64,7 +68,6 @@
   // deliberately ignore) in HandleTagDeclDefinition().
   std::string GetNamespaceImpl(const clang::DeclContext* context,
                                const std::string& candidate);
-  bool InBannedDirectory(clang::SourceLocation loc);
   bool IsIgnoredType(const std::string& base_name);
 
   // Attempts to determine the filename for the given SourceLocation.
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index 2524550e..20919a4 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -70,14 +70,15 @@
   return decl->getQualifiedNameAsString() == "testing::Test";
 }
 
+// Generates a fixit hint to remove the 'virtual' keyword.
+// Unfortunately, there doesn't seem to be a good way to determine the source
+// location of the 'virtual' keyword. It's available in Declarator, but that
+// isn't accessible from the AST. So instead, make an educated guess that the
+// first token is probably the virtual keyword. Strictly speaking, this doesn't
+// have to be true, but it probably will be.
+// TODO(dcheng): Add a warning to force virtual to always appear first ;-)
 FixItHint FixItRemovalForVirtual(const SourceManager& manager,
                                  const CXXMethodDecl* method) {
-  // Unfortunately, there doesn't seem to be a good way to determine the
-  // location of the 'virtual' keyword. It's available in Declarator, but that
-  // isn't accessible from the AST. So instead, make an educated guess that the
-  // first token is probably the virtual keyword. Strictly speaking, this
-  // doesn't have to be true, but it probably will be.
-  // TODO(dcheng): Add a warning to force virtual to always appear first ;-)
   SourceRange range(method->getLocStart());
   // Get the spelling loc just in case it was expanded from a macro.
   SourceRange spelling_range(manager.getSpellingLoc(range.getBegin()));
@@ -413,32 +414,68 @@
 
   // Complain if a method is annotated virtual && (override || final).
   if (has_virtual && (override_attr || final_attr)) {
-    diagnostic().Report(method->getLocStart(),
-                        diag_redundant_virtual_specifier_)
-        << "'virtual'"
-        << (override_attr ? static_cast<Attr*>(override_attr) : final_attr)
-        << FixItRemovalForVirtual(manager, method);
+    // ... but only if virtual does not originate in a macro from a banned file.
+    // Note this is just an educated guess: the assumption here is that any
+    // macro for declaring methods will probably be at the start of the method's
+    // source range.
+    if (!InBannedDirectory(manager.getSpellingLoc(method->getLocStart()))) {
+      diagnostic().Report(method->getLocStart(),
+                          diag_redundant_virtual_specifier_)
+          << "'virtual'"
+          << (override_attr ? static_cast<Attr*>(override_attr) : final_attr)
+          << FixItRemovalForVirtual(manager, method);
+    }
   }
 
   // Complain if a method is an override and is not annotated with override or
   // final.
   if (is_override && !override_attr && !final_attr) {
-    SourceRange type_info_range =
-        method->getTypeSourceInfo()->getTypeLoc().getSourceRange();
-    FullSourceLoc loc(type_info_range.getBegin(), manager);
-
-    // Build the FixIt insertion point after the end of the method definition,
-    // including any const-qualifiers and attributes, and before the opening
-    // of the l-curly-brace (if inline) or the semi-color (if a declaration).
-    SourceLocation spelling_end =
-        manager.getSpellingLoc(type_info_range.getEnd());
-    if (spelling_end.isValid()) {
-      SourceLocation token_end =
-          Lexer::getLocForEndOfToken(spelling_end, 0, manager, LangOptions());
-      diagnostic().Report(token_end, diag_method_requires_override_)
-          << FixItHint::CreateInsertion(token_end, " override");
+    SourceRange range = method->getSourceRange();
+    SourceLocation loc;
+    if (method->hasInlineBody()) {
+      loc = method->getBody()->getSourceRange().getBegin();
     } else {
-      diagnostic().Report(loc, diag_method_requires_override_);
+      // TODO(dcheng): We should probably use ASTContext's LangOptions here.
+      LangOptions lang_options;
+      loc = Lexer::getLocForEndOfToken(
+          manager.getSpellingLoc(range.getEnd()), 0,
+          manager, lang_options);
+      // The original code used the ending source loc of TypeSourceInfo's
+      // TypeLoc. Unfortunately, this breaks down in the presence of attributes.
+      // Attributes often appear at the end of a TypeLoc, e.g.
+      //   virtual ULONG __stdcall AddRef()
+      // has a TypeSourceInfo that looks something like:
+      //   ULONG AddRef() __attribute(stdcall)
+      // so a fix-it insertion would be generated to insert 'override' after
+      // __stdcall in the code as written.
+      // While using the spelling loc of the CXXMethodDecl fixes attribute
+      // handling, it breaks handling of "= 0" and similar constructs.. To work
+      // around this, scan backwards in the source text for a '=' or ')' token
+      // and adjust the location as needed...
+      for (SourceLocation l = loc.getLocWithOffset(-1);
+           l != manager.getLocForStartOfFile(manager.getFileID(loc));
+           l = l.getLocWithOffset(-1)) {
+        l = Lexer::GetBeginningOfToken(l, manager, lang_options);
+        Token token;
+        // getRawToken() returns *true* on failure. In that case, just give up
+        // and don't bother generating a possibly incorrect fix-it.
+        if (Lexer::getRawToken(l, token, manager, lang_options, true)) {
+          loc = SourceLocation();
+          break;
+        }
+        if (token.is(tok::r_paren)) {
+          break;
+        } else if (token.is(tok::equal)) {
+          loc = l;
+          break;
+        }
+      }
+    }
+    if (loc.isValid()) {
+      diagnostic().Report(loc, diag_method_requires_override_)
+          << FixItHint::CreateInsertion(loc, " override");
+    } else {
+      diagnostic().Report(range.getBegin(), diag_method_requires_override_);
     }
   }
 
diff --git a/tools/clang/plugins/tests/overridden_methods.txt b/tools/clang/plugins/tests/overridden_methods.txt
index 69ff2b1..bc2d1aca 100644
--- a/tools/clang/plugins/tests/overridden_methods.txt
+++ b/tools/clang/plugins/tests/overridden_methods.txt
@@ -1,82 +1,82 @@
 In file included from overridden_methods.cpp:5:
-./overridden_methods.h:25:28: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+./overridden_methods.h:25:29: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethod() = 0;
-                           ^
-                            override
-./overridden_methods.h:46:26: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                            ^
+                             override
+./overridden_methods.h:46:27: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual ~DerivedClass() {}
-                         ^
-                          override
+                          ^
+                           override
 ./overridden_methods.h:48:28: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethod();
                            ^
                             override
-./overridden_methods.h:52:34: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+./overridden_methods.h:52:35: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeInlineMethod() {}
-                                 ^
-                                  override
-./overridden_methods.h:56:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                  ^
+                                   override
+./overridden_methods.h:56:40: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeConstMethod() const {}
-                                      ^
-                                       override
-./overridden_methods.h:58:55: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                       ^
+                                        override
+./overridden_methods.h:58:54: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethodWithExceptionSpec() throw() {}
-                                                      ^
-                                                       override
-./overridden_methods.h:61:69: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                                     ^
+                                                      override
+./overridden_methods.h:61:68: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeConstMethodWithExceptionSpec() const throw(int) {}
-                                                                    ^
-                                                                     override
-./overridden_methods.h:63:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                                                   ^
+                                                                    override
+./overridden_methods.h:63:40: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeNonPureBaseMethod() {}
-                                      ^
-                                       override
+                                       ^
+                                        override
 ./overridden_methods.h:65:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethodWithComment();  // This is a comment.
                                       ^
                                        override
-./overridden_methods.h:67:46: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+./overridden_methods.h:67:47: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethodWithCommentAndBody() {}  // This is a comment.
-                                             ^
-                                              override
-overridden_methods.cpp:15:28: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                              ^
+                                               override
+overridden_methods.cpp:15:29: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethod() = 0;
-                           ^
-                            override
-overridden_methods.cpp:22:40: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                            ^
+                             override
+overridden_methods.cpp:22:41: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual ~ImplementationDerivedClass() {}
-                                       ^
-                                        override
+                                        ^
+                                         override
 overridden_methods.cpp:24:28: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethod();
                            ^
                             override
-overridden_methods.cpp:28:34: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+overridden_methods.cpp:28:35: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeInlineMethod() {}
-                                 ^
-                                  override
-overridden_methods.cpp:32:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                  ^
+                                   override
+overridden_methods.cpp:32:40: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeConstMethod() const {}
-                                      ^
-                                       override
-overridden_methods.cpp:34:55: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                       ^
+                                        override
+overridden_methods.cpp:34:54: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethodWithExceptionSpec() throw() {}
-                                                      ^
-                                                       override
-overridden_methods.cpp:37:69: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                                     ^
+                                                      override
+overridden_methods.cpp:37:68: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeConstMethodWithExceptionSpec() const throw(int) {}
-                                                                    ^
-                                                                     override
-overridden_methods.cpp:39:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                                                                   ^
+                                                                    override
+overridden_methods.cpp:39:40: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeNonPureBaseMethod() {}
-                                      ^
-                                       override
+                                       ^
+                                        override
 overridden_methods.cpp:41:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethodWithComment();  // This is a comment.
                                       ^
                                        override
-overridden_methods.cpp:43:46: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+overridden_methods.cpp:43:47: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void SomeMethodWithCommentAndBody() {}  // This is a comment.
-                                             ^
-                                              override
+                                              ^
+                                               override
 20 warnings generated.
diff --git a/tools/clang/plugins/tests/system/windows.h b/tools/clang/plugins/tests/system/windows.h
new file mode 100644
index 0000000..f93d5e2
--- /dev/null
+++ b/tools/clang/plugins/tests/system/windows.h
@@ -0,0 +1,10 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_WINDOWS_H_
+#define TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_WINDOWS_H_
+
+#define STDMETHOD(x) virtual void x
+
+#endif  // TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_WINDOWS_H_
diff --git a/tools/clang/plugins/tests/test.sh b/tools/clang/plugins/tests/test.sh
index ea210544..cf26252 100755
--- a/tools/clang/plugins/tests/test.sh
+++ b/tools/clang/plugins/tests/test.sh
@@ -12,6 +12,8 @@
 
 failed_any_test=
 
+THIS_DIR="$(dirname "${0}")"
+
 # Prints usage information.
 usage() {
   echo "Usage: $(basename "${0}")" \
@@ -38,6 +40,7 @@
 
   local output="$("${CLANG_PATH}" -fsyntax-only -Wno-c++11-extensions \
       -Wno-inconsistent-missing-override \
+      -isystem ${THIS_DIR}/system \
       -Xclang -load -Xclang "${PLUGIN_PATH}" \
       -Xclang -add-plugin -Xclang find-bad-constructs ${flags} ${1} 2>&1)"
   local diffout="$(echo "${output}" | diff - "${2}")"
@@ -81,7 +84,7 @@
 
   # The golden files assume that the cwd is this directory. To make the script
   # work no matter what the cwd is, explicitly cd to there.
-  cd "$(dirname "${0}")"
+  cd "${THIS_DIR}"
 fi
 
 for input in *.cpp; do
diff --git a/tools/clang/plugins/tests/virtual_specifiers.cpp b/tools/clang/plugins/tests/virtual_specifiers.cpp
index 28321e8..2103248 100644
--- a/tools/clang/plugins/tests/virtual_specifiers.cpp
+++ b/tools/clang/plugins/tests/virtual_specifiers.cpp
@@ -5,6 +5,8 @@
 // Tests for chromium style checks for virtual/override/final specifiers on
 // virtual methods.
 
+#include <windows.h>
+
 // Purposely use macros to test that the FixIt hints don't try to remove the
 // macro body.
 #define OVERRIDE override
@@ -79,7 +81,13 @@
   virtual void F() override = 0;
 };
 
-// Finally, some simple sanity tests that overrides in the testing namespace
+// Test that the redundant virtual warning is suppressed when the virtual
+// keyword comes from a macro in a system header.
+class COMIsAwesome : public Base {
+  STDMETHOD(F)() override = 0;
+};
+
+// Some tests that overrides in the testing namespace
 // don't trigger warnings, except for testing::Test.
 namespace testing {
 
diff --git a/tools/clang/plugins/tests/virtual_specifiers.txt b/tools/clang/plugins/tests/virtual_specifiers.txt
index a51236c..135ebdd3 100644
--- a/tools/clang/plugins/tests/virtual_specifiers.txt
+++ b/tools/clang/plugins/tests/virtual_specifiers.txt
@@ -1,69 +1,69 @@
-virtual_specifiers.cpp:36:21: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+virtual_specifiers.cpp:38:22: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   ~MissingOverride() {}
-                    ^
-                     override
-virtual_specifiers.cpp:37:11: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                     ^
+                      override
+virtual_specifiers.cpp:39:12: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   void F() {}
-          ^
-           override
-virtual_specifiers.cpp:43:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+           ^
+            override
+virtual_specifiers.cpp:45:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
   virtual ~VirtualAndOverride() OVERRIDE {}
   ^~~~~~~~
-virtual_specifiers.cpp:44:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+virtual_specifiers.cpp:46:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
   virtual void F() OVERRIDE {}
   ^~~~~~~~
-virtual_specifiers.cpp:49:3: warning: [chromium-style] 'virtual' is redundant; 'final' implies 'virtual'.
+virtual_specifiers.cpp:51:3: warning: [chromium-style] 'virtual' is redundant; 'final' implies 'virtual'.
   virtual ~VirtualAndFinal() FINAL {}
   ^~~~~~~~
-virtual_specifiers.cpp:50:3: warning: [chromium-style] 'virtual' is redundant; 'final' implies 'virtual'.
+virtual_specifiers.cpp:52:3: warning: [chromium-style] 'virtual' is redundant; 'final' implies 'virtual'.
   virtual void F() FINAL {}
   ^~~~~~~~
-virtual_specifiers.cpp:55:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+virtual_specifiers.cpp:57:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
   virtual ~VirtualAndOverrideFinal() OVERRIDE FINAL {}
   ^~~~~~~~
-virtual_specifiers.cpp:55:38: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
+virtual_specifiers.cpp:57:38: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
   virtual ~VirtualAndOverrideFinal() OVERRIDE FINAL {}
                                      ^~~~~~~~~
-virtual_specifiers.cpp:10:18: note: expanded from macro 'OVERRIDE'
+virtual_specifiers.cpp:12:18: note: expanded from macro 'OVERRIDE'
 #define OVERRIDE override
                  ^
-virtual_specifiers.cpp:56:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+virtual_specifiers.cpp:58:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
   virtual void F() OVERRIDE FINAL {}
   ^~~~~~~~
-virtual_specifiers.cpp:56:20: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
+virtual_specifiers.cpp:58:20: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
   virtual void F() OVERRIDE FINAL {}
                    ^~~~~~~~~
-virtual_specifiers.cpp:10:18: note: expanded from macro 'OVERRIDE'
+virtual_specifiers.cpp:12:18: note: expanded from macro 'OVERRIDE'
 #define OVERRIDE override
                  ^
-virtual_specifiers.cpp:61:23: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
+virtual_specifiers.cpp:63:23: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
   ~OverrideAndFinal() OVERRIDE FINAL {}
                       ^~~~~~~~~
-virtual_specifiers.cpp:10:18: note: expanded from macro 'OVERRIDE'
+virtual_specifiers.cpp:12:18: note: expanded from macro 'OVERRIDE'
 #define OVERRIDE override
                  ^
-virtual_specifiers.cpp:62:12: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
+virtual_specifiers.cpp:64:12: warning: [chromium-style] 'override' is redundant; 'final' implies 'override'.
   void F() OVERRIDE FINAL {}
            ^~~~~~~~~
-virtual_specifiers.cpp:10:18: note: expanded from macro 'OVERRIDE'
+virtual_specifiers.cpp:12:18: note: expanded from macro 'OVERRIDE'
 #define OVERRIDE override
                  ^
-virtual_specifiers.cpp:67:19: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+virtual_specifiers.cpp:69:20: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual void F() = 0;
-                  ^
-                   override
-virtual_specifiers.cpp:71:11: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+                   ^
+                    override
+virtual_specifiers.cpp:73:12: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   void F() = 0;
-          ^
-           override
-virtual_specifiers.cpp:79:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+           ^
+            override
+virtual_specifiers.cpp:81:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
   virtual void F() override = 0;
   ^~~~~~~~
-virtual_specifiers.cpp:102:20: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+virtual_specifiers.cpp:110:20: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
   virtual ~MyTest();
                    ^
                     override
-virtual_specifiers.cpp:103:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+virtual_specifiers.cpp:111:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
   virtual void SetUp() override;
   ^~~~~~~~
 17 warnings generated.
diff --git a/tools/clang/scripts/update.sh b/tools/clang/scripts/update.sh
index 1348341c..f0dbeb0 100755
--- a/tools/clang/scripts/update.sh
+++ b/tools/clang/scripts/update.sh
@@ -11,7 +11,7 @@
 CLANG_REVISION=233105
 
 # This is incremented when pushing a new build of Clang at the same revision.
-CLANG_SUB_REVISION=1
+CLANG_SUB_REVISION=2
 
 PACKAGE_VERSION="${CLANG_REVISION}-${CLANG_SUB_REVISION}"
 
@@ -314,6 +314,7 @@
       "${CLANG_DIR}/test/SemaCXX/typo-correction-delayed.cpp" \
       "${COMPILER_RT_DIR}/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc" \
       "${COMPILER_RT_DIR}/test/tsan/signal_segv_handler.cc" \
+      "${COMPILER_RT_DIR}/lib/sanitizer_common/sanitizer_coverage_libcdep.cc" \
       ; do
   if [[ -e "${i}" ]]; then
     rm -f "${i}"  # For unversioned files.
@@ -396,6 +397,27 @@
   patch -p0
   popd
 
+  # Cherry-pick r234010 [sancov] Shrink pc array on Android back to 2**24."
+  pushd "${COMPILER_RT_DIR}"
+  cat << 'EOF' |
+diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
+index 4b976fc..cfd9e7e 100644
+--- a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
++++ b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
+@@ -109,7 +109,8 @@ class CoverageData {
+ 
+   // Maximal size pc array may ever grow.
+   // We MmapNoReserve this space to ensure that the array is contiguous.
+-  static const uptr kPcArrayMaxSize = FIRST_32_SECOND_64(1 << 26, 1 << 27);
++  static const uptr kPcArrayMaxSize =
++      FIRST_32_SECOND_64(1 << (SANITIZER_ANDROID ? 24 : 26), 1 << 27);
+   // The amount file mapping for the pc array is grown by.
+   static const uptr kPcArrayMmapSize = 64 * 1024;
+
+EOF
+  patch -p1
+  popd
+
   # This Go bindings test doesn't work after the bootstrap build on Linux. (PR21552)
   pushd "${LLVM_DIR}"
   cat << 'EOF' |
@@ -543,6 +565,14 @@
   BINUTILS_INCDIR="${ABS_BINUTILS_DIR}/Linux_x64/Release/include"
 fi
 
+
+# If building at head, define a macro that plugins can use for #ifdefing
+# out code that builds at head, but not at CLANG_REVISION or vice versa.
+if [[ -n ${LLVM_FORCE_HEAD_REVISION:-''} ]]; then
+  CFLAGS="${CFLAGS} -DLLVM_FORCE_HEAD_REVISION"
+  CXXFLAGS="${CXXFLAGS} -DLLVM_FORCE_HEAD_REVISION"
+fi
+
 # Hook the Chromium tools into the LLVM build. Several Chromium tools have
 # dependencies on LLVM/Clang libraries. The LLVM build detects implicit tools
 # in the tools subdirectory, so install a shim CMakeLists.txt that forwards to
diff --git a/tools/gn/command_help.cc b/tools/gn/command_help.cc
index fda82696..7679b17 100644
--- a/tools/gn/command_help.cc
+++ b/tools/gn/command_help.cc
@@ -92,7 +92,11 @@
   const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
   if (cmdline->HasSwitch(switches::kMarkdown)) {
     OutputString("# GN Reference\n\n");
-    OutputString("[TOC]\n\n");
+
+    // TODO: https://code.google.com/p/gitiles/issues/detail?id=75
+    // Gitiles crashes when rendering the table of contents, so we must omit
+    // it until the bug is fixed.
+    // OutputString("[TOC]\n\n");
     OutputString("*This page is automatically generated from* "
                  "`gn help --markdown all`.\n\n");
   } else {
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index 39550a2..a405a34 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -1,7 +1,5 @@
 # GN Reference
 
-[TOC]
-
 *This page is automatically generated from* `gn help --markdown all`.
 
 ## **--args**: Specifies build arguments overrides.
@@ -565,7 +563,7 @@
 
 
 ```
-## **gn refs <out_dir> (<label_pattern>|<label>|<file>)* [--all]**
+## **gn refs <out_dir> (<label_pattern>|<label>|<file>|@<response_file>)* [--all]**
 ```
         [--all-toolchains] [--as=...] [--testonly=...] [--type=...]
 
@@ -587,6 +585,11 @@
      that does not contain wildcards and does not match a target or a
      config will be treated as a file.
 
+   - Response file: If the input starts with an "@", it will be
+     interpreted as a path to a file containing a list of labels or
+     file names, one per line. This allows us to handle long lists
+     of inputs without worrying about command line limits.
+
 ```
 
 ### **Options**
diff --git a/tools/gn/misc/GN.tmLanguage b/tools/gn/misc/GN.tmLanguage
new file mode 100644
index 0000000..8a0f8a2
--- /dev/null
+++ b/tools/gn/misc/GN.tmLanguage
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>fileTypes</key>
+  <array>
+    <string>gn</string>
+    <string>gni</string>
+  </array>
+  <key>name</key>
+  <string>GN</string>
+  <key>patterns</key>
+  <array>
+    <dict>
+      <key>comment</key>
+      <string>keywords</string>
+      <key>match</key>
+      <string>\b(?:if)\b</string>
+      <key>name</key>
+      <string>keyword.control.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>constants</string>
+      <key>match</key>
+      <string>\b(?:true|false)\b</string>
+      <key>name</key>
+      <string>constant.language.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>numbers</string>
+      <key>match</key>
+      <string>\b\d+\.?(?:\d+)?\b</string>
+      <key>name</key>
+      <string>constant.numeric.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>double quoted string</string>
+      <key>match</key>
+      <string>\"[^\"]*\"</string>
+      <key>name</key>
+      <string>string.quoted.double.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>comment</string>
+      <key>begin</key>
+      <string>#</string>
+      <key>end</key>
+      <string>$</string>
+      <key>name</key>
+      <string>comment.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>operators</string>
+      <key>match</key>
+      <string>(?:=|==|\+=|-=|\+|-)</string>
+      <key>name</key>
+      <string>keyword.operator.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>targets</string>
+      <key>match</key>
+      <string>\b(?:action|action_foreach|copy|executable|group|shared_library|source_set|static_library)\b</string>
+      <key>name</key>
+      <string>entity.name.tag.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>functions</string>
+      <key>match</key>
+      <string>\b(?:assert|config|declare_args|defined|exec_script|foreach|get_label_info|get_path_info|get_target_outputs|getenv|import|print|process_file_template|read_file|rebase_path|set_default_toolchain|set_defaults|set_sources_assignment_filter|template|tool|toolchain|toolchain_args|write_file)\b</string>
+      <key>name</key>
+      <string>entity.name.function.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>predefined variables</string>
+      <key>match</key>
+      <string>\b(?:current_cpu|current_os|current_toolchain|default_toolchain|host_cpu|host_os|python_path|root_build_dir|root_gen_dir|root_out_dir|target_cpu|target_gen_dir|target_os|target_out_dir)\b</string>
+      <key>name</key>
+      <string>variable.parameter.gn</string>
+    </dict>
+    <dict>
+      <key>comment</key>
+      <string>target variables</string>
+      <key>match</key>
+      <string>\b(?:all_dependent_configs|allow_circular_includes_from|args|cflags|cflags_c|cflags_cc|cflags_objc|cflags_objcc|check_includes|complete_static_lib|configs|data|data_deps|defines|depfile|deps|forward_dependent_configs_from|include_dirs|inputs|ldflags|lib_dirs|libs|output_extension|output_name|outputs|public|public_configs|public_deps|script|sources|testonly|visibility)\b</string>
+      <key>name</key>
+      <string>entity.other.attribute-name.gn</string>
+    </dict>
+  </array>
+  <key>scopeName</key>
+  <string>source.gn</string>
+  <key>uuid</key>
+  <string>DE419F8C-EC46-4824-87F3-732BD08694DC</string>
+</dict>
+</plist>
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 9fab045..7fa3014 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -162,6 +162,10 @@
       'Linux GN': 'gn_release_bot',
       'Linux GN (dbg)': 'gn_debug_bot'
     },
+    'client.v8': {
+      'V8 Linux GN': 'gn_release_bot',
+      'V8 Android GN (dbg)': 'android_gn_debug_bot',
+    },
     'tryserver.blink': {
       'android_chromium_gn_compile_rel': 'android_gn_release_bot',
       'linux_chromium_gn_rel': 'gn_release_bot',
@@ -188,5 +192,9 @@
       'win8_chromium_gn_rel': 'gn_release_trybot_x86',
       'win8_chromium_gn_upload': 'gn_release_bot',
     },
+    'tryserver.v8': {
+      'v8_linux_chromium_gn_rel': 'gn_release_trybot',
+      'v8_android_chromium_gn_dbg': 'android_gn_debug_bot',
+    },
   },
 }
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 5f98d958b..327f44d 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -7091,6 +7091,14 @@
   </description>
 </action>
 
+<action name="Launcher_SwitchTask">
+  <owner>bruthig@google.com</owner>
+  <owner>tdanderson@google.com</owner>
+  <description>
+    Recorded when the user activates an existing task from the shelf.
+  </description>
+</action>
+
 <action name="LoadURL">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -8469,6 +8477,20 @@
   <description>Settings: Accessibility: Enable tap dragging</description>
 </action>
 
+<action name="Options_AddPersonEnabled_Disable">
+  <owner>jwd@chromium.org</owner>
+  <description>
+    Settings: People: Disables allowing anyone to add a person to Chrome.
+  </description>
+</action>
+
+<action name="Options_AddPersonEnabled_Enable">
+  <owner>jwd@chromium.org</owner>
+  <description>
+    Settings: People: Enables anyone to add a person to Chrome.
+  </description>
+</action>
+
 <action name="Options_AllowAllUsers_Disable">
   <owner>stevenjb@chromium.org</owner>
   <description>
@@ -8601,6 +8623,16 @@
   <description>Settings: Bluetooth: Add a device</description>
 </action>
 
+<action name="Options_BrowserGuestEnabled_Disable">
+  <owner>jwd@chromium.org</owner>
+  <description>Settings: People: Disable Guest browsing.</description>
+</action>
+
+<action name="Options_BrowserGuestEnabled_Enable">
+  <owner>jwd@chromium.org</owner>
+  <description>Settings: People: Allows guests to browse.</description>
+</action>
+
 <action name="Options_CaptivePortalBypassProxy_Disable">
   <owner>alemate@chromium.org</owner>
   <description>
@@ -8881,6 +8913,11 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Options_GetMoreExtensions">
+  <owner>jwd@chromium.org</owner>
+  <description>Extensions: Click on 'Get More Extensions' link.</description>
+</action>
+
 <action name="Options_GoogleGeolocationAccessCheckbox_Disable">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -9128,6 +9165,11 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Options_LoadUnpackedExtension">
+  <owner>jwd@chromium.org</owner>
+  <description>Extensions: Loads an unpacked extension.</description>
+</action>
+
 <action name="Options_ManageAccounts">
   <owner>stevenjb@chromium.org</owner>
   <description>Settings: Users: Manage other users</description>
@@ -9710,6 +9752,20 @@
   <description>Settings: Date and time: Timezone</description>
 </action>
 
+<action name="Options_ToggleDeveloperMode_Disabled">
+  <owner>jwd@chromium.org</owner>
+  <description>
+    Extensions: Disables developer mode for Chrome extensions.
+  </description>
+</action>
+
+<action name="Options_ToggleDeveloperMode_Enabled">
+  <owner>jwd@chromium.org</owner>
+  <description>
+    Extensions: Enables developer mode for Chrome extensions.
+  </description>
+</action>
+
 <action name="Options_TouchpadNaturalScroll_Disable">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -9740,6 +9796,11 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Options_UpdateExtensions">
+  <owner>jwd@chromium.org</owner>
+  <description>Extensions: Click on update extensions in settings.</description>
+</action>
+
 <action name="Options_Use24HourClockCheckbox_Disable">
   <owner>michaelpg@chromium.org</owner>
   <description>Settings: Date and time: Use 24-hour clock</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 14f0abb..7ffa0ec 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -11394,6 +11394,15 @@
   </summary>
 </histogram>
 
+<histogram name="GPU.ANGLE.D3D11CreateDeviceMS" units="milliseconds">
+  <owner>jmadill@chromium.org</owner>
+  <summary>
+    The time that elapses for the initial call to D3D11CreateDevice on D3D11
+    ANGLE. A pure system call, with no ANGLE or Chromium code, called once every
+    GPU process startup.
+  </summary>
+</histogram>
+
 <histogram name="GPU.ANGLE.D3D11InitializeResult" enum="D3D11InitializeResult">
   <owner>jmadill@chromium.org</owner>
   <summary>
@@ -13087,6 +13096,14 @@
   </summary>
 </histogram>
 
+<histogram name="interstitial.ssl.good_cert_seen" enum="SSLGoodCertSeenEvent">
+  <owner>jww@chromium.org</owner>
+  <summary>
+    Emitted when a good certificate is seen, specifying whether the user already
+    gave an exception for a bad certificate for the same host.
+  </summary>
+</histogram>
+
 <histogram name="interstitial.ssl.severity_score.authority_invalid" units="%">
   <obsolete>
     Deprecated Jan 2015 (M42).
@@ -13194,6 +13211,57 @@
   </summary>
 </histogram>
 
+<histogram name="Layout.MicroSecondsPerComplexText" units="microseconds">
+  <owner>benjhayden@chromium.org</owner>
+  <summary>
+    For layouts that considered at least 100 nodes, at least half of which were
+    complex text fragments, the average number of microseconds spent laying out
+    each node.
+  </summary>
+</histogram>
+
+<histogram name="Layout.MicroSecondsPerFloat" units="microseconds">
+  <owner>benjhayden@chromium.org</owner>
+  <summary>
+    For layouts that considered at least 100 nodes, at least half of which were
+    floats, the average number of microseconds spent laying out each node.
+  </summary>
+</histogram>
+
+<histogram name="Layout.MicroSecondsPerNode" units="microseconds">
+  <owner>benjhayden@chromium.org</owner>
+  <summary>
+    For layouts that considered at least 100 nodes, the average number of
+    microseconds spent laying out each node.
+  </summary>
+</histogram>
+
+<histogram name="Layout.MicroSecondsPerPositioned" units="microseconds">
+  <owner>benjhayden@chromium.org</owner>
+  <summary>
+    For layouts that considered at least 100 nodes, at least half of which were
+    fixed or absolute positioned, the average number of microseconds spent
+    laying out each node.
+  </summary>
+</histogram>
+
+<histogram name="Layout.MicroSecondsPerSimpleText" units="microseconds">
+  <owner>benjhayden@chromium.org</owner>
+  <summary>
+    For layouts that considered at least 100 nodes, at least half of which were
+    simple text fragments, the average number of microseconds spent laying out
+    each node.
+  </summary>
+</histogram>
+
+<histogram name="Layout.MicroSecondsPerTD" units="microseconds">
+  <owner>benjhayden@chromium.org</owner>
+  <summary>
+    For layouts that considered at least 100 nodes, at least half of which were
+    table cells, the average number of microseconds spent laying out each node.
+  </summary>
+</histogram>
+
 <histogram name="LevelDBEnv.All.SafeThreadAccess" units="accesses">
   <obsolete>
     Deprecated 2013-10. No thread-unsafety was found.
@@ -13639,6 +13707,12 @@
   </summary>
 </histogram>
 
+<histogram name="Login.StateKeyGenerationStatus"
+    enum="LoginStateKeyGenerationStatus">
+  <owner>mnissler@chromium.org</owner>
+  <summary>Result of a state key generation operation.</summary>
+</histogram>
+
 <histogram name="Login.SuccessReason" enum="LoginSuccessReason">
   <owner>nkostylev@chromium.org</owner>
   <summary>Chrome OS login success reason.</summary>
@@ -25450,6 +25524,81 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.AffiliationBackend.FetchSize" units="facets">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    The number of facets for which affiliation information was requested in a
+    network fetch. Recorded for each network fetch.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationBackend.FirstFetchDelay"
+    units="milliseconds">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    The time elapsed between creation of the AffiliationBackend and the first
+    time it needed to issue a network fetch.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationBackend.SubsequentFetchDelay"
+    units="milliseconds">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    The elapsed time between subsequent network fetches. Recorded whenever the
+    AffiliationBackend initiated a network fetch, regardless of success or
+    failure.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationDummyData.RequestResultCount"
+    units="results">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    The number of facets affiliated with a dummy Web facet, according to the
+    affiliation information retrieved from the cache. Recorded for each dummy
+    Web facet, once shortly after start-up, and then periodically every hour;
+    but only if getting affiliations succeeded for the Web facet.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationDummyData.RequestSuccess"
+    enum="BooleanSuccess">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    Whether or not affiliations of a dummy Web facet could be successfully
+    retrieved from the cache. Recorded for each dummy Web facet, once shortly
+    after start-up, and then periodically every hour.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationFetcher.FetchErrorCode"
+    enum="NetErrorCodes">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    The network error code, as reported by the underlying URLFetcher. Recorded
+    only for each network fetch that failed due to network/server errors.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationFetcher.FetchHttpResponseCode"
+    enum="HttpResponseCode">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    The HTTP response code, as reported by the underlying URLFetcher. Recorded
+    only for each network fetch that failed due to network/server errors.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.AffiliationFetcher.FetchResult"
+    enum="AffiliationFetchResult">
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    Whether the network fetch succeeded, failed due to network/server errors, or
+    contained malformed data. Recorded for each network fetch.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.AllowToCollectURLBubble.UIDismissalReason"
     enum="PasswordManagerAllowToCollectURLBubble.UIDismissalReason">
   <obsolete>
@@ -44305,6 +44454,49 @@
   </summary>
 </histogram>
 
+<histogram name="WebCore.IndexedDB.Schema.Index.KeyPathType"
+    enum="IDBKeyPathType">
+  <owner>jsbell@chromium.org</owner>
+  <summary>
+    Records the 'keyPath' type (none, string, or array) during IDBObjectStore's
+    createIndex operation. See http://www.w3.org/TR/IndexedDB/
+  </summary>
+</histogram>
+
+<histogram name="WebCore.IndexedDB.Schema.Index.MultiEntry" enum="Boolean">
+  <owner>jsbell@chromium.org</owner>
+  <summary>
+    Records the 'multiEntry' flag value during IDBObjectStore's createIndex
+    operation. See http://www.w3.org/TR/IndexedDB/
+  </summary>
+</histogram>
+
+<histogram name="WebCore.IndexedDB.Schema.Index.Unique" enum="Boolean">
+  <owner>jsbell@chromium.org</owner>
+  <summary>
+    Records the 'unique' flag value during IDBObjectStore's createIndex
+    operation. See http://www.w3.org/TR/IndexedDB/
+  </summary>
+</histogram>
+
+<histogram name="WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement"
+    enum="Boolean">
+  <owner>jsbell@chromium.org</owner>
+  <summary>
+    Records the 'autoIncrement' flag value during IDBDatabase's
+    createObjectStore operation. See http://www.w3.org/TR/IndexedDB/
+  </summary>
+</histogram>
+
+<histogram name="WebCore.IndexedDB.Schema.ObjectStore.KeyPathType"
+    enum="IDBKeyPathType">
+  <owner>jsbell@chromium.org</owner>
+  <summary>
+    Records the 'keyPath' type (none, string, or array) during IDBDatabase's
+    createObjectStore operation. See http://www.w3.org/TR/IndexedDB/
+  </summary>
+</histogram>
+
 <histogram name="WebCore.PreloadDelayMs" units="milliseconds">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>
@@ -45890,6 +46082,12 @@
   <int value="2" label="IPv6"/>
 </enum>
 
+<enum name="AffiliationFetchResult" type="int">
+  <int value="0" label="Success"/>
+  <int value="1" label="Network/server error"/>
+  <int value="2" label="Malformed response"/>
+</enum>
+
 <enum name="AlternateProtocolUsage" type="int">
   <int value="0" label="ALTERNATE_PROTOCOL_USAGE_NO_RACE"/>
   <int value="1" label="ALTERNATE_PROTOCOL_USAGE_WON_RACE"/>
@@ -48425,6 +48623,7 @@
   <int value="295718620" label="cespy.dll"/>
   <int value="313484566" label="vntsrv.dll"/>
   <int value="447643466" label="libinject.dll"/>
+  <int value="604217493" label="explorerex.dll"/>
   <int value="685821492" label="smdmf.dll"/>
   <int value="750761702" label="systemk.dll"/>
   <int value="777975221" label="activedetect32.dll"/>
@@ -52138,6 +52337,7 @@
       label="V8HTMLTextAreaElement_Autocapitalize_AttributeSetter"/>
   <int value="758" label="SVGHrefBaseVal"/>
   <int value="759" label="SVGHrefAnimVal"/>
+  <int value="760" label="AutocapitalizeAttribute"/>
 </enum>
 
 <enum name="FFmpegCodecs" type="int">
@@ -53317,6 +53517,12 @@
   </int>
 </enum>
 
+<enum name="IDBKeyPathType" type="int">
+  <int value="0" label="None">No key path.</int>
+  <int value="1" label="String">Key path is a string.</int>
+  <int value="2" label="Array">Key path is an array of strings.</int>
+</enum>
+
 <enum name="IDBLevelDBBackingStoreInternalErrorType" type="int">
   <int value="0" label="IDBLevelDBBackingStoreReadError">
     IndexedDB encountered an error attempting to read or decode a value from the
@@ -54948,6 +55154,7 @@
   <int value="-820041355" label="enable-transition-compositing"/>
   <int value="-814097014" label="disable-session-crashed-bubble"/>
   <int value="-813474479" label="site-per-process"/>
+  <int value="-802348444" label="disable-site-engagement-service"/>
   <int value="-795600188" label="disable-async-dns"/>
   <int value="-780798969" label="disable-single-click-autofill"/>
   <int value="-770319039" label="enable-touch-editing"/>
@@ -54971,6 +55178,7 @@
   <int value="-562274241" label="enable-extension-action-redesign"/>
   <int value="-560551550" label="use-memory-pressure-chromeos"/>
   <int value="-536289234" label="ssl-interstitial-v2-colorful"/>
+  <int value="-519960638" label="enable-site-engagement-service"/>
   <int value="-516845951" label="enable-embedded-extension-options"/>
   <int value="-512971943" label="disable-one-copy"/>
   <int value="-510488450" label="disable-pnacl"/>
@@ -55073,6 +55281,8 @@
   <int value="625273056" label="disable-boot-animation"/>
   <int value="630947363" label="touch-events"/>
   <int value="643725031" label="disable-touch-feedback"/>
+  <int value="683410401"
+      label="enable-proximity-auth-bluetooth-low-energy-discovery"/>
   <int value="689489984" label="disable-zero-suggest"/>
   <int value="709850261" label="disable-touch-editing"/>
   <int value="711424932" label="enable-cloud-print-xps"/>
@@ -55176,6 +55386,7 @@
   <int value="1505194447" label="disable-transition-compositing"/>
   <int value="1510476448" label="disable-prefixed-encrypted-media"/>
   <int value="1515196403" label="fast-user-switching"/>
+  <int value="1560188739" label="reader-mode-heuristics"/>
   <int value="1589341623" label="disable-easy-unlock"/>
   <int value="1612974229" label="allow-insecure-localhost"/>
   <int value="1622131033" label="ozone-test-single-overlay-support"/>
@@ -55306,6 +55517,24 @@
   <int value="43" label="RESERVED">Reserved</int>
 </enum>
 
+<enum name="LoginStateKeyGenerationStatus" type="int">
+  <summary>The result of a state key generation operation.</summary>
+  <int value="0" label="GENERATION_METHOD_IDENTIFIER_HASH">
+    Successfully generated state keys from machine identifiers.
+  </int>
+  <int value="1" label="GENERATION_METHOD_HMAC_DEVICE_SECRET">
+    Successfully generated state keys from stable device secret.
+  </int>
+  <int value="2" label="MISSING_IDENTIFIERS">
+    Failed due to missing machine IDs.
+  </int>
+  <int value="3" label="BAD_DEVICE_SECRET">
+    Failed due to invalid device secret input.
+  </int>
+  <int value="4" label="HMAC_INIT_FAILURE">HMAC initialization failed.</int>
+  <int value="5" label="HMAC_SIGN_FAILURE">HMAC computation failed.</int>
+</enum>
+
 <enum name="LoginSuccessReason" type="int">
   <int value="0" label="OFFLINE_AND_ONLINE">
     Login success offline and online
@@ -62335,6 +62564,11 @@
   <int value="9" label="UNKNOWN"/>
 </enum>
 
+<enum name="SSLGoodCertSeenEvent" type="int">
+  <int value="0" label="NO_PREVIOUS_EXCEPTION"/>
+  <int value="1" label="HAD_PREVIOUS_EXCEPTION"/>
+</enum>
+
 <enum name="SSLIsExpiredAndDecision" type="int">
   <int value="0" label="EXPIRED_AND_PROCEED"/>
   <int value="1" label="EXPIRED_AND_DO_NOT_PROCEED"/>
@@ -62359,6 +62593,7 @@
   <int value="102" label="ALPN, SPDY 3.1"/>
   <int value="103" label="ALPN, HTTP/2 draft-14"/>
   <int value="104" label="ALPN, HTTP/2 draft-15"/>
+  <int value="107" label="ALPN, HTTP/2"/>
   <int value="200" label="ALPN, QUIC/1 + SPDY/3"/>
   <int value="501" label="NPN, HTTP/1.1"/>
   <int value="600" label="NPN, SPDY 2.0"/>
@@ -62366,6 +62601,7 @@
   <int value="602" label="NPN, SPDY 3.1"/>
   <int value="603" label="NPN, HTTP/2 draft-14"/>
   <int value="604" label="NPN, HTTP/2 draft-15"/>
+  <int value="607" label="NPN, HTTP/2"/>
   <int value="700" label="NPN, QUIC/1 + SPDY/3"/>
   <int value="1001" label="NPN, fallback to HTTP/1.1"/>
   <int value="1100" label="NPN, fallback to SPDY 2.0"/>
@@ -62373,6 +62609,7 @@
   <int value="1102" label="NPN, fallback to SPDY 3.1"/>
   <int value="1103" label="NPN, fallback to HTTP/2 draft-14"/>
   <int value="1104" label="NPN, fallback to HTTP/2 draft-15"/>
+  <int value="1107" label="NPN, fallback to HTTP/2"/>
   <int value="1200" label="NPN, fallback to QUIC/1 + SPDY/3"/>
 </enum>
 
@@ -64077,6 +64314,17 @@
   <affected-histogram name="CaptivePortal.Session.DiscrepancyWithShill"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="AffiliationDummyData" separator=".">
+  <suffix name="OnStartup"
+      label="with the dummy data being requested shortly after start-up"/>
+  <suffix name="Periodic"
+      label="with the dummy data being requested periodically later"/>
+  <affected-histogram
+      name="PasswordManager.AffiliationDummyData.RequestResultCount"/>
+  <affected-histogram
+      name="PasswordManager.AffiliationDummyData.RequestSuccess"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="AlternateProtocol">
   <suffix name="AlternateProtocol_spdy"
       label="with alternate protocol available but http is used"/>
@@ -64534,7 +64782,47 @@
 <histogram_suffixes name="DataReductionProxy_TamperingTotal" separator="_">
   <suffix name="Total" label="total number of tamperings detected"/>
   <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP"/>
+  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP_CSS"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_0_10KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_100_500KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_10_100KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_500KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_GIF"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_JPG"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_PNG"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_WEBP"/>
+  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP_JS"/>
   <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS"/>
+  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS_CSS"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_0_10KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_100_500KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_10_100KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_500KB"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_GIF"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_JPG"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_PNG"/>
+  <affected-histogram
+      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_WEBP"/>
+  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS_JS"/>
   <affected-histogram name="DataReductionProxy.HeaderTamperDetectionPassHTTP"/>
   <affected-histogram name="DataReductionProxy.HeaderTamperDetectionPassHTTPS"/>
   <affected-histogram name="DataReductionProxy.HeaderTamperedHTTP_ChromeProxy"/>
@@ -64571,6 +64859,22 @@
       name="DataReductionProxy.HeaderTamperedHTTPS_Via_Missing"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="DataReductionProxy_TotalCounts" separator="_">
+  <suffix name="JS" label="JavaScript count"/>
+  <suffix name="CSS" label="CSS count"/>
+  <suffix name="Image" label="image count"/>
+  <suffix name="Image_GIF" label="GIF image count"/>
+  <suffix name="Image_JPG" label="JPG image count"/>
+  <suffix name="Image_PNG" label="PNG image count"/>
+  <suffix name="Image_WEBP" label="WEBP image count"/>
+  <suffix name="Image_0_10KB" label="image counts of 0-10KB"/>
+  <suffix name="Image_10_100KB" label="image counts of 10-100KB"/>
+  <suffix name="Image_100_500KB" label="image counts of 100-500KB"/>
+  <suffix name="Image_500KB" label="image counts of more than 500KB"/>
+  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP"/>
+  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="DataReductionProxyBypassedBytes" separator=".">
   <suffix name="SSL" label="Bypass due to SSL"/>
   <suffix name="LocalBypassRules"
@@ -67207,15 +67511,51 @@
 
 <histogram_suffixes name="PrerenderSource" ordering="prefix">
   <suffix name="" label="All prerenders."/>
-  <suffix name="exp1" label="Likelihood threshold experiment 1."/>
-  <suffix name="exp2" label="Likelihood threshold experiment 2."/>
-  <suffix name="exp3" label="Likelihood threshold experiment 3."/>
-  <suffix name="exp4" label="Likelihood threshold experiment 4."/>
-  <suffix name="exp5" label="Likelihood threshold experiment 5."/>
-  <suffix name="exp6" label="Likelihood threshold experiment 6."/>
-  <suffix name="exp7" label="Likelihood threshold experiment 7."/>
-  <suffix name="exp8" label="Likelihood threshold experiment 8."/>
-  <suffix name="exp9" label="Likelihood threshold experiment 9."/>
+  <suffix name="exp1" label="Likelihood threshold experiment 1.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp2" label="Likelihood threshold experiment 2.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp3" label="Likelihood threshold experiment 3.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp4" label="Likelihood threshold experiment 4.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp5" label="Likelihood threshold experiment 5.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp6" label="Likelihood threshold experiment 6.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp7" label="Likelihood threshold experiment 7.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp8" label="Likelihood threshold experiment 8.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
+  <suffix name="exp9" label="Likelihood threshold experiment 9.">
+    <obsolete>
+      Deprecated April 2015
+    </obsolete>
+  </suffix>
   <suffix name="gws" label="GWS triggered prerender."/>
   <suffix name="externalrequest" label="Externally triggered prerender."/>
   <suffix name="Instant" label="Instant search prerender."/>
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml
index c32d6bd..33502e0 100644
--- a/tools/metrics/rappor/rappor.xml
+++ b/tools/metrics/rappor/rappor.xml
@@ -107,6 +107,15 @@
   </summary>
 </rappor-metric>
 
+<rappor-metric name="Autofill.QueryResponseHasNoServerDataForForm"
+    type="ETLD_PLUS_ONE">
+  <owner>mathp@chromium.org</owner>
+  <summary>
+    The eTLD+1 of a URL for which there was a server query response for which
+    the server had no data at all for at least one form.
+  </summary>
+</rappor-metric>
+
 <rappor-metric name="ContentSettings.MixedScript.DisplayedShield"
     type="ETLD_PLUS_ONE">
   <owner>lgarron@chromium.org</owner>
diff --git a/tools/perf/PRESUBMIT.py b/tools/perf/PRESUBMIT.py
index 70aadd7..ad11c24 100644
--- a/tools/perf/PRESUBMIT.py
+++ b/tools/perf/PRESUBMIT.py
@@ -11,13 +11,6 @@
 import os
 import sys
 
-PYLINT_BLACKLIST = []
-PYLINT_DISABLED_WARNINGS = [
-    'R0923',  # Interface not implemented
-    'R0201',  # Method could be a function
-    'E1101',  # Non-existent member is accessed.
-]
-
 
 def _CommonChecks(input_api, output_api):
   """Performs common checks, which includes running pylint."""
@@ -27,9 +20,7 @@
     # Modules in tools/perf depend on telemetry.
     sys.path = [os.path.join(os.pardir, 'telemetry')] + sys.path
     results.extend(input_api.canned_checks.RunPylint(
-        input_api, output_api,
-        black_list=PYLINT_BLACKLIST,
-        disabled_warnings=PYLINT_DISABLED_WARNINGS))
+        input_api, output_api, black_list=[], pylintrc='pylintrc'))
     results.extend(_CheckJson(input_api, output_api))
     results.extend(_CheckWprShaFiles(input_api, output_api))
   finally:
diff --git a/tools/perf/benchmarks/blink_style.py b/tools/perf/benchmarks/blink_style.py
index cf5049b..0dae4d15 100644
--- a/tools/perf/benchmarks/blink_style.py
+++ b/tools/perf/benchmarks/blink_style.py
@@ -34,6 +34,7 @@
     return 'blink_style.key_mobile_sites'
 
 
+@benchmark.Disabled('mac', 'reference')  # http://crbug.com/479048
 class BlinkStylePolymer(benchmark.Benchmark):
   """Measures performance of Blink's style engine (CSS Parsing, Style Recalc,
   etc.) for Polymer cases.
diff --git a/tools/perf/benchmarks/draw_properties.py b/tools/perf/benchmarks/draw_properties.py
index 7a985fd..8030af6 100644
--- a/tools/perf/benchmarks/draw_properties.py
+++ b/tools/perf/benchmarks/draw_properties.py
@@ -9,8 +9,7 @@
 
 
 # This benchmark depends on tracing categories available in M43
-@benchmark.Disabled('reference',  # http://crbug.com/463111
-                    'android')    # http://crbug.com/471786
+@benchmark.Disabled('reference')
 class DrawPropertiesToughScrolling(benchmark.Benchmark):
   test = draw_properties.DrawProperties
   page_set = page_sets.ToughScrollingCasesPageSet
@@ -20,8 +19,7 @@
 
 
 # This benchmark depends on tracing categories available in M43
-@benchmark.Disabled('reference','win',  # http://crbug.com/463111
-                    'android')          # http://crbug.com/471786
+@benchmark.Disabled('reference','win')  # http://crbug.com/463111
 class DrawPropertiesTop25(benchmark.Benchmark):
   """Measures the relative performance of CalcDrawProperties vs computing draw
   properties from property trees.
diff --git a/tools/perf/benchmarks/dromaeo.py b/tools/perf/benchmarks/dromaeo.py
index b0f7d60c..b10f0a0 100644
--- a/tools/perf/benchmarks/dromaeo.py
+++ b/tools/perf/benchmarks/dromaeo.py
@@ -226,7 +226,9 @@
     return 'dromaeo.jslibeventprototype'
 
 
-@benchmark.Disabled('xp')  # crbug.com/389731
+# xp: crbug.com/389731
+# win7: http://crbug.com/479796
+@benchmark.Disabled('xp', 'win7')
 class DromaeoJslibModifyJquery(_DromaeoBenchmark):
   """Dromaeo JSLib modify jquery JavaScript benchmark.
 
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index b39aeeb9..eaa16f34 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -205,7 +205,6 @@
 class SmoothnessFlingSimpleMobilePages(benchmark.Benchmark):
   """Measures rendering statistics for flinging a simple mobile sites page set.
   """
-  test = smoothness.Smoothness
   page_set = page_sets.SimpleMobileSitesFlingPageSet
 
   def CustomizeBrowserOptions(self, options):
@@ -218,48 +217,57 @@
   def Name(cls):
     return 'smoothness.fling.simple_mobile_sites'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
+
 @benchmark.Enabled('android', 'chromeos')
 class SmoothnessToughPinchZoomCases(benchmark.Benchmark):
   """Measures rendering statistics for pinch-zooming into the tough pinch zoom
   cases.
   """
-  test = smoothness.Smoothness
   page_set = page_sets.ToughPinchZoomCasesPageSet
 
   @classmethod
   def Name(cls):
     return 'smoothness.tough_pinch_zoom_cases'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
 
 @benchmark.Enabled('chromeos')
 class SmoothnessToughScrollingWhileZoomedInCases(benchmark.Benchmark):
   """Measures rendering statistics for pinch-zooming then diagonal scrolling"""
-  test = smoothness.Smoothness
   page_set = page_sets.ToughScrollingWhileZoomedInCasesPageSet
 
   @classmethod
   def Name(cls):
     return 'smoothness.tough_scrolling_while_zoomed_in_cases'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
 
 @benchmark.Enabled('android')
 class SmoothnessPolymer(benchmark.Benchmark):
   """Measures rendering statistics for Polymer cases.
   """
-  test = smoothness.Smoothness
   page_set = page_sets.PolymerPageSet
 
   @classmethod
   def Name(cls):
     return 'smoothness.polymer'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
 
 @benchmark.Enabled('android')
 class SmoothnessGpuRasterizationPolymer(benchmark.Benchmark):
   """Measures rendering statistics for the Polymer cases with GPU rasterization.
   """
   tag = 'gpu_rasterization'
-  test = smoothness.Smoothness
   page_set = page_sets.PolymerPageSet
 
   def CustomizeBrowserOptions(self, options):
@@ -269,6 +277,9 @@
   def Name(cls):
     return 'smoothness.gpu_rasterization.polymer'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
 
 class SmoothnessToughFastScrollingCases(benchmark.Benchmark):
   test = smoothness.Smoothness
@@ -316,20 +327,21 @@
 class SmoothnessPathologicalMobileSites(benchmark.Benchmark):
   """Measures task execution statistics while scrolling pathological sites.
   """
-  test = smoothness.Smoothness
   page_set = page_sets.PathologicalMobileSitesPageSet
 
   @classmethod
   def Name(cls):
     return 'smoothness.pathological_mobile_sites'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
 
 @benchmark.Enabled('android')
 class SmoothnessSyncScrollPathologicalMobileSites(benchmark.Benchmark):
   """Measures task execution statistics while sync-scrolling pathological sites.
   """
   tag = 'sync_scroll'
-  test = smoothness.Smoothness
   page_set = page_sets.PathologicalMobileSitesPageSet
 
   def CustomizeBrowserOptions(self, options):
@@ -339,6 +351,10 @@
   def Name(cls):
     return 'smoothness.sync_scroll.pathological_mobile_sites'
 
+  def CreatePageTest(self, options):  # pylint: disable=unused-argument
+    return smoothness.Smoothness(enable_auto_issuing_marker=False)
+
+
 class SmoothnessToughAnimatedImageCases(benchmark.Benchmark):
   test = smoothness.Smoothness
   page_set = page_sets.ToughAnimatedImageCasesPageSet
diff --git a/tools/perf/measurements/measurement_smoke_test.py b/tools/perf/measurements/measurement_smoke_test.py
index c8debc9..ef45aa9 100644
--- a/tools/perf/measurements/measurement_smoke_test.py
+++ b/tools/perf/measurements/measurement_smoke_test.py
@@ -1,8 +1,6 @@
 # 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.
-"""Measurement smoke test to make sure that no new action_name_to_run is
-defined."""
 
 import logging
 import optparse
@@ -10,6 +8,7 @@
 import unittest
 
 from telemetry import benchmark as benchmark_module
+from telemetry.core import browser_options
 from telemetry.core import discover
 from telemetry.page import page_test
 from telemetry.unittest_util import options_for_unittests
@@ -42,9 +41,15 @@
   for benchmark_class in all_benchmarks_classes:
     options = options_for_unittests.GetCopy()
     parser = optparse.OptionParser()
-    benchmark_class.AddCommandLineArgs(parser)
-    benchmark_module.AddCommandLineArgs(parser)
-    benchmark_class.SetArgumentDefaults(parser)
+    browser_options.BrowserOptions.AddCommandLineArgs(parser)
+    try:
+      benchmark_class.AddCommandLineArgs(parser)
+      benchmark_module.AddCommandLineArgs(parser)
+      benchmark_class.SetArgumentDefaults(parser)
+    except Exception:
+      logging.error('Exception raised when processing benchmark %s'
+          % benchmark_class)
+      raise
     options.MergeDefaultValues(parser.get_default_values())
     pt = benchmark_class().CreatePageTest(options)
     if not isinstance(pt, timeline_based_measurement.TimelineBasedMeasurement):
diff --git a/tools/perf/measurements/smoothness.py b/tools/perf/measurements/smoothness.py
index 12cec16..6cf2741 100644
--- a/tools/perf/measurements/smoothness.py
+++ b/tools/perf/measurements/smoothness.py
@@ -8,7 +8,7 @@
 
 
 class Smoothness(page_test.PageTest):
-  def __init__(self, enable_auto_issuing_marker=True):
+  def __init__(self, enable_auto_issuing_marker=False):
     super(Smoothness, self).__init__()
     self._smoothness_controller = None
     self._enable_auto_issuing_marker = enable_auto_issuing_marker
diff --git a/tools/perf/measurements/smoothness_unittest.py b/tools/perf/measurements/smoothness_unittest.py
index a3f9506..1a4f4e9 100644
--- a/tools/perf/measurements/smoothness_unittest.py
+++ b/tools/perf/measurements/smoothness_unittest.py
@@ -29,16 +29,6 @@
     self.platform = FakePlatform()
 
 
-class AnimatedPage(page.Page):
-  def __init__(self, page_set):
-    super(AnimatedPage, self).__init__(
-      url='file://animated_page.html',
-      page_set=page_set, base_dir=page_set.base_dir)
-
-  def RunPageInteractions(self, action_runner):
-    action_runner.Wait(.2)
-
-
 class FakeTab(object):
   def __init__(self):
     self.browser = FakeBrowser()
@@ -147,19 +137,5 @@
     self.assertEquals(1, len(frame_lengths))
     self.assertGreater(frame_lengths[0].GetRepresentativeNumber, 0)
 
-  @decorators.Disabled('mac', 'chromeos')  # http://crbug.com/403903
-  def testSmoothnessForPageWithNoGesture(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddUserStory(AnimatedPage(ps))
-
-    measurement = smoothness.Smoothness()
-    results = self.RunMeasurement(measurement, ps, options=self._options)
-    self.assertEquals(0, len(results.failures))
-
-    percentage_smooth = results.FindAllPageSpecificValuesNamed(
-        'percentage_smooth')
-    self.assertEquals(len(percentage_smooth), 1)
-    self.assertGreaterEqual(percentage_smooth[0].GetRepresentativeNumber(), 0)
-
   def testCleanUpTrace(self):
     self.TestTracingCleanedUp(smoothness.Smoothness, self._options)
diff --git a/tools/perf/measurements/thread_times_unittest.py b/tools/perf/measurements/thread_times_unittest.py
index 310b98c..a6a2426 100644
--- a/tools/perf/measurements/thread_times_unittest.py
+++ b/tools/perf/measurements/thread_times_unittest.py
@@ -4,14 +4,24 @@
 
 from telemetry.core import wpr_modes
 from telemetry import decorators
+from telemetry.page import page
 from telemetry.unittest_util import options_for_unittests
 from telemetry.unittest_util import page_test_test_case
 
-from measurements import smoothness_unittest
 from measurements import thread_times
 from metrics import timeline
 
 
+class AnimatedPage(page.Page):
+  def __init__(self, page_set):
+    super(AnimatedPage, self).__init__(
+      url='file://animated_page.html',
+      page_set=page_set, base_dir=page_set.base_dir)
+
+  def RunPageInteractions(self, action_runner):
+    action_runner.Wait(.2)
+
+
 class ThreadTimesUnitTest(page_test_test_case.PageTestTestCase):
   def setUp(self):
     self._options = options_for_unittests.GetCopy()
@@ -32,7 +42,7 @@
 
   def testBasicForPageWithNoGesture(self):
     ps = self.CreateEmptyPageSet()
-    ps.AddUserStory(smoothness_unittest.AnimatedPage(ps))
+    ps.AddUserStory(AnimatedPage(ps))
 
     measurement = thread_times.ThreadTimes()
     timeline_options = self._options
diff --git a/tools/perf/page_sets/image_decoding_cases.py b/tools/perf/page_sets/image_decoding_cases.py
index a213115..335040f6 100644
--- a/tools/perf/page_sets/image_decoding_cases.py
+++ b/tools/perf/page_sets/image_decoding_cases.py
@@ -10,7 +10,8 @@
     super(ImageDecodingCasesPage, self).__init__(url=url, page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.Wait(5)
+    with action_runner.CreateInteraction('DecodeImage'):
+      action_runner.Wait(5)
 
 class ImageDecodingCasesPageSet(page_set_module.PageSet):
 
diff --git a/tools/perf/page_sets/maps.py b/tools/perf/page_sets/maps.py
index ed49983f..5bf64cd 100644
--- a/tools/perf/page_sets/maps.py
+++ b/tools/perf/page_sets/maps.py
@@ -24,7 +24,7 @@
     action_runner.Wait(3)
 
   def RunPageInteractions(self, action_runner):
-    with action_runner.RunPageInteractions('MapAnimation'):
+    with action_runner.CreateInteraction('MapAnimation'):
       action_runner.WaitForJavaScriptCondition('window.testDone', 120)
 
 
diff --git a/tools/perf/page_sets/polymer.py b/tools/perf/page_sets/polymer.py
index fa90a7a..bbab4d4 100644
--- a/tools/perf/page_sets/polymer.py
+++ b/tools/perf/page_sets/polymer.py
@@ -97,13 +97,14 @@
       page_set=page_set, run_no_page_interactions=run_no_page_interactions)
 
   def PerformPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript(
-        "document.getElementById('fab').scrollIntoView()")
-    action_runner.Wait(5)
-    self.AnimateShadow(action_runner, 'card')
-    #FIXME(wiltzius) disabling until this issue is fixed:
-    # https://github.com/Polymer/paper-shadow/issues/12
-    #self.AnimateShadow(action_runner, 'fab')
+    with action_runner.CreateInteraction('ScrollAndShadowAnimation'):
+      action_runner.ExecuteJavaScript(
+          "document.getElementById('fab').scrollIntoView()")
+      action_runner.Wait(5)
+      self.AnimateShadow(action_runner, 'card')
+      #FIXME(wiltzius) disabling until this issue is fixed:
+      # https://github.com/Polymer/paper-shadow/issues/12
+      #self.AnimateShadow(action_runner, 'fab')
 
   def AnimateShadow(self, action_runner, eid):
     for i in range(1, 6):
diff --git a/tools/perf/page_sets/tough_animation_cases.py b/tools/perf/page_sets/tough_animation_cases.py
index 5c458d8..485926a 100644
--- a/tools/perf/page_sets/tough_animation_cases.py
+++ b/tools/perf/page_sets/tough_animation_cases.py
@@ -18,7 +18,8 @@
       action_runner.WaitForJavaScriptCondition('window.measurementReady')
 
   def RunPageInteractions(self, action_runner):
-    action_runner.Wait(10)
+    with action_runner.CreateInteraction('ToughAnimation'):
+      action_runner.Wait(10)
 
 class ToughAnimationCasesPageSet(page_set_module.PageSet):
 
diff --git a/tools/perf/page_sets/tough_canvas_cases.py b/tools/perf/page_sets/tough_canvas_cases.py
index 292e911..dd8f9f5 100644
--- a/tools/perf/page_sets/tough_canvas_cases.py
+++ b/tools/perf/page_sets/tough_canvas_cases.py
@@ -17,7 +17,8 @@
         "document.readyState == 'complete'")
 
   def RunPageInteractions(self, action_runner):
-    action_runner.Wait(5)
+    with action_runner.CreateInteraction('CanvasAnimation'):
+      action_runner.Wait(5)
 
 
 class MicrosofFirefliesPage(ToughCanvasCasesPage):
diff --git a/tools/perf/page_sets/tough_filters_cases.py b/tools/perf/page_sets/tough_filters_cases.py
index 6b6fc04..a51e961e 100644
--- a/tools/perf/page_sets/tough_filters_cases.py
+++ b/tools/perf/page_sets/tough_filters_cases.py
@@ -8,15 +8,17 @@
 class ToughFiltersCasesPage(page_module.Page):
 
   def RunPageInteractions(self, action_runner):
-    action_runner.Wait(10)
+    with action_runner.CreateInteraction('Filter'):
+      action_runner.Wait(10)
 
 
 class PirateMarkPage(page_module.Page):
 
   def RunPageInteractions(self, action_runner):
-    action_runner.EvaluateJavaScript(
-        'document.getElementById("benchmarkButtonText").click()')
-    action_runner.Wait(10)
+    with action_runner.CreateInteraction('Filter'):
+      action_runner.EvaluateJavaScript(
+          'document.getElementById("benchmarkButtonText").click()')
+      action_runner.Wait(10)
 
 class ToughFiltersCasesPageSet(page_set_module.PageSet):
 
diff --git a/tools/perf/page_sets/tough_scheduling_cases.py b/tools/perf/page_sets/tough_scheduling_cases.py
index 275f470..6ea808e 100644
--- a/tools/perf/page_sets/tough_scheduling_cases.py
+++ b/tools/perf/page_sets/tough_scheduling_cases.py
@@ -293,7 +293,8 @@
         page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.Wait(3)
+    with action_runner.CreateInteraction('SplitAnimation'):
+      action_runner.Wait(3)
 
 
 class Page20(ToughSchedulingCasesPage):
diff --git a/tools/perf/page_sets/tough_webgl_cases.py b/tools/perf/page_sets/tough_webgl_cases.py
index 461eb55e..099fb9a 100644
--- a/tools/perf/page_sets/tough_webgl_cases.py
+++ b/tools/perf/page_sets/tough_webgl_cases.py
@@ -27,7 +27,8 @@
     action_runner.Wait(2)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.Wait(5)
+    with action_runner.CreateInteraction('WebGLAnimation'):
+      action_runner.Wait(5)
 
 
 class ToughWebglCasesPageSet(page_set_module.PageSet):
diff --git a/tools/perf/profile_creators/cookie_profile_extender.py b/tools/perf/profile_creators/cookie_profile_extender.py
index b98af38..ad9e85d8 100644
--- a/tools/perf/profile_creators/cookie_profile_extender.py
+++ b/tools/perf/profile_creators/cookie_profile_extender.py
@@ -20,12 +20,13 @@
   """
   _COOKIE_DB_EXPECTED_SIZE = 3300
 
-  def __init__(self):
+  def __init__(self, finder_options):
     # The rate limiting factors are fetching network resources and executing
     # javascript. There's not much to be done about the former, and having one
     # tab per logical core appears close to optimum for the latter.
     maximum_batch_size = multiprocessing.cpu_count()
-    super(CookieProfileExtender, self).__init__(maximum_batch_size)
+    super(CookieProfileExtender, self).__init__(
+        finder_options, maximum_batch_size)
 
     # A list of urls that have not yet been navigated to. This list will shrink
     # over time. Each navigation will add a diminishing number of new cookies,
diff --git a/tools/perf/profile_creators/fast_navigation_profile_extender.py b/tools/perf/profile_creators/fast_navigation_profile_extender.py
index 7fa222a..d5b3da7 100644
--- a/tools/perf/profile_creators/fast_navigation_profile_extender.py
+++ b/tools/perf/profile_creators/fast_navigation_profile_extender.py
@@ -4,8 +4,6 @@
 import time
 
 from profile_creators import profile_extender
-from telemetry.core import browser_finder
-from telemetry.core import browser_finder_exceptions
 from telemetry.core import exceptions
 
 
@@ -21,14 +19,14 @@
       with the number of batches, but does not scale with the size of the
       batch.
   """
-  def __init__(self, maximum_batch_size):
+  def __init__(self, finder_options, maximum_batch_size):
     """Initializer.
 
     Args:
       maximum_batch_size: A positive integer indicating the number of tabs to
       simultaneously perform navigations.
     """
-    super(FastNavigationProfileExtender, self).__init__()
+    super(FastNavigationProfileExtender, self).__init__(finder_options)
 
     # The instance keeps a list of Tabs that can be navigated successfully.
     # This means that the Tab is not crashed, and is processing JavaScript in a
@@ -44,19 +42,13 @@
     # The default amount of time to wait for the retrieval of the URL of a tab.
     self._TAB_URL_RETRIEVAL_TIMEOUT_IN_SECONDS = 1
 
-  def Run(self, finder_options):
-    """Extends the profile.
-
-    Args:
-      finder_options: An instance of BrowserFinderOptions that contains the
-      directory of the input profile, the directory to place the output
-      profile, and sufficient information to choose a specific browser binary.
-    """
+  def Run(self):
+    """Superclass override."""
     try:
-      self.SetUp(finder_options)
+      self.SetUpBrowser()
       self._PerformNavigations()
     finally:
-      self.TearDown()
+      self.TearDownBrowser()
 
   def GetUrlIterator(self):
     """Gets URLs for the browser to navigate to.
@@ -83,10 +75,6 @@
     """
     pass
 
-  @property
-  def profile_path(self):
-    return self._profile_path
-
   def _AddNewTab(self):
     """Adds a new tab to the browser."""
 
@@ -124,18 +112,6 @@
     since there is no guarantee that the tab can be safely removed."""
     self._navigation_tabs.remove(tab)
 
-  def _GetPossibleBrowser(self, finder_options):
-    """Return a possible_browser with the given options."""
-    possible_browser = browser_finder.FindBrowser(finder_options)
-    if not possible_browser:
-      raise browser_finder_exceptions.BrowserFinderException(
-          'No browser found.\n\nAvailable browsers:\n%s\n' %
-          '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)))
-    finder_options.browser_options.browser_type = (
-        possible_browser.browser_type)
-
-    return possible_browser
-
   def _RetrieveTabUrl(self, tab, timeout):
     """Retrives the URL of the tab."""
     try:
diff --git a/tools/perf/profile_creators/fast_navigation_profile_extender_unittest.py b/tools/perf/profile_creators/fast_navigation_profile_extender_unittest.py
index 05cf334e..c514947 100644
--- a/tools/perf/profile_creators/fast_navigation_profile_extender_unittest.py
+++ b/tools/perf/profile_creators/fast_navigation_profile_extender_unittest.py
@@ -6,6 +6,7 @@
 from profile_creators.fast_navigation_profile_extender import (
     FastNavigationProfileExtender)
 from telemetry.core import util
+from telemetry.unittest_util import options_for_unittests
 
 util.AddDirToPythonPath(util.GetTelemetryDir(), 'third_party', 'mock')
 import mock
@@ -38,7 +39,8 @@
 class FastNavigationProfileExtenderTest(unittest.TestCase):
   def testPerformNavigations(self):
     maximum_batch_size = 15
-    extender = FastNavigationProfileExtender(maximum_batch_size)
+    options = options_for_unittests.GetCopy()
+    extender = FastNavigationProfileExtender(options, maximum_batch_size)
 
     navigation_urls = []
     for i in range(extender._NUM_TABS):
diff --git a/tools/perf/profile_creators/history_profile_extender.py b/tools/perf/profile_creators/history_profile_extender.py
index 58293c3..f68548f3 100644
--- a/tools/perf/profile_creators/history_profile_extender.py
+++ b/tools/perf/profile_creators/history_profile_extender.py
@@ -14,13 +14,14 @@
   files. It continues running until the history DB becomes full."""
   _HISTORY_DB_MAX_SIZE_IN_MB = 10
 
-  def __init__(self):
+  def __init__(self, finder_options):
     # The rate limiting factors are the speed of page navigation, and the speed
     # of python bindings. The former is larger than the latter, so having a
     # large batch size skews the amortized average time per page load towards
     # the latter.
     maximum_batch_size = multiprocessing.cpu_count() * 2
-    super(HistoryProfileExtender, self).__init__(maximum_batch_size)
+    super(HistoryProfileExtender, self).__init__(
+        finder_options, maximum_batch_size)
 
     # A list of paths of temporary files. The instance is responsible for
     # making sure that the files are deleted before they are removed from this
@@ -64,9 +65,9 @@
     """Superclass override."""
     return self._IsHistoryDBAtMaxSize()
 
-  def TearDown(self):
+  def TearDownBrowser(self):
     """Superclass override."""
-    super(HistoryProfileExtender, self).TearDown()
+    super(HistoryProfileExtender, self).TearDownBrowser()
     for path in self._generated_temp_files:
       os.remove(path)
     self._generated_temp_files = []
diff --git a/tools/perf/profile_creators/history_profile_extender_unittest.py b/tools/perf/profile_creators/history_profile_extender_unittest.py
index c0b0b0f0..46997cd 100644
--- a/tools/perf/profile_creators/history_profile_extender_unittest.py
+++ b/tools/perf/profile_creators/history_profile_extender_unittest.py
@@ -21,7 +21,9 @@
   # The profile extender does not work on Android or ChromeOS.
   @decorators.Disabled('android', 'chromeos')
   def testFullFunctionality(self):
-    extender = HistoryProfileExtender()
+    options = options_for_unittests.GetCopy()
+    options.output_profile_path = tempfile.mkdtemp()
+    extender = HistoryProfileExtender(options)
 
     # Stop the extender at the earliest possible opportunity.
     extender.ShouldExitAfterBatchNavigation = mock.MagicMock(return_value=True)
@@ -29,11 +31,8 @@
     # static, small number to increase the speed of the test.
     extender._NUM_TABS = 3
 
-    options = options_for_unittests.GetCopy()
-    options.output_profile_path = tempfile.mkdtemp()
-
     try:
-      extender.Run(options)
+      extender.Run()
       self.assertEquals(extender.profile_path, options.output_profile_path)
       self.assertTrue(os.path.exists(extender.profile_path))
       history_db_path = os.path.join(extender.profile_path, "Default",
diff --git a/tools/perf/profile_creators/large_profile_extender.py b/tools/perf/profile_creators/large_profile_extender.py
index 8b61efc..56bd4ff 100644
--- a/tools/perf/profile_creators/large_profile_extender.py
+++ b/tools/perf/profile_creators/large_profile_extender.py
@@ -9,9 +9,11 @@
 class LargeProfileExtender(profile_extender.ProfileExtender):
   """This class creates a large profile by performing a large number of url
   navigations."""
-  def Run(self, options):
-    extender = history_profile_extender.HistoryProfileExtender()
-    extender.Run(options)
+  def Run(self):
+    extender = history_profile_extender.HistoryProfileExtender(
+        self.finder_options)
+    extender.Run()
 
-    extender = cookie_profile_extender.CookieProfileExtender()
-    extender.Run(options)
+    extender = cookie_profile_extender.CookieProfileExtender(
+        self.finder_options)
+    extender.Run()
diff --git a/tools/perf/profile_creators/profile_extender.py b/tools/perf/profile_creators/profile_extender.py
index f69957a..b1dccfa6 100644
--- a/tools/perf/profile_creators/profile_extender.py
+++ b/tools/perf/profile_creators/profile_extender.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 telemetry.core import browser_finder
+from telemetry.core import browser_finder_exceptions
 from telemetry.core import platform
 from telemetry.core import wpr_modes
 
@@ -9,31 +11,30 @@
 class ProfileExtender(object):
   """Abstract base class for an object that constructs a Chrome profile."""
 
-  def __init__(self):
-    # The path of the profile that the browser will use while it's running.
-    # This member is initialized during SetUp().
-    self._profile_path = None
+  def __init__(self, finder_options):
+    """Initializer.
+
+    |finder_options| is an instance of BrowserFinderOptions. When subclass
+    implementations of this method inevitably attempt to find and launch a
+    browser, they should pass |finder_options| to the relevant methods.
+
+    Several properties of |finder_options| might require direct manipulation by
+    subclasses. These are:
+      |finder_options.output_profile_path|: The path at which the profile
+      should be created.
+      |finder_options.browser_options.profile_dir|: If this property is None,
+      then a new profile is created. Otherwise, the existing profile is
+      appended on to.
+    """
+    self._finder_options = finder_options
 
     # A reference to the browser that will be performing all of the tab
     # navigations.
-    # This member is initialized during SetUp().
+    # This member is initialized during SetUpBrowser().
     self._browser = None
 
-  def Run(self, options):
-    """Creates or extends the profile.
-
-    |options| is an instance of BrowserFinderOptions. When subclass
-    implementations of this method inevitably attempt to find and launch a
-    browser, they should pass |options| to the relevant methods.
-
-    Several properties of |options| might require direct manipulation by
-    subclasses. These are:
-      |options.output_profile_path|: The path at which the profile should be
-      created.
-      |options.browser_options.profile_dir|: If this property is None, then a
-      new profile is created. Otherwise, the existing profile is appended on
-      to.
-    """
+  def Run(self):
+    """Creates or extends the profile."""
     raise NotImplementedError()
 
   def WebPageReplayArchivePath(self):
@@ -44,35 +45,43 @@
     return None
 
   @property
+  def finder_options(self):
+    """The options to use to find and run the browser."""
+    return self._finder_options
+
+  @property
   def profile_path(self):
-    return self._profile_path
+    """The path of the profile that the browser will use while it's running."""
+    return self.finder_options.output_profile_path
 
   @property
   def browser(self):
     return self._browser
 
-  def SetUp(self, finder_options):
+  def SetUpBrowser(self):
     """Finds and starts the browser.
 
-    Can be overridden by subclasses. Subclasses must call the super class
-    implementation.
+    Can be overridden by subclasses. The subclass implementation must call the
+    super class implementation.
+
+    Subclasses do not need to call this method. This method is only necessary
+    if the subclass needs to start a browser. If a subclass does call this
+    method, the subclass must also call TearDownBrowser().
     """
-    self._profile_path = finder_options.output_profile_path
-    possible_browser = self._GetPossibleBrowser(finder_options)
+    possible_browser = self._GetPossibleBrowser(self.finder_options)
 
     assert possible_browser.supports_tab_control
     assert (platform.GetHostPlatform().GetOSName() in
         ["win", "mac", "linux"])
 
-    self._SetUpWebPageReplay(finder_options, possible_browser)
-    self._browser = possible_browser.Create(finder_options)
+    self._SetUpWebPageReplay(self.finder_options, possible_browser)
+    self._browser = possible_browser.Create(self.finder_options)
 
-  def TearDown(self):
-    """Teardown that is guaranteed to be executed before the instance is
-    destroyed.
+  def TearDownBrowser(self):
+    """Tears down the browser.
 
-    Can be overridden by subclasses. Subclasses must call the super class
-    implementation.
+    Can be overridden by subclasses. The subclass implementation must call the
+    super class implementation.
     """
     if self._browser:
       self._browser.Close()
@@ -108,3 +117,16 @@
     network_controller.SetReplayArgs(
         wpr_archive_path, browser_options.wpr_mode, browser_options.netsim,
         browser_options.extra_wpr_args, make_javascript_deterministic)
+
+  def _GetPossibleBrowser(self, finder_options):
+    """Return a possible_browser with the given options."""
+    possible_browser = browser_finder.FindBrowser(finder_options)
+    if not possible_browser:
+      raise browser_finder_exceptions.BrowserFinderException(
+          'No browser found.\n\nAvailable browsers:\n%s\n' %
+          '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)))
+    finder_options.browser_options.browser_type = (
+        possible_browser.browser_type)
+
+    return possible_browser
+
diff --git a/tools/perf/profile_creators/profile_generator.py b/tools/perf/profile_creators/profile_generator.py
index 784f8aadf..cbbc85e 100644
--- a/tools/perf/profile_creators/profile_generator.py
+++ b/tools/perf/profile_creators/profile_generator.py
@@ -70,9 +70,9 @@
   temp_output_directory = tempfile.mkdtemp()
   options.output_profile_path = temp_output_directory
 
-  profile_creator_instance = profile_extender_class()
+  profile_creator_instance = profile_extender_class(options)
   try:
-    profile_creator_instance.Run(options)
+    profile_creator_instance.Run()
   except Exception as e:
     logging.exception('Profile creation failed.')
     shutil.rmtree(temp_output_directory)
diff --git a/tools/perf/profile_creators/small_profile_extender.py b/tools/perf/profile_creators/small_profile_extender.py
index 2fc64c9..ff9a793 100644
--- a/tools/perf/profile_creators/small_profile_extender.py
+++ b/tools/perf/profile_creators/small_profile_extender.py
@@ -11,11 +11,12 @@
     fast_navigation_profile_extender.FastNavigationProfileExtender):
   """Creates a small profile by performing 25 navigations."""
 
-  def __init__(self):
+  def __init__(self, finder_options):
     # Use exactly 5 tabs to generate the profile. This is because consumers of
     # this profile will perform a session restore, and expect 5 restored tabs.
     maximum_batch_size = 5
-    super(SmallProfileExtender, self).__init__(maximum_batch_size)
+    super(SmallProfileExtender, self).__init__(
+        finder_options, maximum_batch_size)
 
     # Get the list of urls from the typical 25 page set.
     self._page_set = page_sets.Typical25PageSet()
diff --git a/tools/perf/pylintrc b/tools/perf/pylintrc
new file mode 100644
index 0000000..b112c527
--- /dev/null
+++ b/tools/perf/pylintrc
@@ -0,0 +1,17 @@
+[MESSAGES CONTROL]
+
+# Disable the message, report, category or checker with the given id(s).
+# TODO(nednguyen): Remove unusued-argument and unused-import from this list.
+disable=I0010,I0011,abstract-class-little-used,abstract-class-not-used,anomalous-backslash-in-string,bad-builtin,bad-context-manager,bad-continuation,bad-indentation,bad-str-strip-call,bad-whitespace,broad-except,cell-var-from-loop,deprecated-lambda,deprecated-module,duplicate-code,eval-used,exec-used,fixme,function-redefined,global-statement,import-error,interface-not-implemented,invalid-name,locally-enabled,logging-not-lazy,missing-docstring,missing-final-newline,no-init,no-member,no-name-in-module,no-self-use,no-self-use,not-callable,old-style-class,protected-access,reimported,star-args,super-on-old-class,superfluous-parens,too-few-public-methods,too-many-ancestors,too-many-arguments,too-many-branches,too-many-function-args,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-return-statements,too-many-statements,trailing-whitespace,unnecessary-semicolon,unpacking-non-sequence,useless-else-on-loop,unused-argument,unused-import
+
+
+[REPORTS]
+
+# Don't write out full reports, just messages.
+reports=no
+
+
+[FORMAT]
+
+# We use two spaces for indents, instead of the usual four spaces or tab.
+indent-string='  '
diff --git a/tools/perf_expectations/perf_expectations.json b/tools/perf_expectations/perf_expectations.json
index 252be4f7..858241e5 100644
--- a/tools/perf_expectations/perf_expectations.json
+++ b/tools/perf_expectations/perf_expectations.json
@@ -374,7 +374,7 @@
  "linux-release/sizes/nacl_helper-si/initializers": {"reva": 271321, "revb": 271321, "type": "absolute", "better": "lower", "improve": 6, "regress": 8, "sha1": "3394be7f"},
  "linux-release/sizes/nacl_helper-text/text": {"reva": 320500, "revb": 320622, "type": "absolute", "better": "lower", "improve": 5754494, "regress": 6373632, "sha1": "a61cbb0f"},
  "linux-release/sizes/nacl_helper-textrel/textrel": {"reva": 264283, "revb": 264283, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "sha1": "0efaa99f"},
- "linux-release/sizes/nacl_helper/nacl_helper": {"reva": 316558, "revb": 316807, "type": "absolute", "better": "lower", "improve": 7712027, "regress": 8529465, "sha1": "72d6bac9"},
+ "linux-release/sizes/nacl_helper/nacl_helper": {"reva": 326388, "revb": 326429, "type": "absolute", "better": "lower", "improve": 8103256, "regress": 8960541, "sha1": "58f1a213"},
  "linux-release/sizes/nacl_helper_bootstrap-bss/bss": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 1019980807, "regress": 1127347209, "sha1": "a4ff54ab"},
  "linux-release/sizes/nacl_helper_bootstrap-data/data": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 19, "regress": 21, "sha1": "6a3e92f4"},
  "linux-release/sizes/nacl_helper_bootstrap-si/initializers": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "sha1": "dd908f29"},
diff --git a/tools/telemetry/PRESUBMIT.py b/tools/telemetry/PRESUBMIT.py
index b376189..89909f1 100644
--- a/tools/telemetry/PRESUBMIT.py
+++ b/tools/telemetry/PRESUBMIT.py
@@ -4,8 +4,6 @@
 import os
 import sys
 
-PYLINT_BLACKLIST = []
-PYLINT_DISABLED_WARNINGS = ['R0923', 'R0201', 'E1101']
 
 def _CommonChecks(input_api, output_api):
   results = []
@@ -21,9 +19,7 @@
       '$ %s' % os.path.abspath(update_docs_path)))
 
   results.extend(input_api.canned_checks.RunPylint(
-        input_api, output_api,
-        black_list=PYLINT_BLACKLIST,
-        disabled_warnings=PYLINT_DISABLED_WARNINGS))
+        input_api, output_api, black_list=[], pylintrc='pylintrc'))
   return results
 
 def GetPathsToPrepend(input_api):
diff --git a/tools/telemetry/pylintrc b/tools/telemetry/pylintrc
new file mode 100644
index 0000000..b112c527
--- /dev/null
+++ b/tools/telemetry/pylintrc
@@ -0,0 +1,17 @@
+[MESSAGES CONTROL]
+
+# Disable the message, report, category or checker with the given id(s).
+# TODO(nednguyen): Remove unusued-argument and unused-import from this list.
+disable=I0010,I0011,abstract-class-little-used,abstract-class-not-used,anomalous-backslash-in-string,bad-builtin,bad-context-manager,bad-continuation,bad-indentation,bad-str-strip-call,bad-whitespace,broad-except,cell-var-from-loop,deprecated-lambda,deprecated-module,duplicate-code,eval-used,exec-used,fixme,function-redefined,global-statement,import-error,interface-not-implemented,invalid-name,locally-enabled,logging-not-lazy,missing-docstring,missing-final-newline,no-init,no-member,no-name-in-module,no-self-use,no-self-use,not-callable,old-style-class,protected-access,reimported,star-args,super-on-old-class,superfluous-parens,too-few-public-methods,too-many-ancestors,too-many-arguments,too-many-branches,too-many-function-args,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-return-statements,too-many-statements,trailing-whitespace,unnecessary-semicolon,unpacking-non-sequence,useless-else-on-loop,unused-argument,unused-import
+
+
+[REPORTS]
+
+# Don't write out full reports, just messages.
+reports=no
+
+
+[FORMAT]
+
+# We use two spaces for indents, instead of the usual four spaces or tab.
+indent-string='  '
diff --git a/tools/telemetry/telemetry/core/discover.py b/tools/telemetry/telemetry/core/discover.py
index f612bfe..84fe5823 100644
--- a/tools/telemetry/telemetry/core/discover.py
+++ b/tools/telemetry/telemetry/core/discover.py
@@ -52,7 +52,7 @@
 # and class names, then always index by class name.
 @decorators.Cache
 def DiscoverClasses(start_dir, top_level_dir, base_class, pattern='*',
-                    index_by_class_name=False):
+                    index_by_class_name=True):
   """Discover all classes in |start_dir| which subclass |base_class|.
 
   Base classes that contain subclasses are ignored by default.
diff --git a/tools/telemetry/telemetry/core/discover_unittest.py b/tools/telemetry/telemetry/core/discover_unittest.py
index ba2bf70..1bdcf87 100644
--- a/tools/telemetry/telemetry/core/discover_unittest.py
+++ b/tools/telemetry/telemetry/core/discover_unittest.py
@@ -14,19 +14,45 @@
     self._start_dir = os.path.join(self._base_dir, 'discoverable_classes')
     self._base_class = Exception
 
-  def testDiscoverClassesBasic(self):
+  def testDiscoverClassesWithIndexByModuleName(self):
+    classes = discover.DiscoverClasses(
+        self._start_dir, self._base_dir, self._base_class,
+      index_by_class_name=False)
+
+    actual_classes = dict(
+        (name, cls.__name__) for name, cls in classes.iteritems())
+    expected_classes = {
+        'another_discover_dummyclass': 'DummyExceptionImpl2',
+        'discover_dummyclass': 'DummyException',
+    }
+    self.assertEqual(actual_classes, expected_classes)
+
+  def testDiscoverClassesWithIndexByClassName(self):
     classes = discover.DiscoverClasses(
         self._start_dir, self._base_dir, self._base_class)
 
     actual_classes = dict(
         (name, cls.__name__) for name, cls in classes.iteritems())
     expected_classes = {
-        'discover_dummyclass': 'DummyException',
+        'dummy_exception': 'DummyException',
+        'dummy_exception_impl1': 'DummyExceptionImpl1',
+        'dummy_exception_impl2': 'DummyExceptionImpl2'
+    }
+    self.assertEqual(actual_classes, expected_classes)
+
+  def testDiscoverClassesWithPatternAndIndexByModule(self):
+    classes = discover.DiscoverClasses(
+        self._start_dir, self._base_dir, self._base_class,
+        pattern='another*', index_by_class_name=False)
+
+    actual_classes = dict(
+        (name, cls.__name__) for name, cls in classes.iteritems())
+    expected_classes = {
         'another_discover_dummyclass': 'DummyExceptionImpl2',
     }
     self.assertEqual(actual_classes, expected_classes)
 
-  def testDiscoverClassesWithPattern(self):
+  def testDiscoverClassesWithPatternAndIndexByClassName(self):
     classes = discover.DiscoverClasses(
         self._start_dir, self._base_dir, self._base_class,
         pattern='another*')
@@ -34,20 +60,7 @@
     actual_classes = dict(
         (name, cls.__name__) for name, cls in classes.iteritems())
     expected_classes = {
-        'another_discover_dummyclass': 'DummyExceptionImpl2',
-    }
-    self.assertEqual(actual_classes, expected_classes)
-
-  def testDiscoverClassesByClassName(self):
-    classes = discover.DiscoverClasses(
-        self._start_dir, self._base_dir, self._base_class,
-        index_by_class_name=True)
-
-    actual_classes = dict(
-        (name, cls.__name__) for name, cls in classes.iteritems())
-    expected_classes = {
-        'dummy_exception': 'DummyException',
         'dummy_exception_impl1': 'DummyExceptionImpl1',
-        'dummy_exception_impl2': 'DummyExceptionImpl2',
+        'dummy_exception_impl2': 'DummyExceptionImpl2'
     }
     self.assertEqual(actual_classes, expected_classes)
diff --git a/tools/telemetry/telemetry/core/platform/android_platform_backend.py b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
index f3539e7..00aad43 100644
--- a/tools/telemetry/telemetry/core/platform/android_platform_backend.py
+++ b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
@@ -38,6 +38,7 @@
 
 # Get build/android scripts into our path.
 util.AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android')
+from pylib.device import battery_utils # pylint: disable=F0401
 from pylib.device import device_errors  # pylint: disable=F0401
 from pylib.perf import cache_control  # pylint: disable=F0401
 from pylib.perf import perf_control  # pylint: disable=F0401
@@ -70,6 +71,7 @@
       # Ignore result.
       self._adb.EnableAdbRoot()
     self._device = self._adb.device()
+    self._battery = battery_utils.BatteryUtils(self._device)
     self._enable_performance_mode = device.enable_performance_mode
     self._surface_stats_collector = None
     self._perf_tests_setup = perf_control.PerfControl(self._device)
@@ -80,7 +82,7 @@
     power_controller = power_monitor_controller.PowerMonitorController([
         monsoon_power_monitor.MonsoonPowerMonitor(self._device, self),
         android_ds2784_power_monitor.DS2784PowerMonitor(self._device, self),
-        android_dumpsys_power_monitor.DumpsysPowerMonitor(self._device, self),
+        android_dumpsys_power_monitor.DumpsysPowerMonitor(self._battery, self),
     ])
     self._power_monitor = android_temperature_monitor.AndroidTemperatureMonitor(
         power_controller, self._device)
diff --git a/tools/telemetry/telemetry/core/platform/linux_platform_backend_unittest.py b/tools/telemetry/telemetry/core/platform/linux_platform_backend_unittest.py
index 8727779..1059285d 100644
--- a/tools/telemetry/telemetry/core/platform/linux_platform_backend_unittest.py
+++ b/tools/telemetry/telemetry/core/platform/linux_platform_backend_unittest.py
@@ -9,55 +9,35 @@
 from telemetry.core import util
 from telemetry import decorators
 
-class TestBackend(
-    linux_platform_backend.LinuxPlatformBackend):
-
-  def __init__(self):
-    super(TestBackend, self).__init__()
-    self._mock_files = {}
-
-  def SetMockFile(self, filename, output):
-    self._mock_files[filename] = output
-
-  def GetFileContents(self, filename):
-    return self._mock_files[filename]
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def GetSystemCommitCharge(self):
-    raise NotImplementedError()
-
-  def StopVideoCapture(self):
-    raise NotImplementedError()
-
-  def StartVideoCapture(self, min_bitrate_mbps):
-    raise NotImplementedError()
-
-  def GetSystemTotalPhysicalMemory(self):
-    raise NotImplementedError()
+util.AddDirToPythonPath(util.GetTelemetryDir(), 'third_party', 'mock')
+import mock
 
 
 class LinuxPlatformBackendTest(unittest.TestCase):
   @decorators.Enabled('linux')
   def testGetOSVersionNameSaucy(self):
-    backend = TestBackend()
     path = os.path.join(util.GetUnittestDataDir(), 'ubuntu-saucy-lsb-release')
     with open(path) as f:
-      backend.SetMockFile('/etc/lsb-release', f.read())
+      unbuntu_saucy_lsb_release_content = f.read()
 
-    self.assertEqual(backend.GetOSVersionName(), 'saucy')
+    with mock.patch.object(
+        linux_platform_backend.LinuxPlatformBackend, 'GetFileContents',
+        return_value=unbuntu_saucy_lsb_release_content) as mock_method:
+      backend = linux_platform_backend.LinuxPlatformBackend()
+      self.assertEqual(backend.GetOSVersionName(), 'saucy')
+      mock_method.assert_called_once_with('/etc/lsb-release')
 
   @decorators.Enabled('linux')
   def testGetOSVersionNameArch(self):
-    backend = TestBackend()
     path = os.path.join(util.GetUnittestDataDir(), 'arch-lsb-release')
     with open(path) as f:
-      backend.SetMockFile('/etc/lsb-release', f.read())
+      arch_lsb_release_content = f.read()
 
-    # a distribution may not have a codename or a release number. We just check
-    # that GetOSVersionName doesn't raise an exception
-    backend.GetOSVersionName()
+    with mock.patch.object(
+        linux_platform_backend.LinuxPlatformBackend, 'GetFileContents',
+        return_value=arch_lsb_release_content) as mock_method:
+      backend = linux_platform_backend.LinuxPlatformBackend()
+      # a distribution may not have a codename or a release number. We just
+      # check that GetOSVersionName doesn't raise an exception
+      backend.GetOSVersionName()
+      mock_method.assert_called_once_with('/etc/lsb-release')
diff --git a/tools/telemetry/telemetry/core/platform/platform_backend_unittest.py b/tools/telemetry/telemetry/core/platform/platform_backend_unittest.py
index 751e9f19..b4efa57 100644
--- a/tools/telemetry/telemetry/core/platform/platform_backend_unittest.py
+++ b/tools/telemetry/telemetry/core/platform/platform_backend_unittest.py
@@ -11,7 +11,8 @@
 
 
 class PlatformBackendTest(unittest.TestCase):
-  @decorators.Disabled('mac')  # http://crbug.com/440666
+  @decorators.Disabled('mac',  # http://crbug.com/440666
+                       'vista')  # http://crbug.com/479337
   def testPowerMonitoringSync(self):
     # Tests that the act of monitoring power doesn't blow up.
     platform = platform_module.GetHostPlatform()
diff --git a/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py b/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py
index e871441493..f6da6ace 100644
--- a/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py
+++ b/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py
@@ -9,9 +9,6 @@
 from telemetry.core import util
 from telemetry.core.platform.power_monitor import sysfs_power_monitor
 
-# Get build/android scripts into path
-util.AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android')
-from pylib.device import battery_utils # pylint: disable=F0401
 
 class DumpsysPowerMonitor(sysfs_power_monitor.SysfsPowerMonitor):
   """PowerMonitor that relies on the dumpsys batterystats to monitor the power
@@ -19,16 +16,16 @@
   and is the same information end-users see with the battery application.
   Available on Android L and higher releases.
   """
-  def __init__(self, device, platform_backend):
+  def __init__(self, battery, platform_backend):
     """Constructor.
 
     Args:
-        device: A DeviceUtil instance.
+        battery: A BatteryUtil instance.
         platform_backend: A LinuxBasedPlatformBackend instance.
     """
     super(DumpsysPowerMonitor, self).__init__(platform_backend)
+    self._battery = battery
     self._browser = None
-    self._battery = battery_utils.BatteryUtils(device)
 
   def CanMonitorPower(self):
     result = self._platform.RunCommand('dumpsys batterystats -c')
diff --git a/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor_unittest.py b/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor_unittest.py
index 68f925e2..1db6624 100644
--- a/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor_unittest.py
+++ b/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor_unittest.py
@@ -12,7 +12,7 @@
 
 
 class MsrPowerMonitorTest(unittest.TestCase):
-  @decorators.Enabled('win')
+  @decorators.Enabled('xp', 'win7', 'win8')  # http://crbug.com/479337
   def testMsrRuns(self):
     platform_backend = win_platform_backend.WinPlatformBackend()
     power_monitor = msr_power_monitor.MsrPowerMonitor(platform_backend)
diff --git a/tools/telemetry/telemetry/core/platform/win_platform_backend.py b/tools/telemetry/telemetry/core/platform/win_platform_backend.py
index 5be2428..938414e 100644
--- a/tools/telemetry/telemetry/core/platform/win_platform_backend.py
+++ b/tools/telemetry/telemetry/core/platform/win_platform_backend.py
@@ -60,7 +60,8 @@
 
   # Check for WinRing0 and download if needed.
   if not (os.path.exists(dll_path) and os.path.exists(driver_path)):
-    win_binary_dir = os.path.join(path.GetTelemetryDir(), 'bin', 'win')
+    win_binary_dir = os.path.join(
+        path.GetTelemetryDir(), 'bin', 'win', 'AMD64')
     zip_path = os.path.join(win_binary_dir, 'winring0.zip')
     cloud_storage.GetIfChanged(zip_path, bucket=cloud_storage.PUBLIC_BUCKET)
     try:
diff --git a/tools/telemetry/telemetry/timeline/event_container.py b/tools/telemetry/telemetry/timeline/event_container.py
index d145b03..6c1b3c2 100644
--- a/tools/telemetry/telemetry/timeline/event_container.py
+++ b/tools/telemetry/telemetry/timeline/event_container.py
@@ -15,6 +15,10 @@
     self.parent = parent
     self.name = name
 
+  @staticmethod
+  def IsAsyncSlice(t):
+    return t == async_slice_module.AsyncSlice
+
   # Basic functions that subclasses of TimelineEventContainer should implement
   # in order to expose their events. New methods should be added to this part of
   # the code only when absolutely certain they're needed.
@@ -113,13 +117,17 @@
       event_predicate=lambda e: e.name == name and e.parent_slice == None)
 
   def IterAllAsyncSlicesOfName(self, name, recursive=True):
-    def IsAsyncSlice(t):
-      return t == async_slice_module.AsyncSlice
     return self.IterAllEvents(
       recursive=recursive,
-      event_type_predicate=IsAsyncSlice,
+      event_type_predicate=self.IsAsyncSlice,
       event_predicate=lambda e: e.name == name)
 
+  def IterAllAsyncSlicesStartsWithName(self, name, recursive=True):
+    return self.IterAllEvents(
+      recursive=recursive,
+      event_type_predicate=self.IsAsyncSlice,
+      event_predicate=lambda e: e.name.startswith(name))
+
   def IterAllFlowEvents(self, recursive=True):
     return self.IterAllEvents(
       recursive=recursive,
diff --git a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
index 75af84b..231f23e 100644
--- a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
+++ b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
@@ -23,9 +23,9 @@
 END_COMP_NAME = 'INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT'
 
 # Name for a main thread scroll update latency event.
-SCROLL_UPDATE_EVENT_NAME = 'InputLatency:ScrollUpdate'
+SCROLL_UPDATE_EVENT_NAME = 'InputLatency::ScrollUpdate'
 # Name for a gesture scroll update latency event.
-GESTURE_SCROLL_UPDATE_EVENT_NAME = 'InputLatency:GestureScrollUpdate'
+GESTURE_SCROLL_UPDATE_EVENT_NAME = 'InputLatency::GestureScrollUpdate'
 
 # These are keys used in the 'data' field dictionary located in
 # BenchmarkInstrumentation::ImplThreadRenderingStats.
@@ -43,14 +43,14 @@
      within the timeline_range.
 
   Input events dump their LatencyInfo into trace buffer as async trace event
-  with name "InputLatency". The trace event has a memeber 'data' containing
-  its latency history.
+  of name starting with "InputLatency". The trace event has a memeber 'data'
+  containing its latency history.
 
   """
   input_events = []
   if not process:
     return input_events
-  for event in process.IterAllAsyncSlicesOfName('InputLatency'):
+  for event in process.IterAllAsyncSlicesStartsWithName('InputLatency'):
     if event.start >= timeline_range.min and event.end <= timeline_range.max:
       for ss in event.sub_slices:
         if 'data' in ss.args:
diff --git a/tools/ubsan/blacklist.txt b/tools/ubsan/blacklist.txt
index 2db4e185..0dca900 100644
--- a/tools/ubsan/blacklist.txt
+++ b/tools/ubsan/blacklist.txt
@@ -107,3 +107,7 @@
 
 # static_cast<StartPageService*> in StartPageServiceFactory::GetForProfile.
 type:*StartPageService*
+
+# Remove once function attribute level blacklisting is implemented.
+# See crbug.com/476063.
+fun:*forbidGCDuringConstruction*
diff --git a/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt b/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt
index 98043de..55df649 100644
--- a/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt
+++ b/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt
@@ -28,6 +28,7 @@
 
 # http://crbug.com/456131
 BrowserSideNavigationBrowserTest.BrowserInitiatedNavigations
+BrowserSideNavigationBrowserTest.FailedNavigation
 
 # http://crbug.com/464029
 WebRtcBrowserTest.CallAndModifyStream
diff --git a/ui/accessibility/ax_enums.idl b/ui/accessibility/ax_enums.idl
index a61f994..43c9e4b 100644
--- a/ui/accessibility/ax_enums.idl
+++ b/ui/accessibility/ax_enums.idl
@@ -313,6 +313,10 @@
     // Identifies a child tree which this node hosts.
     child_tree_id,
 
+    // Position or Number of items in current set of listitems or treeitems
+    set_size,
+    pos_in_set,
+
     // Indicates if a form control has invalid input or
     // if an element has an aria-invalid attribute.
     invalid_state
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc
index b9a2841..99ff332 100644
--- a/ui/accessibility/ax_node_data.cc
+++ b/ui/accessibility/ax_node_data.cc
@@ -242,6 +242,12 @@
             break;
         }
         break;
+      case AX_ATTR_SET_SIZE:
+        result += " setsize=" + value;
+        break;
+      case AX_ATTR_POS_IN_SET:
+        result += " posinset=" + value;
+        break;
       case AX_ATTR_INVALID_STATE:
         switch (int_attributes[i].second) {
           case AX_INVALID_STATE_FALSE:
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index af45654d6..31ca0b2 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -33,7 +33,7 @@
     COM_INTERFACE_ENTRY(IServiceProvider)
   END_COM_MAP()
 
-  virtual ~AXPlatformNodeWin();
+  ~AXPlatformNodeWin() override;
 
   // AXPlatformNode overrides.
   void Destroy() override;
@@ -48,67 +48,69 @@
   //
 
   // Retrieves the child element or child object at a given point on the screen.
-  virtual STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child);
+  STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child) override;
 
   // Performs the object's default action.
-  STDMETHODIMP accDoDefaultAction(VARIANT var_id);
+  STDMETHODIMP accDoDefaultAction(VARIANT var_id) override;
 
   // Retrieves the specified object's current screen location.
   STDMETHODIMP accLocation(LONG* x_left,
                            LONG* y_top,
                            LONG* width,
                            LONG* height,
-                           VARIANT var_id);
+                           VARIANT var_id) override;
 
   // Traverses to another UI element and retrieves the object.
-  STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end);
+  STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end) override;
 
   // Retrieves an IDispatch interface pointer for the specified child.
-  virtual STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child);
+  STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child) override;
 
   // Retrieves the number of accessible children.
-  virtual STDMETHODIMP get_accChildCount(LONG* child_count);
+  STDMETHODIMP get_accChildCount(LONG* child_count) override;
 
   // Retrieves a string that describes the object's default action.
-  STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action);
+  STDMETHODIMP get_accDefaultAction(VARIANT var_id,
+                                    BSTR* default_action) override;
 
   // Retrieves the tooltip description.
-  STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc);
+  STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc) override;
 
   // Retrieves the object that has the keyboard focus.
-  STDMETHODIMP get_accFocus(VARIANT* focus_child);
+  STDMETHODIMP get_accFocus(VARIANT* focus_child) override;
 
   // Retrieves the specified object's shortcut.
-  STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key);
+  STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id,
+                                       BSTR* access_key) override;
 
   // Retrieves the name of the specified object.
-  STDMETHODIMP get_accName(VARIANT var_id, BSTR* name);
+  STDMETHODIMP get_accName(VARIANT var_id, BSTR* name) override;
 
   // Retrieves the IDispatch interface of the object's parent.
-  STDMETHODIMP get_accParent(IDispatch** disp_parent);
+  STDMETHODIMP get_accParent(IDispatch** disp_parent) override;
 
   // Retrieves information describing the role of the specified object.
-  STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role);
+  STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role) override;
 
   // Retrieves the current state of the specified object.
-  STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state);
+  STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state) override;
 
   // Gets the help string for the specified object.
-  STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help);
+  STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help) override;
 
   // Retrieve or set the string value associated with the specified object.
   // Setting the value is not typically used by screen readers, but it's
   // used frequently by automation software.
-  STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value);
-  STDMETHODIMP put_accValue(VARIANT var_id, BSTR new_value);
+  STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value) override;
+  STDMETHODIMP put_accValue(VARIANT var_id, BSTR new_value) override;
 
   // IAccessible methods not implemented.
-  STDMETHODIMP get_accSelection(VARIANT* selected);
-  STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id);
+  STDMETHODIMP get_accSelection(VARIANT* selected) override;
+  STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id) override;
   STDMETHODIMP get_accHelpTopic(BSTR* help_file,
                                 VARIANT var_id,
-                                LONG* topic_id);
-  STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name);
+                                LONG* topic_id) override;
+  STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) override;
 
   //
   // IAccessible2 methods.
@@ -282,7 +284,9 @@
   // IServiceProvider methods.
   //
 
-  STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** object);
+  STDMETHODIMP QueryService(REFGUID guidService,
+                            REFIID riid,
+                            void** object) override;
 
  protected:
   AXPlatformNodeWin();
diff --git a/ui/aura/input_state_lookup_win.h b/ui/aura/input_state_lookup_win.h
index 94e4ee61..04741fd 100644
--- a/ui/aura/input_state_lookup_win.h
+++ b/ui/aura/input_state_lookup_win.h
@@ -15,10 +15,10 @@
 class AURA_EXPORT InputStateLookupWin : public InputStateLookup {
  public:
   InputStateLookupWin();
-  virtual ~InputStateLookupWin();
+  ~InputStateLookupWin() override;
 
   // InputStateLookup overrides:
-  virtual bool IsMouseButtonDown() const override;
+  bool IsMouseButtonDown() const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(InputStateLookupWin);
diff --git a/ui/aura/remote_window_tree_host_win.h b/ui/aura/remote_window_tree_host_win.h
index b680cc87..4cde32c9 100644
--- a/ui/aura/remote_window_tree_host_win.h
+++ b/ui/aura/remote_window_tree_host_win.h
@@ -79,7 +79,7 @@
 
  protected:
   RemoteWindowTreeHostWin();
-  virtual ~RemoteWindowTreeHostWin();
+  ~RemoteWindowTreeHostWin() override;
 
  private:
   // IPC message handing methods:
@@ -116,25 +116,25 @@
   void OnImeInputSourceChanged(uint16 language_id, bool is_ime);
 
   // WindowTreeHost overrides:
-  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 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 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;
 
   // ui::internal::RemoteInputMethodDelegateWin overrides:
-  virtual void CancelComposition() override;
-  virtual void OnTextInputClientUpdated(
+  void CancelComposition() override;
+  void OnTextInputClientUpdated(
       const std::vector<int32>& input_scopes,
       const std::vector<gfx::Rect>& composition_character_bounds) override;
 
diff --git a/ui/aura/test/ui_controls_factory_aurawin.cc b/ui/aura/test/ui_controls_factory_aurawin.cc
index 717aea5e..36953eb9 100644
--- a/ui/aura/test/ui_controls_factory_aurawin.cc
+++ b/ui/aura/test/ui_controls_factory_aurawin.cc
@@ -30,50 +30,51 @@
   UIControlsWin() {}
 
   // UIControlsAura overrides:
-  virtual bool SendKeyPress(gfx::NativeWindow native_window,
-                            ui::KeyboardCode key,
-                            bool control,
-                            bool shift,
-                            bool alt,
-                            bool command) {
+  bool SendKeyPress(gfx::NativeWindow native_window,
+                    ui::KeyboardCode key,
+                    bool control,
+                    bool shift,
+                    bool alt,
+                    bool command) override {
     DCHECK(!command);  // No command key on Aura
     HWND window =
         native_window->GetHost()->GetAcceleratedWidget();
     return SendKeyPressImpl(
         window, key, control, shift, alt, base::Closure());
   }
-  virtual bool SendKeyPressNotifyWhenDone(gfx::NativeWindow native_window,
-                                          ui::KeyboardCode key,
-                                          bool control,
-                                          bool shift,
-                                          bool alt,
-                                          bool command,
-                                          const base::Closure& task) {
+  bool SendKeyPressNotifyWhenDone(gfx::NativeWindow native_window,
+                                  ui::KeyboardCode key,
+                                  bool control,
+                                  bool shift,
+                                  bool alt,
+                                  bool command,
+                                  const base::Closure& task) override {
     DCHECK(!command);  // No command key on Aura
     HWND window =
         native_window->GetHost()->GetAcceleratedWidget();
     return SendKeyPressImpl(window, key, control, shift, alt, task);
   }
-  virtual bool SendMouseMove(long screen_x, long screen_y) {
+  bool SendMouseMove(long screen_x, long screen_y) override {
     return SendMouseMoveImpl(screen_x, screen_y, base::Closure());
   }
-  virtual bool SendMouseMoveNotifyWhenDone(long screen_x,
-                                           long screen_y,
-                                           const base::Closure& task) {
+  bool SendMouseMoveNotifyWhenDone(long screen_x,
+                                   long screen_y,
+                                   const base::Closure& task) override {
     return SendMouseMoveImpl(screen_x, screen_y, task);
   }
-  virtual bool SendMouseEvents(MouseButton type, int state) {
+  bool SendMouseEvents(MouseButton type, int state) override {
     return SendMouseEventsImpl(type, state, base::Closure());
   }
-  virtual bool SendMouseEventsNotifyWhenDone(MouseButton type,
-                                             int state,
-                                             const base::Closure& task) {
+  bool SendMouseEventsNotifyWhenDone(MouseButton type,
+                                     int state,
+                                     const base::Closure& task) override {
     return SendMouseEventsImpl(type, state, task);
   }
-  virtual bool SendMouseClick(MouseButton type) {
+  bool SendMouseClick(MouseButton type) override {
     return SendMouseEvents(type, UP | DOWN);
   }
-  virtual void RunClosureAfterAllPendingUIEvents(const base::Closure& closure) {
+  void RunClosureAfterAllPendingUIEvents(
+      const base::Closure& closure) override {
     // On windows, posting UI events is synchronous so just post the closure.
     base::MessageLoopForUI::current()->PostTask(FROM_HERE, closure);
   }
diff --git a/ui/aura/window_tree_host_win.h b/ui/aura/window_tree_host_win.h
index a448a3f..8399c8e 100644
--- a/ui/aura/window_tree_host_win.h
+++ b/ui/aura/window_tree_host_win.h
@@ -21,40 +21,39 @@
       public NON_EXPORTED_BASE(ui::PlatformWindowDelegate) {
  public:
   explicit WindowTreeHostWin(const gfx::Rect& bounds);
-  virtual ~WindowTreeHostWin();
+  ~WindowTreeHostWin() override;
 
   // 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 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 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;
 
  protected:
   gfx::AcceleratedWidget hwnd() const { return widget_; }
 
  private:
   // ui::PlatformWindowDelegate:
-  virtual void OnBoundsChanged(const gfx::Rect& new_bounds) override;
-  virtual void OnDamageRect(const gfx::Rect& damaged_region) override;
-  virtual void DispatchEvent(ui::Event* event) override;
-  virtual void OnCloseRequest() override;
-  virtual void OnClosed() override;
-  virtual void OnWindowStateChanged(ui::PlatformWindowState new_state) override;
-  virtual void OnLostCapture() override;
-  virtual void OnAcceleratedWidgetAvailable(
-      gfx::AcceleratedWidget widget) override;
-  virtual void OnActivationChanged(bool active) override;
+  void OnBoundsChanged(const gfx::Rect& new_bounds) override;
+  void OnDamageRect(const gfx::Rect& damaged_region) override;
+  void DispatchEvent(ui::Event* event) override;
+  void OnCloseRequest() override;
+  void OnClosed() override;
+  void OnWindowStateChanged(ui::PlatformWindowState new_state) override;
+  void OnLostCapture() override;
+  void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override;
+  void OnActivationChanged(bool active) override;
 
   bool has_capture_;
   gfx::Rect bounds_;
diff --git a/ui/base/ime/chromeos/ime_bridge.h b/ui/base/ime/chromeos/ime_bridge.h
index 3978ec4..09dd33f3 100644
--- a/ui/base/ime/chromeos/ime_bridge.h
+++ b/ui/base/ime/chromeos/ime_bridge.h
@@ -106,6 +106,10 @@
   // Called when the composition bounds changed.
   virtual void SetCompositionBounds(const std::vector<gfx::Rect>& bounds) = 0;
 
+  // Returns whether the engine is interested in key events.
+  // If not, InputMethodChromeOS won't feed it with key events.
+  virtual bool IsInterestedInKeyEvent() const = 0;
+
  protected:
   IMEEngineHandlerInterface() {}
 };
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.cc b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
index 5645494..867ef19 100644
--- a/ui/base/ime/chromeos/mock_ime_engine_handler.cc
+++ b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
@@ -49,6 +49,10 @@
   ++reset_call_count_;
 }
 
+bool MockIMEEngineHandler::IsInterestedInKeyEvent() const {
+  return true;
+}
+
 void MockIMEEngineHandler::ProcessKeyEvent(
     const ui::KeyEvent& key_event,
     const KeyEventDoneCallback& callback) {
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.h b/ui/base/ime/chromeos/mock_ime_engine_handler.h
index b37a62f..18d3d99 100644
--- a/ui/base/ime/chromeos/mock_ime_engine_handler.h
+++ b/ui/base/ime/chromeos/mock_ime_engine_handler.h
@@ -23,6 +23,7 @@
   void Disable() override;
   void PropertyActivate(const std::string& property_name) override;
   void Reset() override;
+  bool IsInterestedInKeyEvent() const override;
   void ProcessKeyEvent(const ui::KeyEvent& key_event,
                        const KeyEventDoneCallback& callback) override;
   void CandidateClicked(uint32 index) override;
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc
index 0dca378..dd11947 100644
--- a/ui/base/ime/input_method_base.cc
+++ b/ui/base/ime/input_method_base.cc
@@ -38,12 +38,10 @@
 }
 
 void InputMethodBase::OnFocus() {
-  DCHECK(!system_toplevel_window_focused_);
   system_toplevel_window_focused_ = true;
 }
 
 void InputMethodBase::OnBlur() {
-  DCHECK(system_toplevel_window_focused_);
   system_toplevel_window_focused_ = false;
 }
 
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc
index 3a6db87..071a2df 100644
--- a/ui/base/ime/input_method_chromeos.cc
+++ b/ui/base/ime/input_method_chromeos.cc
@@ -37,7 +37,6 @@
     internal::InputMethodDelegate* delegate)
     : composing_text_(false),
       composition_changed_(false),
-      current_keyevent_id_(0),
       weak_ptr_factory_(this) {
   SetDelegate(delegate);
   chromeos::IMEBridge::Get()->SetInputContextHandler(this);
@@ -46,7 +45,6 @@
 }
 
 InputMethodChromeOS::~InputMethodChromeOS() {
-  AbandonAllPendingKeyEvents();
   ConfirmCompositionText();
   // We are dead, so we need to ask the client to stop relying on us.
   OnInputMethodChanged();
@@ -71,12 +69,8 @@
   return false;
 }
 
-void InputMethodChromeOS::ProcessKeyEventDone(uint32 id,
-                                              ui::KeyEvent* event,
+void InputMethodChromeOS::ProcessKeyEventDone(const ui::KeyEvent* event,
                                               bool is_handled) {
-  if (pending_key_events_.find(id) == pending_key_events_.end())
-   return;  // Abandoned key event.
-
   DCHECK(event);
   if (event->type() == ET_KEY_PRESSED) {
     if (is_handled) {
@@ -92,9 +86,6 @@
 
   if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
     ProcessKeyEventPostIME(*event, is_handled);
-
-  // ProcessKeyEventPostIME may change the |pending_key_events_|.
-  pending_key_events_.erase(id);
 }
 
 bool InputMethodChromeOS::DispatchKeyEvent(const ui::KeyEvent& event) {
@@ -138,18 +129,16 @@
     return true;
   }
 
-  pending_key_events_.insert(current_keyevent_id_);
-
-  ui::KeyEvent* copied_event = new ui::KeyEvent(event);
-  GetEngine()->ProcessKeyEvent(
-      event,
-      base::Bind(&InputMethodChromeOS::ProcessKeyEventDone,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 current_keyevent_id_,
-                 // Pass the ownership of |copied_event|.
-                 base::Owned(copied_event)));
-
-  ++current_keyevent_id_;
+  if (GetEngine()->IsInterestedInKeyEvent()) {
+    GetEngine()->ProcessKeyEvent(
+        event,
+        base::Bind(&InputMethodChromeOS::ProcessKeyEventDone,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   // Pass the ownership of the new copied event.
+                   base::Owned(new ui::KeyEvent(event))));
+  } else {
+    ProcessKeyEventDone(&event, false);
+  }
   return true;
 }
 
@@ -312,11 +301,6 @@
   composing_text_ = false;
   composition_changed_ = false;
 
-  // We need to abandon all pending key events, but as above comment says, there
-  // is no reliable way to abandon all results generated by these abandoned key
-  // events.
-  AbandonAllPendingKeyEvents();
-
   // This function runs asynchronously.
   // Note: some input method engines may not support reset method, such as
   // ibus-anthy. But as we control all input method engines by ourselves, we can
@@ -469,10 +453,6 @@
   DispatchKeyEventPostIME(evt);
 }
 
-void InputMethodChromeOS::AbandonAllPendingKeyEvents() {
-  pending_key_events_.clear();
-}
-
 void InputMethodChromeOS::CommitText(const std::string& text) {
   if (text.empty())
     return;
@@ -493,7 +473,7 @@
 
   // If we are not handling key event, do not bother sending text result if the
   // focused text input client does not support text input.
-  if (pending_key_events_.empty() && !IsTextInputTypeNone()) {
+  if (!IsTextInputTypeNone()) {
     SendFakeProcessKeyEvent(true);
     GetTextInputClient()->InsertText(utf16_text);
     SendFakeProcessKeyEvent(false);
@@ -537,13 +517,11 @@
 
   // If we receive a composition text without pending key event, then we need to
   // send it to the focused text input client directly.
-  if (pending_key_events_.empty()) {
-    SendFakeProcessKeyEvent(true);
-    GetTextInputClient()->SetCompositionText(composition_);
-    SendFakeProcessKeyEvent(false);
-    composition_changed_ = false;
-    composition_.Clear();
-  }
+  SendFakeProcessKeyEvent(true);
+  GetTextInputClient()->SetCompositionText(composition_);
+  SendFakeProcessKeyEvent(false);
+  composition_changed_ = false;
+  composition_.Clear();
 }
 
 void InputMethodChromeOS::HidePreeditText() {
@@ -554,15 +532,13 @@
   composition_changed_ = true;
   composition_.Clear();
 
-  if (pending_key_events_.empty()) {
-    TextInputClient* client = GetTextInputClient();
-    if (client && client->HasCompositionText()) {
-      SendFakeProcessKeyEvent(true);
-      client->ClearCompositionText();
-      SendFakeProcessKeyEvent(false);
-    }
-    composition_changed_ = false;
+  TextInputClient* client = GetTextInputClient();
+  if (client && client->HasCompositionText()) {
+    SendFakeProcessKeyEvent(true);
+    client->ClearCompositionText();
+    SendFakeProcessKeyEvent(false);
   }
+  composition_changed_ = false;
 }
 
 void InputMethodChromeOS::DeleteSurroundingText(int32 offset, uint32 length) {
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h
index f0912234..98794165 100644
--- a/ui/base/ime/input_method_chromeos.h
+++ b/ui/base/ime/input_method_chromeos.h
@@ -91,10 +91,6 @@
   // Sends a fake key event for IME composing without physical key events.
   void SendFakeProcessKeyEvent(bool pressed) const;
 
-  // Abandons all pending key events. It usually happends when we lose keyboard
-  // focus, the text input type is changed or we are destroyed.
-  void AbandonAllPendingKeyEvents();
-
   // Passes keyevent and executes character composition if necessary. Returns
   // true if character composer comsumes key event.
   bool ExecuteCharacterComposer(const ui::KeyEvent& event);
@@ -110,7 +106,7 @@
   void HidePreeditText();
 
   // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent.
-  void ProcessKeyEventDone(uint32 id, ui::KeyEvent* event, bool is_handled);
+  void ProcessKeyEventDone(const ui::KeyEvent* event, bool is_handled);
 
   // Returns whether an non-password input field is focused.
   bool IsNonPasswordInputFieldFocused();
@@ -118,11 +114,6 @@
   // 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
-  // pointers to these object so that we can abandon them when necessary.
-  // They will be deleted in ProcessKeyEventDone().
-  std::set<uint32> pending_key_events_;
-
   // Pending composition text generated by the current pending key event.
   // It'll be sent to the focused text input client as soon as we receive the
   // processing result of the pending key event.
@@ -142,9 +133,6 @@
   // Indicates if the composition text is changed or deleted.
   bool composition_changed_;
 
-  // The latest id of key event.
-  uint32 current_keyevent_id_;
-
   // An object to compose a character from a sequence of key presses
   // including dead key etc.
   CharacterComposer character_composer_;
diff --git a/ui/base/ime/input_method_chromeos_unittest.cc b/ui/base/ime/input_method_chromeos_unittest.cc
index 4562eb4..f2d16319 100644
--- a/ui/base/ime/input_method_chromeos_unittest.cc
+++ b/ui/base/ime/input_method_chromeos_unittest.cc
@@ -1008,27 +1008,6 @@
   EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled);
 }
 
-TEST_F(InputMethodChromeOSKeyEventTest, KeyEventDelayResponseResetTest) {
-  ScopedXI2Event xevent;
-  xevent.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_SHIFT_DOWN);
-  const ui::KeyEvent event(xevent);
-
-  // Do key event.
-  input_type_ = TEXT_INPUT_TYPE_TEXT;
-  ime_->OnTextInputTypeChanged(this);
-  ime_->DispatchKeyEvent(event);
-
-  // Check before state.
-  EXPECT_EQ(1, mock_ime_engine_handler_->process_key_event_call_count());
-  EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count());
-
-  ime_->ResetContext();
-
-  // Do callback.
-  mock_ime_engine_handler_->last_passed_callback().Run(true);
-
-  EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count());
-}
 // TODO(nona): Introduce ProcessKeyEventPostIME tests(crbug.com/156593).
 
 }  // namespace ui
diff --git a/ui/base/ios/OWNERS b/ui/base/ios/OWNERS
index f2fff55..ae82009 100644
--- a/ui/base/ios/OWNERS
+++ b/ui/base/ios/OWNERS
@@ -1,3 +1,2 @@
-lliabraa@chromium.org
 rohitrao@chromium.org
 sdefresne@chromium.org
diff --git a/ui/compositor/compositor_switches.cc b/ui/compositor/compositor_switches.cc
index f003e9d..7b8fed3 100644
--- a/ui/compositor/compositor_switches.cc
+++ b/ui/compositor/compositor_switches.cc
@@ -20,7 +20,7 @@
 const char kUIEnableCompositorAnimationTimelines[] =
     "ui-enable-compositor-animation-timelines";
 
-const char kUIDisableImplSidePainting[] = "ui-disable-impl-side-painting";
+const char kUIEnableImplSidePainting[] = "ui-enable-impl-side-painting";
 
 const char kUIEnableSlimmingPaint[] = "ui-enable-slimming-paint";
 
@@ -35,8 +35,7 @@
 bool IsUIImplSidePaintingEnabled() {
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
-
-  return !command_line.HasSwitch(switches::kUIDisableImplSidePainting);
+  return command_line.HasSwitch(switches::kUIEnableImplSidePainting);
 }
 
 bool IsUIZeroCopyEnabled() {
diff --git a/ui/compositor/compositor_switches.h b/ui/compositor/compositor_switches.h
index 2812d62..a6ffba8 100644
--- a/ui/compositor/compositor_switches.h
+++ b/ui/compositor/compositor_switches.h
@@ -13,8 +13,8 @@
 COMPOSITOR_EXPORT extern const char kEnablePixelOutputInTests[];
 COMPOSITOR_EXPORT extern const char kUIDisableThreadedCompositing[];
 COMPOSITOR_EXPORT extern const char kUIEnableCompositorAnimationTimelines[];
+COMPOSITOR_EXPORT extern const char kUIEnableImplSidePainting[];
 COMPOSITOR_EXPORT extern const char kUIEnableSlimmingPaint[];
-COMPOSITOR_EXPORT extern const char kUIDisableImplSidePainting[];
 COMPOSITOR_EXPORT extern const char kUIEnableZeroCopy[];
 COMPOSITOR_EXPORT extern const char kUIShowPaintRects[];
 
diff --git a/ui/compositor/compositor_unittest.cc b/ui/compositor/compositor_unittest.cc
index c64b8ce..3662080 100644
--- a/ui/compositor/compositor_unittest.cc
+++ b/ui/compositor/compositor_unittest.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 "base/message_loop/message_loop_proxy.h"
 #include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "cc/output/begin_frame_args.h"
 #include "cc/test/begin_frame_args_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -30,7 +30,7 @@
   ~CompositorTest() override {}
 
   void SetUp() override {
-    task_runner_ = base::MessageLoopProxy::current();
+    task_runner_ = base::ThreadTaskRunnerHandle::Get();
 
     ui::ContextFactory* context_factory =
         ui::InitializeContextFactoryForTests(false);
@@ -44,11 +44,11 @@
   }
 
  protected:
-  base::MessageLoopProxy* task_runner() { return task_runner_.get(); }
+  base::SingleThreadTaskRunner* task_runner() { return task_runner_.get(); }
   ui::Compositor* compositor() { return compositor_.get(); }
 
  private:
-  scoped_refptr<base::MessageLoopProxy> task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   scoped_ptr<ui::Compositor> compositor_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorTest);
diff --git a/ui/compositor/test/test_compositor_host_win.cc b/ui/compositor/test/test_compositor_host_win.cc
index e89d092..3cdd2835 100644
--- a/ui/compositor/test/test_compositor_host_win.cc
+++ b/ui/compositor/test/test_compositor_host_win.cc
@@ -24,17 +24,11 @@
     compositor_->SetScaleAndSize(1.0f, GetSize());
   }
 
-  virtual ~TestCompositorHostWin() {
-    DestroyWindow(hwnd());
-  }
+  ~TestCompositorHostWin() override { DestroyWindow(hwnd()); }
 
   // Overridden from TestCompositorHost:
-  virtual void Show() override {
-    ShowWindow(hwnd(), SW_SHOWNORMAL);
-  }
-  virtual ui::Compositor* GetCompositor() override {
-    return compositor_.get();
-  }
+  void Show() override { ShowWindow(hwnd(), SW_SHOWNORMAL); }
+  ui::Compositor* GetCompositor() override { return compositor_.get(); }
 
  private:
   CR_BEGIN_MSG_MAP_EX(TestCompositorHostWin)
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn
index 9b5f2ba..d3dcaa6 100644
--- a/ui/display/BUILD.gn
+++ b/ui/display/BUILD.gn
@@ -7,13 +7,18 @@
 
 component("display") {
   sources = [
+    "chromeos/apply_content_protection_task.cc",
+    "chromeos/apply_content_protection_task.h",
     "chromeos/configure_displays_task.cc",
     "chromeos/configure_displays_task.h",
     "chromeos/display_configurator.cc",
     "chromeos/display_configurator.h",
+    "chromeos/display_layout_manager.h",
     "chromeos/display_util.cc",
     "chromeos/display_util.h",
     "chromeos/ozone/display_configurator_ozone.cc",
+    "chromeos/query_content_protection_task.cc",
+    "chromeos/query_content_protection_task.h",
     "chromeos/update_display_configuration_task.cc",
     "chromeos/update_display_configuration_task.h",
     "chromeos/x11/display_configurator_x11.cc",
@@ -111,6 +116,8 @@
     "chromeos/test/action_logger.h",
     "chromeos/test/action_logger_util.cc",
     "chromeos/test/action_logger_util.h",
+    "chromeos/test/test_display_layout_manager.cc",
+    "chromeos/test/test_display_layout_manager.h",
     "chromeos/test/test_native_display_delegate.cc",
     "chromeos/test/test_native_display_delegate.h",
   ]
@@ -128,8 +135,10 @@
 
 test("display_unittests") {
   sources = [
+    "chromeos/apply_content_protection_task_unittest.cc",
     "chromeos/configure_displays_task_unittest.cc",
     "chromeos/display_configurator_unittest.cc",
+    "chromeos/query_content_protection_task_unittest.cc",
     "chromeos/update_display_configuration_task_unittest.cc",
     "chromeos/x11/display_util_x11_unittest.cc",
     "chromeos/x11/native_display_event_dispatcher_x11_unittest.cc",
diff --git a/ui/display/chromeos/apply_content_protection_task.cc b/ui/display/chromeos/apply_content_protection_task.cc
new file mode 100644
index 0000000..e25d427
--- /dev/null
+++ b/ui/display/chromeos/apply_content_protection_task.cc
@@ -0,0 +1,172 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/display/chromeos/apply_content_protection_task.h"
+
+#include "ui/display/chromeos/display_layout_manager.h"
+#include "ui/display/types/display_snapshot.h"
+#include "ui/display/types/native_display_delegate.h"
+
+namespace ui {
+
+namespace {
+
+bool GetHDCPCapableDisplays(
+    const DisplayLayoutManager& layout_manager,
+    std::vector<DisplaySnapshot*>* hdcp_capable_displays) {
+  for (DisplaySnapshot* display : layout_manager.GetDisplayStates()) {
+    switch (display->type()) {
+      case DISPLAY_CONNECTION_TYPE_UNKNOWN:
+        return false;
+      // DisplayPort, DVI, and HDMI all support HDCP.
+      case DISPLAY_CONNECTION_TYPE_DISPLAYPORT:
+      case DISPLAY_CONNECTION_TYPE_DVI:
+      case DISPLAY_CONNECTION_TYPE_HDMI:
+        hdcp_capable_displays->push_back(display);
+        break;
+      case DISPLAY_CONNECTION_TYPE_INTERNAL:
+      case DISPLAY_CONNECTION_TYPE_VGA:
+      case DISPLAY_CONNECTION_TYPE_NETWORK:
+        // No protections for these types. Do nothing.
+        break;
+      case DISPLAY_CONNECTION_TYPE_NONE:
+        NOTREACHED();
+        break;
+    }
+  }
+
+  return true;
+}
+
+}  // namespace
+
+ApplyContentProtectionTask::ApplyContentProtectionTask(
+    DisplayLayoutManager* layout_manager,
+    NativeDisplayDelegate* native_display_delegate,
+    const DisplayConfigurator::ContentProtections& requests,
+    const ResponseCallback& callback)
+    : layout_manager_(layout_manager),
+      native_display_delegate_(native_display_delegate),
+      requests_(requests),
+      callback_(callback),
+      query_status_(true),
+      pending_requests_(0),
+      weak_ptr_factory_(this) {
+}
+
+ApplyContentProtectionTask::~ApplyContentProtectionTask() {
+}
+
+void ApplyContentProtectionTask::Run() {
+  std::vector<DisplaySnapshot*> hdcp_capable_displays;
+  if (!GetHDCPCapableDisplays(*layout_manager_, &hdcp_capable_displays)) {
+    callback_.Run(false);
+    return;
+  }
+
+  pending_requests_ = hdcp_capable_displays.size();
+  if (pending_requests_ == 0) {
+    callback_.Run(true);
+    return;
+  }
+
+  // Need to poll the driver for updates since other applications may have
+  // updated the state.
+  for (DisplaySnapshot* display : hdcp_capable_displays) {
+    native_display_delegate_->GetHDCPState(
+        *display,
+        base::Bind(&ApplyContentProtectionTask::OnHDCPStateUpdate,
+                   weak_ptr_factory_.GetWeakPtr(), display->display_id()));
+  }
+}
+
+void ApplyContentProtectionTask::OnHDCPStateUpdate(int64_t display_id,
+                                                   bool success,
+                                                   HDCPState state) {
+  query_status_ &= success;
+  display_hdcp_state_map_[display_id] = state;
+  pending_requests_--;
+
+  // Wait for all the requests before continuing.
+  if (pending_requests_ != 0)
+    return;
+
+  if (!query_status_) {
+    callback_.Run(false);
+    return;
+  }
+
+  ApplyProtections();
+}
+
+void ApplyContentProtectionTask::ApplyProtections() {
+  std::vector<DisplaySnapshot*> hdcp_capable_displays;
+  if (!GetHDCPCapableDisplays(*layout_manager_, &hdcp_capable_displays)) {
+    callback_.Run(false);
+    return;
+  }
+
+  std::vector<std::pair<DisplaySnapshot*, HDCPState>> hdcp_requests;
+  // Figure out which displays need to have their HDCP state changed.
+  for (DisplaySnapshot* display : hdcp_capable_displays) {
+    uint32_t desired_mask = GetDesiredProtectionMask(display->display_id());
+
+    auto it = display_hdcp_state_map_.find(display->display_id());
+    // If the display can't be found, the display configuration changed.
+    if (it == display_hdcp_state_map_.end()) {
+      callback_.Run(false);
+      return;
+    }
+
+    bool hdcp_enabled = it->second != HDCP_STATE_UNDESIRED;
+    bool hdcp_requested = desired_mask & CONTENT_PROTECTION_METHOD_HDCP;
+    if (hdcp_enabled != hdcp_requested) {
+      hdcp_requests.push_back(std::make_pair(
+          display, hdcp_requested ? HDCP_STATE_DESIRED : HDCP_STATE_UNDESIRED));
+    }
+  }
+
+  pending_requests_ = hdcp_requests.size();
+  // All the requested changes are the same as the current HDCP state. Nothing
+  // to do anymore, just ack the content protection change.
+  if (pending_requests_ == 0) {
+    callback_.Run(true);
+    return;
+  }
+
+  for (const auto& pair : hdcp_requests) {
+    native_display_delegate_->SetHDCPState(
+        *pair.first, pair.second,
+        base::Bind(&ApplyContentProtectionTask::OnHDCPStateApplied,
+                   weak_ptr_factory_.GetWeakPtr()));
+  }
+}
+
+void ApplyContentProtectionTask::OnHDCPStateApplied(bool success) {
+  query_status_ &= success;
+  pending_requests_--;
+
+  if (pending_requests_ == 0)
+    callback_.Run(query_status_);
+}
+
+uint32_t ApplyContentProtectionTask::GetDesiredProtectionMask(
+    int64_t display_id) const {
+  uint32_t desired_mask = 0;
+  // In mirror mode, protection request of all displays need to be fulfilled.
+  // In non-mirror mode, only request of client's display needs to be
+  // fulfilled.
+  if (layout_manager_->IsMirroring()) {
+    for (auto pair : requests_)
+      desired_mask |= pair.second;
+  } else {
+    auto it = requests_.find(display_id);
+    if (it != requests_.end())
+      desired_mask = it->second;
+  }
+
+  return desired_mask;
+}
+
+}  // namespace ui
diff --git a/ui/display/chromeos/apply_content_protection_task.h b/ui/display/chromeos/apply_content_protection_task.h
new file mode 100644
index 0000000..48fa59f
--- /dev/null
+++ b/ui/display/chromeos/apply_content_protection_task.h
@@ -0,0 +1,85 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_DISPLAY_CHROMEOS_APPLY_CONTENT_PROTECTION_TASK_H_
+#define UI_DISPLAY_CHROMEOS_APPLY_CONTENT_PROTECTION_TASK_H_
+
+#include <map>
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "ui/display/chromeos/display_configurator.h"
+
+namespace ui {
+
+class DisplayLayoutManager;
+class DisplaySnapshot;
+class NativeDisplayDelegate;
+
+// In order to apply content protection the task executes in the following
+// manner:
+// 1) Run()
+//   a) Query NativeDisplayDelegate for HDCP state on capable displays
+//   b) OnHDCPStateUpdate() called for each display as response to (a)
+// 2) ApplyProtections()
+//   a) Compute preferred HDCP state for capable displays
+//   b) Call into NativeDisplayDelegate to set HDCP state on capable displays
+//   c) OnHDCPStateApplied() called for each display as reponse to (b)
+// 3) Call |callback_| to signal end of task.
+//
+// Note, in steps 1a and 2a, if no HDCP capable displays are found or if errors
+// are reported, the task finishes early and skips to step 3.
+class DISPLAY_EXPORT ApplyContentProtectionTask {
+ public:
+  typedef base::Callback<void(bool)> ResponseCallback;
+
+  ApplyContentProtectionTask(
+      DisplayLayoutManager* layout_manager,
+      NativeDisplayDelegate* native_display_delegate,
+      const DisplayConfigurator::ContentProtections& requests,
+      const ResponseCallback& callback);
+  ~ApplyContentProtectionTask();
+
+  void Run();
+
+ private:
+  // Callback to NatvieDisplayDelegate::GetHDCPState()
+  void OnHDCPStateUpdate(int64_t display_id, bool success, HDCPState state);
+
+  // Callback to NativeDisplayDelegate::SetHDCPState()
+  void OnHDCPStateApplied(bool success);
+
+  void ApplyProtections();
+
+  uint32_t GetDesiredProtectionMask(int64_t display_id) const;
+
+  DisplayLayoutManager* layout_manager_;  // Not owned.
+
+  NativeDisplayDelegate* native_display_delegate_;  // Not owned.
+
+  DisplayConfigurator::ContentProtections requests_;
+
+  // Callback used to respond once the task finishes.
+  ResponseCallback callback_;
+
+  // Mapping between display IDs and the HDCP state returned by
+  // NativeDisplayDelegate.
+  std::map<int64_t, HDCPState> display_hdcp_state_map_;
+
+  // Tracks the status of the NativeDisplayDelegate responses. This will be true
+  // if all the queries were successful, false otherwise.
+  bool query_status_;
+
+  // Tracks the number of NativeDisplayDelegate requests sent but not answered
+  // yet.
+  size_t pending_requests_;
+
+  base::WeakPtrFactory<ApplyContentProtectionTask> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ApplyContentProtectionTask);
+};
+
+}  // namespace ui
+
+#endif  // UI_DISPLAY_CHROMEOS_APPLY_CONTENT_PROTECTION_TASK_H_
diff --git a/ui/display/chromeos/apply_content_protection_task_unittest.cc b/ui/display/chromeos/apply_content_protection_task_unittest.cc
new file mode 100644
index 0000000..df279c9
--- /dev/null
+++ b/ui/display/chromeos/apply_content_protection_task_unittest.cc
@@ -0,0 +1,174 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/chromeos/apply_content_protection_task.h"
+#include "ui/display/chromeos/display_layout_manager.h"
+#include "ui/display/chromeos/test/action_logger_util.h"
+#include "ui/display/chromeos/test/test_display_layout_manager.h"
+#include "ui/display/chromeos/test/test_display_snapshot.h"
+#include "ui/display/chromeos/test/test_native_display_delegate.h"
+
+namespace ui {
+namespace test {
+
+namespace {
+
+scoped_ptr<DisplaySnapshot> CreateDisplaySnapshot(int64_t id,
+                                                  DisplayConnectionType type) {
+  scoped_ptr<TestDisplaySnapshot> display(new TestDisplaySnapshot());
+  display->set_display_id(id);
+  display->set_type(type);
+
+  return display.Pass();
+}
+
+}  // namespace
+
+class ApplyContentProtectionTaskTest : public testing::Test {
+ public:
+  enum Response {
+    ERROR,
+    SUCCESS,
+    NOT_CALLED,
+  };
+
+  ApplyContentProtectionTaskTest()
+      : response_(NOT_CALLED), display_delegate_(&log_) {}
+  ~ApplyContentProtectionTaskTest() override {}
+
+  void ResponseCallback(bool success) { response_ = success ? SUCCESS : ERROR; }
+
+ protected:
+  Response response_;
+  ActionLogger log_;
+  TestNativeDisplayDelegate display_delegate_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ApplyContentProtectionTaskTest);
+};
+
+TEST_F(ApplyContentProtectionTaskTest, ApplyWithNoHDCPCapableDisplay) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(
+      CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_INTERNAL));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+
+  DisplayConfigurator::ContentProtections request;
+  request[1] = CONTENT_PROTECTION_METHOD_HDCP;
+  ApplyContentProtectionTask task(
+      &layout_manager, &display_delegate_, request,
+      base::Bind(&ApplyContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_EQ(SUCCESS, response_);
+  EXPECT_EQ(kNoActions, log_.GetActionsAndClear());
+}
+
+TEST_F(ApplyContentProtectionTaskTest, ApplyWithHDMIDisplay) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+
+  DisplayConfigurator::ContentProtections request;
+  request[1] = CONTENT_PROTECTION_METHOD_HDCP;
+  ApplyContentProtectionTask task(
+      &layout_manager, &display_delegate_, request,
+      base::Bind(&ApplyContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_EQ(SUCCESS, response_);
+  EXPECT_EQ(
+      JoinActions(GetSetHDCPStateAction(*layout_manager.GetDisplayStates()[0],
+                                        HDCP_STATE_DESIRED).c_str(),
+                  NULL),
+      log_.GetActionsAndClear());
+}
+
+TEST_F(ApplyContentProtectionTaskTest, ApplyWithUnknownDisplay) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_UNKNOWN));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+
+  DisplayConfigurator::ContentProtections request;
+  request[1] = CONTENT_PROTECTION_METHOD_HDCP;
+  ApplyContentProtectionTask task(
+      &layout_manager, &display_delegate_, request,
+      base::Bind(&ApplyContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_EQ(ERROR, response_);
+  EXPECT_EQ(kNoActions, log_.GetActionsAndClear());
+}
+
+TEST_F(ApplyContentProtectionTaskTest, FailGettingHDCPState) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+  display_delegate_.set_get_hdcp_state_expectation(false);
+
+  DisplayConfigurator::ContentProtections request;
+  request[1] = CONTENT_PROTECTION_METHOD_HDCP;
+  ApplyContentProtectionTask task(
+      &layout_manager, &display_delegate_, request,
+      base::Bind(&ApplyContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_EQ(ERROR, response_);
+  EXPECT_EQ(kNoActions, log_.GetActionsAndClear());
+}
+
+TEST_F(ApplyContentProtectionTaskTest, FailSettingHDCPState) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+  display_delegate_.set_set_hdcp_state_expectation(false);
+
+  DisplayConfigurator::ContentProtections request;
+  request[1] = CONTENT_PROTECTION_METHOD_HDCP;
+  ApplyContentProtectionTask task(
+      &layout_manager, &display_delegate_, request,
+      base::Bind(&ApplyContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_EQ(ERROR, response_);
+  EXPECT_EQ(
+      JoinActions(GetSetHDCPStateAction(*layout_manager.GetDisplayStates()[0],
+                                        HDCP_STATE_DESIRED).c_str(),
+                  NULL),
+      log_.GetActionsAndClear());
+}
+
+TEST_F(ApplyContentProtectionTaskTest, ApplyNoopProtection) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+  display_delegate_.set_hdcp_state(HDCP_STATE_UNDESIRED);
+
+  DisplayConfigurator::ContentProtections request;
+  request[1] = CONTENT_PROTECTION_METHOD_NONE;
+  ApplyContentProtectionTask task(
+      &layout_manager, &display_delegate_, request,
+      base::Bind(&ApplyContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_EQ(SUCCESS, response_);
+  EXPECT_EQ(kNoActions, log_.GetActionsAndClear());
+}
+
+}  // namespace test
+}  // namespace ui
diff --git a/ui/display/chromeos/display_configurator.cc b/ui/display/chromeos/display_configurator.cc
index 8b1f1f7c2..48e31ab 100644
--- a/ui/display/chromeos/display_configurator.cc
+++ b/ui/display/chromeos/display_configurator.cc
@@ -9,6 +9,7 @@
 #include "base/logging.h"
 #include "base/sys_info.h"
 #include "base/time/time.h"
+#include "ui/display/chromeos/display_layout_manager.h"
 #include "ui/display/chromeos/display_util.h"
 #include "ui/display/chromeos/update_display_configuration_task.h"
 #include "ui/display/display_switches.h"
@@ -81,6 +82,8 @@
                         chromeos::DisplayPowerState new_power_state,
                         std::vector<DisplayConfigureRequest>* requests,
                         gfx::Size* framebuffer_size) const override;
+  DisplayStateList GetDisplayStates() const override;
+  bool IsMirroring() const override;
 
  private:
   // Parses the |displays| into a list of DisplayStates. This effectively adds
@@ -329,6 +332,19 @@
   return true;
 }
 
+DisplayConfigurator::DisplayStateList
+DisplayConfigurator::DisplayLayoutManagerImpl::GetDisplayStates() const {
+  return configurator_->cached_displays();
+}
+
+bool DisplayConfigurator::DisplayLayoutManagerImpl::IsMirroring() const {
+  if (GetDisplayState() == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)
+    return true;
+
+  return GetSoftwareMirroringController() &&
+         GetSoftwareMirroringController()->SoftwareMirroringEnabled();
+}
+
 const DisplayMode*
 DisplayConfigurator::DisplayLayoutManagerImpl::GetUserSelectedMode(
     const DisplaySnapshot& display) const {
@@ -622,33 +638,39 @@
   ApplyProtections(protections);
 }
 
-bool DisplayConfigurator::QueryContentProtectionStatus(
+void DisplayConfigurator::QueryContentProtectionStatus(
     ContentProtectionClientId client_id,
     int64_t display_id,
-    uint32_t* link_mask,
-    uint32_t* protection_mask) {
-  if (!configure_display_ || display_externally_controlled_)
-    return false;
+    const QueryProtectionCallback& callback) {
+  QueryProtectionResponse response;
+  if (!configure_display_ || display_externally_controlled_) {
+    callback.Run(response);
+    return;
+  }
 
   uint32_t enabled = 0;
   uint32_t unfulfilled = 0;
-  *link_mask = 0;
+  uint32_t link_mask = 0;
   for (const DisplaySnapshot* display : cached_displays_) {
     // Query display if it is in mirror mode or client on the same display.
     if (!IsMirroring() && display->display_id() != display_id)
       continue;
 
-    *link_mask |= display->type();
+    link_mask |= display->type();
     switch (display->type()) {
       case DISPLAY_CONNECTION_TYPE_UNKNOWN:
-        return false;
+        callback.Run(response);
+        return;
       // DisplayPort, DVI, and HDMI all support HDCP.
       case DISPLAY_CONNECTION_TYPE_DISPLAYPORT:
       case DISPLAY_CONNECTION_TYPE_DVI:
       case DISPLAY_CONNECTION_TYPE_HDMI: {
         HDCPState state;
-        if (!native_display_delegate_->GetHDCPState(*display, &state))
-          return false;
+        if (!native_display_delegate_->GetHDCPState(*display, &state)) {
+          callback.Run(response);
+          return;
+        }
+
         if (state == HDCP_STATE_ENABLED)
           enabled |= CONTENT_PROTECTION_METHOD_HDCP;
         else
@@ -672,19 +694,23 @@
     uint32_t requested_mask = 0;
     if (it->second.find(display_id) != it->second.end())
       requested_mask = it->second[display_id];
-    *protection_mask = enabled & ~unfulfilled & requested_mask;
-  } else {
-    *protection_mask = 0;
+    response.protection_mask = enabled & ~unfulfilled & requested_mask;
   }
-  return true;
+
+  response.success = true;
+  response.link_mask = link_mask;
+  callback.Run(response);
 }
 
-bool DisplayConfigurator::EnableContentProtection(
+void DisplayConfigurator::EnableContentProtection(
     ContentProtectionClientId client_id,
     int64_t display_id,
-    uint32_t desired_method_mask) {
-  if (!configure_display_ || display_externally_controlled_)
-    return false;
+    uint32_t desired_method_mask,
+    const EnableProtectionCallback& callback) {
+  if (!configure_display_ || display_externally_controlled_) {
+    callback.Run(false);
+    return;
+  }
 
   ContentProtections protections;
   for (const auto& requests_pair : client_protection_requests_) {
@@ -698,8 +724,10 @@
   }
   protections[display_id] |= desired_method_mask;
 
-  if (!ApplyProtections(protections))
-    return false;
+  if (!ApplyProtections(protections)) {
+    callback.Run(false);
+    return;
+  }
 
   if (desired_method_mask == CONTENT_PROTECTION_METHOD_NONE) {
     if (client_protection_requests_.find(client_id) !=
@@ -712,7 +740,7 @@
     client_protection_requests_[client_id][display_id] = desired_method_mask;
   }
 
-  return true;
+  callback.Run(true);
 }
 
 std::vector<ui::ColorCalibrationProfile>
diff --git a/ui/display/chromeos/display_configurator.h b/ui/display/chromeos/display_configurator.h
index 88eab83..7c83dd2 100644
--- a/ui/display/chromeos/display_configurator.h
+++ b/ui/display/chromeos/display_configurator.h
@@ -28,7 +28,7 @@
 }
 
 namespace ui {
-struct DisplayConfigureRequest;
+class DisplayLayoutManager;
 class DisplayMode;
 class DisplaySnapshot;
 class NativeDisplayDelegate;
@@ -42,8 +42,29 @@
 
   typedef base::Callback<void(bool)> ConfigurationCallback;
 
+  typedef base::Callback<void(bool /* success */)> EnableProtectionCallback;
+
+  struct QueryProtectionResponse {
+    // True if the query succeeded, false otherwise.
+    bool success = false;
+
+    // The type of connected display links, which is a bitmask of
+    // DisplayConnectionType values.
+    uint32_t link_mask = 0;
+
+    // The desired protection methods, which is a bitmask of the
+    // ContentProtectionMethod values.
+    uint32_t protection_mask = 0;
+  };
+
+  typedef base::Callback<void(const QueryProtectionResponse&)>
+      QueryProtectionCallback;
+
   typedef std::vector<DisplaySnapshot*> DisplayStateList;
 
+  // Mapping a display_id to a protection request bitmask.
+  typedef std::map<int64_t, uint32_t> ContentProtections;
+
   class Observer {
    public:
     virtual ~Observer() {}
@@ -89,33 +110,6 @@
     virtual bool SoftwareMirroringEnabled() const = 0;
   };
 
-  class DisplayLayoutManager {
-   public:
-    virtual ~DisplayLayoutManager() {}
-
-    virtual SoftwareMirroringController* GetSoftwareMirroringController()
-        const = 0;
-
-    virtual StateController* GetStateController() const = 0;
-
-    // Returns the current display state.
-    virtual MultipleDisplayState GetDisplayState() const = 0;
-
-    // Returns the current power state.
-    virtual chromeos::DisplayPowerState GetPowerState() const = 0;
-
-    // Based on the given |displays|, display state and power state, it will
-    // create display configuration requests which will then be used to
-    // configure the hardware. The requested configuration is stored in
-    // |requests| and |framebuffer_size|.
-    virtual bool GetDisplayLayout(
-        const std::vector<DisplaySnapshot*>& displays,
-        MultipleDisplayState new_display_state,
-        chromeos::DisplayPowerState new_power_state,
-        std::vector<DisplayConfigureRequest>* requests,
-        gfx::Size* framebuffer_size) const = 0;
-  };
-
   // Helper class used by tests.
   class TestApi {
    public:
@@ -240,23 +234,20 @@
   // Unregisters the client.
   void UnregisterContentProtectionClient(ContentProtectionClientId client_id);
 
-  // Queries link status and protection status.
-  // |link_mask| is the type of connected display links, which is a bitmask of
-  // DisplayConnectionType values. |protection_mask| is the desired protection
-  // methods, which is a bitmask of the ContentProtectionMethod values.
-  // Returns true on success.
-  bool QueryContentProtectionStatus(ContentProtectionClientId client_id,
+  // Queries link status and protection status. |callback| is used to respond
+  // to the query.
+  void QueryContentProtectionStatus(ContentProtectionClientId client_id,
                                     int64_t display_id,
-                                    uint32_t* link_mask,
-                                    uint32_t* protection_mask);
+                                    const QueryProtectionCallback& callback);
 
   // Requests the desired protection methods.
   // |protection_mask| is the desired protection methods, which is a bitmask
   // of the ContentProtectionMethod values.
   // Returns true when the protection request has been made.
-  bool EnableContentProtection(ContentProtectionClientId client_id,
+  void EnableContentProtection(ContentProtectionClientId client_id,
                                int64_t display_id,
-                               uint32_t desired_protection_mask);
+                               uint32_t protection_mask,
+                               const EnableProtectionCallback& callback);
 
   // Checks the available color profiles for |display_id| and fills the result
   // into |profiles|.
@@ -270,8 +261,6 @@
  private:
   class DisplayLayoutManagerImpl;
 
-  // Mapping a display_id to a protection request bitmask.
-  typedef std::map<int64_t, uint32_t> ContentProtections;
   // Mapping a client to its protection request.
   typedef std::map<ContentProtectionClientId, ContentProtections>
       ProtectionRequests;
diff --git a/ui/display/chromeos/display_configurator_unittest.cc b/ui/display/chromeos/display_configurator_unittest.cc
index f819184c..9000af6 100644
--- a/ui/display/chromeos/display_configurator_unittest.cc
+++ b/ui/display/chromeos/display_configurator_unittest.cc
@@ -125,6 +125,9 @@
         big_mode_(gfx::Size(2560, 1600), false, 60.0f),
         observer_(&configurator_),
         test_api_(&configurator_),
+        enable_content_protection_status_(0),
+        enable_content_protection_call_count_(0),
+        query_content_protection_call_count_(0),
         callback_result_(CALLBACK_NOT_CALLED) {}
   ~DisplayConfiguratorTest() override {}
 
@@ -165,6 +168,17 @@
     callback_result_ = (status ? CALLBACK_SUCCESS : CALLBACK_FAILURE);
   }
 
+  void EnableContentProtectionCallback(bool status) {
+    enable_content_protection_status_ = status;
+    enable_content_protection_call_count_++;
+  }
+
+  void QueryContentProtectionCallback(
+      const DisplayConfigurator::QueryProtectionResponse& response) {
+    query_content_protection_response_ = response;
+    query_content_protection_call_count_++;
+  }
+
   // Predefined modes that can be used by outputs.
   const DisplayMode small_mode_;
   const DisplayMode big_mode_;
@@ -219,6 +233,12 @@
   TestNativeDisplayDelegate* native_display_delegate_;  // not owned
   DisplayConfigurator::TestApi test_api_;
 
+  bool enable_content_protection_status_;
+  int enable_content_protection_call_count_;
+  DisplayConfigurator::QueryProtectionResponse
+      query_content_protection_response_;
+  int query_content_protection_call_count_;
+
   TestDisplaySnapshot outputs_[2];
 
   CallbackResult callback_result_;
@@ -937,37 +957,54 @@
   // One output.
   UpdateOutputs(1, true);
   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
-  uint32_t link_mask = 0;
-  uint32_t protection_mask = 0;
-  EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
-      id, outputs_[0].display_id(), &link_mask, &protection_mask));
-  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL), link_mask);
+  configurator_.QueryContentProtectionStatus(
+      id, outputs_[0].display_id(),
+      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(1, query_content_protection_call_count_);
+  EXPECT_TRUE(query_content_protection_response_.success);
+  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL),
+            query_content_protection_response_.link_mask);
   EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
-            protection_mask);
+            query_content_protection_response_.protection_mask);
   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
 
   // Two outputs.
   UpdateOutputs(2, true);
   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
-  EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
-      id, outputs_[1].display_id(), &link_mask, &protection_mask));
-  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
+  configurator_.QueryContentProtectionStatus(
+      id, outputs_[1].display_id(),
+      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(2, query_content_protection_call_count_);
+  EXPECT_TRUE(query_content_protection_response_.success);
+  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
+            query_content_protection_response_.link_mask);
   EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
-            protection_mask);
+            query_content_protection_response_.protection_mask);
   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
 
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
+  configurator_.EnableContentProtection(
+      id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(1, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED),
             log_->GetActionsAndClear());
 
   // Enable protection.
   native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
-  EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
-      id, outputs_[1].display_id(), &link_mask, &protection_mask));
-  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
+  configurator_.QueryContentProtectionStatus(
+      id, outputs_[1].display_id(),
+      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(3, query_content_protection_call_count_);
+  EXPECT_TRUE(query_content_protection_response_.success);
+  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
+            query_content_protection_response_.link_mask);
   EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP),
-            protection_mask);
+            query_content_protection_response_.protection_mask);
   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
 
   // Protections should be disabled after unregister.
@@ -1086,30 +1123,53 @@
   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
 
   // Clients never know state enableness for methods that they didn't request.
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
+  configurator_.EnableContentProtection(
+      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(1, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
             log_->GetActionsAndClear());
   native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
 
-  uint32_t link_mask = 0;
-  uint32_t protection_mask = 0;
-  EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
-      client1, outputs_[1].display_id(), &link_mask, &protection_mask));
-  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
-  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask);
+  configurator_.QueryContentProtectionStatus(
+      client1, outputs_[1].display_id(),
+      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(1, query_content_protection_call_count_);
+  EXPECT_TRUE(query_content_protection_response_.success);
+  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
+            query_content_protection_response_.link_mask);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP,
+            query_content_protection_response_.protection_mask);
 
-  EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
-      client2, outputs_[1].display_id(), &link_mask, &protection_mask));
-  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
-  EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask);
+  configurator_.QueryContentProtectionStatus(
+      client2, outputs_[1].display_id(),
+      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(2, query_content_protection_call_count_);
+  EXPECT_TRUE(query_content_protection_response_.success);
+  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
+            query_content_protection_response_.link_mask);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE,
+            query_content_protection_response_.protection_mask);
 
   // Protections will be disabled only if no more clients request them.
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE));
+  configurator_.EnableContentProtection(
+      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(2, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE));
+
+  configurator_.EnableContentProtection(
+      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(3, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED).c_str(),
             log_->GetActionsAndClear());
 }
@@ -1127,20 +1187,36 @@
   log_->GetActionsAndClear();
 
   // Only enable once if HDCP is enabling.
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
+  configurator_.EnableContentProtection(
+      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(1, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   native_display_delegate_->set_hdcp_state(HDCP_STATE_DESIRED);
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
+  configurator_.EnableContentProtection(
+      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(2, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
             log_->GetActionsAndClear());
   native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
 
   // Don't enable again if HDCP is already active.
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
-  EXPECT_TRUE(configurator_.EnableContentProtection(
-      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
+  configurator_.EnableContentProtection(
+      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(3, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
+  configurator_.EnableContentProtection(
+      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
+                 base::Unretained(this)));
+  EXPECT_EQ(4, enable_content_protection_call_count_);
+  EXPECT_TRUE(enable_content_protection_status_);
   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
 }
 
diff --git a/ui/display/chromeos/display_layout_manager.h b/ui/display/chromeos/display_layout_manager.h
new file mode 100644
index 0000000..068f118
--- /dev/null
+++ b/ui/display/chromeos/display_layout_manager.h
@@ -0,0 +1,51 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_DISPLAY_CHROMEOS_DISPLAY_LAYOUT_MANAGER_H_
+#define UI_DISPLAY_CHROMEOS_DISPLAY_LAYOUT_MANAGER_H_
+
+#include <vector>
+
+#include "third_party/cros_system_api/dbus/service_constants.h"
+#include "ui/display/chromeos/display_configurator.h"
+#include "ui/display/types/display_constants.h"
+
+namespace ui {
+
+struct DisplayConfigureRequest;
+class DisplaySnapshot;
+
+class DisplayLayoutManager {
+ public:
+  virtual ~DisplayLayoutManager() {}
+
+  virtual DisplayConfigurator::SoftwareMirroringController*
+  GetSoftwareMirroringController() const = 0;
+
+  virtual DisplayConfigurator::StateController* GetStateController() const = 0;
+
+  // Returns the current display state.
+  virtual MultipleDisplayState GetDisplayState() const = 0;
+
+  // Returns the current power state.
+  virtual chromeos::DisplayPowerState GetPowerState() const = 0;
+
+  // Based on the given |displays|, display state and power state, it will
+  // create display configuration requests which will then be used to
+  // configure the hardware. The requested configuration is stored in
+  // |requests| and |framebuffer_size|.
+  virtual bool GetDisplayLayout(const std::vector<DisplaySnapshot*>& displays,
+                                MultipleDisplayState new_display_state,
+                                chromeos::DisplayPowerState new_power_state,
+                                std::vector<DisplayConfigureRequest>* requests,
+                                gfx::Size* framebuffer_size) const = 0;
+
+  virtual std::vector<DisplaySnapshot*> GetDisplayStates() const = 0;
+
+  virtual bool IsMirroring() const = 0;
+};
+
+}  // namespace ui
+
+#endif  // UI_DISPLAY_CHROMEOS_DISPLAY_LAYOUT_MANAGER_H_
diff --git a/ui/display/chromeos/query_content_protection_task.cc b/ui/display/chromeos/query_content_protection_task.cc
new file mode 100644
index 0000000..d90d55f
--- /dev/null
+++ b/ui/display/chromeos/query_content_protection_task.cc
@@ -0,0 +1,87 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/display/chromeos/query_content_protection_task.h"
+
+#include "ui/display/chromeos/display_layout_manager.h"
+#include "ui/display/types/display_snapshot.h"
+#include "ui/display/types/native_display_delegate.h"
+
+namespace ui {
+
+QueryContentProtectionTask::QueryContentProtectionTask(
+    DisplayLayoutManager* layout_manager,
+    NativeDisplayDelegate* native_display_delegate,
+    int64_t display_id,
+    const ResponseCallback& callback)
+    : layout_manager_(layout_manager),
+      native_display_delegate_(native_display_delegate),
+      display_id_(display_id),
+      callback_(callback),
+      pending_requests_(0),
+      weak_ptr_factory_(this) {
+}
+
+QueryContentProtectionTask::~QueryContentProtectionTask() {
+}
+
+void QueryContentProtectionTask::Run() {
+  std::vector<DisplaySnapshot*> hdcp_capable_displays;
+  for (DisplaySnapshot* display : layout_manager_->GetDisplayStates()) {
+    // Query display if it is in mirror mode or client on the same display.
+    if (!layout_manager_->IsMirroring() && display->display_id() != display_id_)
+      continue;
+
+    response_.link_mask |= display->type();
+
+    switch (display->type()) {
+      case DISPLAY_CONNECTION_TYPE_UNKNOWN:
+        callback_.Run(response_);
+        return;
+      case DISPLAY_CONNECTION_TYPE_DISPLAYPORT:
+      case DISPLAY_CONNECTION_TYPE_DVI:
+      case DISPLAY_CONNECTION_TYPE_HDMI:
+        hdcp_capable_displays.push_back(display);
+        break;
+      case DISPLAY_CONNECTION_TYPE_INTERNAL:
+      case DISPLAY_CONNECTION_TYPE_VGA:
+      case DISPLAY_CONNECTION_TYPE_NETWORK:
+        // No protections for these types. Do nothing.
+        break;
+      case DISPLAY_CONNECTION_TYPE_NONE:
+        NOTREACHED();
+        break;
+    }
+  }
+
+  response_.success = true;
+  pending_requests_ = hdcp_capable_displays.size();
+  if (pending_requests_ != 0) {
+    for (DisplaySnapshot* display : hdcp_capable_displays) {
+      native_display_delegate_->GetHDCPState(
+          *display, base::Bind(&QueryContentProtectionTask::OnHDCPStateUpdate,
+                               weak_ptr_factory_.GetWeakPtr()));
+    }
+  } else {
+    callback_.Run(response_);
+  }
+}
+
+void QueryContentProtectionTask::OnHDCPStateUpdate(bool success,
+                                                   HDCPState state) {
+  response_.success &= success;
+  if (state == HDCP_STATE_ENABLED)
+    response_.enabled |= CONTENT_PROTECTION_METHOD_HDCP;
+  else
+    response_.unfulfilled |= CONTENT_PROTECTION_METHOD_HDCP;
+
+  pending_requests_--;
+  // Wait for all the requests to finish before invoking the callback.
+  if (pending_requests_ != 0)
+    return;
+
+  callback_.Run(response_);
+}
+
+}  // namespace ui
diff --git a/ui/display/chromeos/query_content_protection_task.h b/ui/display/chromeos/query_content_protection_task.h
new file mode 100644
index 0000000..863b286
--- /dev/null
+++ b/ui/display/chromeos/query_content_protection_task.h
@@ -0,0 +1,64 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_DISPLAY_CHROMEOS_QUERY_CONTENT_PROTECTION_TASK_H_
+#define UI_DISPLAY_CHROMEOS_QUERY_CONTENT_PROTECTION_TASK_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/display/display_export.h"
+#include "ui/display/types/display_constants.h"
+
+namespace ui {
+
+class DisplayLayoutManager;
+class NativeDisplayDelegate;
+
+class DISPLAY_EXPORT QueryContentProtectionTask {
+ public:
+  struct Response {
+    bool success = false;
+    uint32_t link_mask = 0;
+    uint32_t enabled = 0;
+    uint32_t unfulfilled = 0;
+  };
+
+  typedef base::Callback<void(Response)> ResponseCallback;
+
+  QueryContentProtectionTask(DisplayLayoutManager* layout_manager,
+                             NativeDisplayDelegate* native_display_delegate,
+                             int64_t display_id,
+                             const ResponseCallback& callback);
+  ~QueryContentProtectionTask();
+
+  void Run();
+
+ private:
+  // Callback for NativeDisplayDelegate::GetHDCPState()
+  void OnHDCPStateUpdate(bool success, HDCPState state);
+
+  DisplayLayoutManager* layout_manager_;  // Not owned.
+
+  NativeDisplayDelegate* native_display_delegate_;  // Not owned.
+
+  // Display ID for the query.
+  int64_t display_id_;
+
+  // Called at the end of the query to signal completion.
+  ResponseCallback callback_;
+
+  Response response_;
+
+  // Tracks the number of NativeDisplayDelegate requests sent but not answered
+  // yet.
+  size_t pending_requests_;
+
+  base::WeakPtrFactory<QueryContentProtectionTask> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(QueryContentProtectionTask);
+};
+
+}  // namespace ui
+
+#endif  // UI_DISPLAY_CHROMEOS_QUERY_CONTENT_PROTECTION_TASK_H_
diff --git a/ui/display/chromeos/query_content_protection_task_unittest.cc b/ui/display/chromeos/query_content_protection_task_unittest.cc
new file mode 100644
index 0000000..2cd2cb2
--- /dev/null
+++ b/ui/display/chromeos/query_content_protection_task_unittest.cc
@@ -0,0 +1,191 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/chromeos/display_layout_manager.h"
+#include "ui/display/chromeos/query_content_protection_task.h"
+#include "ui/display/chromeos/test/action_logger_util.h"
+#include "ui/display/chromeos/test/test_display_layout_manager.h"
+#include "ui/display/chromeos/test/test_display_snapshot.h"
+#include "ui/display/chromeos/test/test_native_display_delegate.h"
+
+namespace ui {
+namespace test {
+
+namespace {
+
+scoped_ptr<DisplaySnapshot> CreateDisplaySnapshot(int64_t id,
+                                                  DisplayConnectionType type) {
+  scoped_ptr<TestDisplaySnapshot> display(new TestDisplaySnapshot());
+  display->set_display_id(id);
+  display->set_type(type);
+
+  return display.Pass();
+}
+
+}  // namespace
+
+class QueryContentProtectionTaskTest : public testing::Test {
+ public:
+  QueryContentProtectionTaskTest()
+      : display_delegate_(&log_), has_response_(false) {}
+  ~QueryContentProtectionTaskTest() override {}
+
+  void ResponseCallback(QueryContentProtectionTask::Response response) {
+    has_response_ = true;
+    response_ = response;
+  }
+
+ protected:
+  ActionLogger log_;
+  TestNativeDisplayDelegate display_delegate_;
+
+  bool has_response_;
+  QueryContentProtectionTask::Response response_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(QueryContentProtectionTaskTest);
+};
+
+TEST_F(QueryContentProtectionTaskTest, QueryWithNoHDCPCapableDisplay) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(
+      CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_INTERNAL));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_TRUE(response_.success);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_INTERNAL, response_.link_mask);
+  EXPECT_EQ(0u, response_.enabled);
+  EXPECT_EQ(0u, response_.unfulfilled);
+}
+
+TEST_F(QueryContentProtectionTaskTest, QueryWithUnknownDisplay) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_UNKNOWN));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_FALSE(response_.success);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_UNKNOWN, response_.link_mask);
+  EXPECT_EQ(0u, response_.enabled);
+  EXPECT_EQ(0u, response_.unfulfilled);
+}
+
+TEST_F(QueryContentProtectionTaskTest, FailQueryWithHDMIDisplay) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+  display_delegate_.set_get_hdcp_state_expectation(false);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_FALSE(response_.success);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, response_.link_mask);
+}
+
+TEST_F(QueryContentProtectionTaskTest, QueryWithHDMIDisplayAndUnfulfilled) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_TRUE(response_.success);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, response_.link_mask);
+  EXPECT_EQ(0u, response_.enabled);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, response_.unfulfilled);
+}
+
+TEST_F(QueryContentProtectionTaskTest, QueryWithHDMIDisplayAndFulfilled) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_SINGLE);
+  display_delegate_.set_hdcp_state(HDCP_STATE_ENABLED);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_TRUE(response_.success);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, response_.link_mask);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, response_.enabled);
+  EXPECT_EQ(0u, response_.unfulfilled);
+}
+
+TEST_F(QueryContentProtectionTaskTest, QueryWith2HDCPDisplays) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  displays.push_back(CreateDisplaySnapshot(2, DISPLAY_CONNECTION_TYPE_DVI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_TRUE(response_.success);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, response_.link_mask);
+  EXPECT_EQ(0u, response_.enabled);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, response_.unfulfilled);
+}
+
+TEST_F(QueryContentProtectionTaskTest, QueryWithMirrorHDCPDisplays) {
+  ScopedVector<DisplaySnapshot> displays;
+  displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI));
+  displays.push_back(CreateDisplaySnapshot(2, DISPLAY_CONNECTION_TYPE_DVI));
+  TestDisplayLayoutManager layout_manager(displays.Pass(),
+                                          MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
+
+  QueryContentProtectionTask task(
+      &layout_manager, &display_delegate_, 1,
+      base::Bind(&QueryContentProtectionTaskTest::ResponseCallback,
+                 base::Unretained(this)));
+  task.Run();
+
+  EXPECT_TRUE(has_response_);
+  EXPECT_TRUE(response_.success);
+  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI |
+                                  DISPLAY_CONNECTION_TYPE_DVI),
+            response_.link_mask);
+  EXPECT_EQ(0u, response_.enabled);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, response_.unfulfilled);
+}
+
+}  // namespace test
+}  // namespace ui
diff --git a/ui/display/chromeos/test/test_display_layout_manager.cc b/ui/display/chromeos/test/test_display_layout_manager.cc
new file mode 100644
index 0000000..2494c9b
--- /dev/null
+++ b/ui/display/chromeos/test/test_display_layout_manager.cc
@@ -0,0 +1,60 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/display/chromeos/test/test_display_layout_manager.h"
+
+#include "ui/display/types/display_snapshot.h"
+
+namespace ui {
+namespace test {
+
+TestDisplayLayoutManager::TestDisplayLayoutManager(
+    ScopedVector<DisplaySnapshot> displays,
+    MultipleDisplayState display_state)
+    : displays_(displays.Pass()), display_state_(display_state) {
+}
+
+TestDisplayLayoutManager::~TestDisplayLayoutManager() {
+}
+
+DisplayConfigurator::StateController*
+TestDisplayLayoutManager::GetStateController() const {
+  return nullptr;
+}
+
+DisplayConfigurator::SoftwareMirroringController*
+TestDisplayLayoutManager::GetSoftwareMirroringController() const {
+  return nullptr;
+}
+
+MultipleDisplayState TestDisplayLayoutManager::GetDisplayState() const {
+  return display_state_;
+}
+
+chromeos::DisplayPowerState TestDisplayLayoutManager::GetPowerState() const {
+  NOTREACHED();
+  return chromeos::DISPLAY_POWER_ALL_ON;
+}
+
+bool TestDisplayLayoutManager::GetDisplayLayout(
+    const std::vector<DisplaySnapshot*>& displays,
+    MultipleDisplayState new_display_state,
+    chromeos::DisplayPowerState new_power_state,
+    std::vector<DisplayConfigureRequest>* requests,
+    gfx::Size* framebuffer_size) const {
+  NOTREACHED();
+  return false;
+}
+
+std::vector<DisplaySnapshot*> TestDisplayLayoutManager::GetDisplayStates()
+    const {
+  return displays_.get();
+}
+
+bool TestDisplayLayoutManager::IsMirroring() const {
+  return display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR;
+}
+
+}  // namespace test
+}  // namespace ui
diff --git a/ui/display/chromeos/test/test_display_layout_manager.h b/ui/display/chromeos/test/test_display_layout_manager.h
new file mode 100644
index 0000000..c46f850
--- /dev/null
+++ b/ui/display/chromeos/test/test_display_layout_manager.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_DISPLAY_CHROMEOS_TEST_TEST_DISPLAY_LAYOUT_MANAGER_H_
+#define UI_DISPLAY_CHROMEOS_TEST_TEST_DISPLAY_LAYOUT_MANAGER_H_
+
+#include "base/memory/scoped_vector.h"
+#include "ui/display/chromeos/display_configurator.h"
+#include "ui/display/chromeos/display_layout_manager.h"
+
+namespace ui {
+namespace test {
+
+class TestDisplayLayoutManager : public DisplayLayoutManager {
+ public:
+  TestDisplayLayoutManager(ScopedVector<DisplaySnapshot> displays,
+                           MultipleDisplayState display_state);
+  ~TestDisplayLayoutManager() override;
+
+  // DisplayLayoutManager:
+  DisplayConfigurator::StateController* GetStateController() const override;
+  DisplayConfigurator::SoftwareMirroringController*
+  GetSoftwareMirroringController() const override;
+  MultipleDisplayState GetDisplayState() const override;
+  chromeos::DisplayPowerState GetPowerState() const override;
+  bool GetDisplayLayout(const std::vector<DisplaySnapshot*>& displays,
+                        MultipleDisplayState new_display_state,
+                        chromeos::DisplayPowerState new_power_state,
+                        std::vector<DisplayConfigureRequest>* requests,
+                        gfx::Size* framebuffer_size) const override;
+  std::vector<DisplaySnapshot*> GetDisplayStates() const override;
+  bool IsMirroring() const override;
+
+ private:
+  ScopedVector<DisplaySnapshot> displays_;
+  MultipleDisplayState display_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestDisplayLayoutManager);
+};
+
+}  // namespace test
+}  // namespace ui
+
+#endif  // UI_DISPLAY_CHROMEOS_TEST_TEST_DISPLAY_LAYOUT_MANAGER_H_
diff --git a/ui/display/chromeos/test/test_native_display_delegate.cc b/ui/display/chromeos/test/test_native_display_delegate.cc
index 0da2e11..5533961 100644
--- a/ui/display/chromeos/test/test_native_display_delegate.cc
+++ b/ui/display/chromeos/test/test_native_display_delegate.cc
@@ -14,6 +14,8 @@
 
 TestNativeDisplayDelegate::TestNativeDisplayDelegate(ActionLogger* log)
     : max_configurable_pixels_(0),
+      get_hdcp_expectation_(true),
+      set_hdcp_expectation_(true),
       hdcp_state_(HDCP_STATE_UNDESIRED),
       run_async_(false),
       log_(log) {
@@ -107,13 +109,27 @@
 bool TestNativeDisplayDelegate::GetHDCPState(const DisplaySnapshot& output,
                                              HDCPState* state) {
   *state = hdcp_state_;
-  return true;
+  return get_hdcp_expectation_;
+}
+
+void TestNativeDisplayDelegate::GetHDCPState(
+    const DisplaySnapshot& output,
+    const GetHDCPStateCallback& callback) {
+  callback.Run(get_hdcp_expectation_, hdcp_state_);
 }
 
 bool TestNativeDisplayDelegate::SetHDCPState(const DisplaySnapshot& output,
                                              HDCPState state) {
   log_->AppendAction(GetSetHDCPStateAction(output, state));
-  return true;
+  return set_hdcp_expectation_;
+}
+
+void TestNativeDisplayDelegate::SetHDCPState(
+    const DisplaySnapshot& output,
+    HDCPState state,
+    const SetHDCPStateCallback& callback) {
+  log_->AppendAction(GetSetHDCPStateAction(output, state));
+  callback.Run(set_hdcp_expectation_);
 }
 
 std::vector<ui::ColorCalibrationProfile>
diff --git a/ui/display/chromeos/test/test_native_display_delegate.h b/ui/display/chromeos/test/test_native_display_delegate.h
index eac789e1..a3ed4c64 100644
--- a/ui/display/chromeos/test/test_native_display_delegate.h
+++ b/ui/display/chromeos/test/test_native_display_delegate.h
@@ -35,6 +35,14 @@
     max_configurable_pixels_ = pixels;
   }
 
+  void set_get_hdcp_state_expectation(bool success) {
+    get_hdcp_expectation_ = success;
+  }
+
+  void set_set_hdcp_state_expectation(bool success) {
+    set_hdcp_expectation_ = success;
+  }
+
   void set_hdcp_state(HDCPState state) { hdcp_state_ = state; }
 
   void set_run_async(bool run_async) { run_async_ = run_async; }
@@ -57,6 +65,11 @@
   void CreateFrameBuffer(const gfx::Size& size) override;
   bool GetHDCPState(const DisplaySnapshot& output, HDCPState* state) override;
   bool SetHDCPState(const DisplaySnapshot& output, HDCPState state) override;
+  void GetHDCPState(const DisplaySnapshot& output,
+                    const GetHDCPStateCallback& callback) override;
+  void SetHDCPState(const DisplaySnapshot& output,
+                    HDCPState state,
+                    const SetHDCPStateCallback& callback) override;
   std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
       const DisplaySnapshot& output) override;
   bool SetColorCalibrationProfile(
@@ -81,6 +94,9 @@
   // return success regardless of the resolution.
   int max_configurable_pixels_;
 
+  bool get_hdcp_expectation_;
+  bool set_hdcp_expectation_;
+
   // Result value of GetHDCPState().
   HDCPState hdcp_state_;
 
diff --git a/ui/display/chromeos/update_display_configuration_task.cc b/ui/display/chromeos/update_display_configuration_task.cc
index 2db4422..7b254fc 100644
--- a/ui/display/chromeos/update_display_configuration_task.cc
+++ b/ui/display/chromeos/update_display_configuration_task.cc
@@ -5,6 +5,7 @@
 #include "ui/display/chromeos/update_display_configuration_task.h"
 
 #include "ui/display/chromeos/configure_displays_task.h"
+#include "ui/display/chromeos/display_layout_manager.h"
 #include "ui/display/chromeos/display_util.h"
 #include "ui/display/types/display_snapshot.h"
 #include "ui/display/types/native_display_delegate.h"
@@ -13,7 +14,7 @@
 
 UpdateDisplayConfigurationTask::UpdateDisplayConfigurationTask(
     NativeDisplayDelegate* delegate,
-    DisplayConfigurator::DisplayLayoutManager* layout_manager,
+    DisplayLayoutManager* layout_manager,
     MultipleDisplayState new_display_state,
     chromeos::DisplayPowerState new_power_state,
     int power_flags,
diff --git a/ui/display/chromeos/update_display_configuration_task.h b/ui/display/chromeos/update_display_configuration_task.h
index c6447db5..7b8272e 100644
--- a/ui/display/chromeos/update_display_configuration_task.h
+++ b/ui/display/chromeos/update_display_configuration_task.h
@@ -25,15 +25,14 @@
       MultipleDisplayState /* new_display_state */,
       chromeos::DisplayPowerState /* new_power_state */)> ResponseCallback;
 
-  UpdateDisplayConfigurationTask(
-      NativeDisplayDelegate* delegate,
-      DisplayConfigurator::DisplayLayoutManager* layout_manager,
-      MultipleDisplayState new_display_state,
-      chromeos::DisplayPowerState new_power_state,
-      int power_flags,
-      uint32_t background_color_argb,
-      bool force_configure,
-      const ResponseCallback& callback);
+  UpdateDisplayConfigurationTask(NativeDisplayDelegate* delegate,
+                                 DisplayLayoutManager* layout_manager,
+                                 MultipleDisplayState new_display_state,
+                                 chromeos::DisplayPowerState new_power_state,
+                                 int power_flags,
+                                 uint32_t background_color_argb,
+                                 bool force_configure,
+                                 const ResponseCallback& callback);
   ~UpdateDisplayConfigurationTask();
 
   void Run();
@@ -68,8 +67,8 @@
   // Returns a display state based on the power state.
   MultipleDisplayState ChooseDisplayState() const;
 
-  NativeDisplayDelegate* delegate_;                            // Not owned.
-  DisplayConfigurator::DisplayLayoutManager* layout_manager_;  // Not owned.
+  NativeDisplayDelegate* delegate_;       // Not owned.
+  DisplayLayoutManager* layout_manager_;  // Not owned.
 
   // Requested display state.
   MultipleDisplayState new_display_state_;
diff --git a/ui/display/chromeos/update_display_configuration_task_unittest.cc b/ui/display/chromeos/update_display_configuration_task_unittest.cc
index b8a323b..b2904c73 100644
--- a/ui/display/chromeos/update_display_configuration_task_unittest.cc
+++ b/ui/display/chromeos/update_display_configuration_task_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/chromeos/display_layout_manager.h"
 #include "ui/display/chromeos/test/action_logger_util.h"
 #include "ui/display/chromeos/test/test_display_snapshot.h"
 #include "ui/display/chromeos/test/test_native_display_delegate.h"
@@ -16,8 +17,7 @@
 
 namespace {
 
-class TestDisplayLayoutManager
-    : public DisplayConfigurator::DisplayLayoutManager {
+class TestDisplayLayoutManager : public DisplayLayoutManager {
  public:
   TestDisplayLayoutManager()
       : should_mirror_(true),
@@ -82,6 +82,15 @@
     return true;
   }
 
+  DisplayConfigurator::DisplayStateList GetDisplayStates() const override {
+    NOTREACHED();
+    return DisplayConfigurator::DisplayStateList();
+  }
+
+  bool IsMirroring() const override {
+    return display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR;
+  }
+
  private:
   const DisplayMode* FindMirrorMode(
       const std::vector<DisplaySnapshot*>& displays) const {
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc
index b5022ba..5c23e3f 100644
--- a/ui/display/chromeos/x11/native_display_delegate_x11.cc
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc
@@ -381,6 +381,14 @@
   return display_snapshot;
 }
 
+void NativeDisplayDelegateX11::GetHDCPState(
+    const DisplaySnapshot& output,
+    const GetHDCPStateCallback& callback) {
+  HDCPState state = HDCP_STATE_UNDESIRED;
+  bool success = GetHDCPState(output, &state);
+  callback.Run(success, state);
+}
+
 bool NativeDisplayDelegateX11::GetHDCPState(const DisplaySnapshot& output,
                                             HDCPState* state) {
   unsigned char* values = NULL;
@@ -440,6 +448,13 @@
   return true;
 }
 
+void NativeDisplayDelegateX11::SetHDCPState(
+    const DisplaySnapshot& output,
+    HDCPState state,
+    const SetHDCPStateCallback& callback) {
+  callback.Run(SetHDCPState(output, state));
+}
+
 bool NativeDisplayDelegateX11::SetHDCPState(const DisplaySnapshot& output,
                                             HDCPState state) {
   Atom name = XInternAtom(display_, kContentProtectionAtomName, False);
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.h b/ui/display/chromeos/x11/native_display_delegate_x11.h
index 1d7d42a..036a121 100644
--- a/ui/display/chromeos/x11/native_display_delegate_x11.h
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.h
@@ -88,6 +88,11 @@
   void CreateFrameBuffer(const gfx::Size& size) override;
   bool GetHDCPState(const DisplaySnapshot& output, HDCPState* state) override;
   bool SetHDCPState(const DisplaySnapshot& output, HDCPState state) override;
+  void GetHDCPState(const DisplaySnapshot& output,
+                    const GetHDCPStateCallback& callback) override;
+  void SetHDCPState(const DisplaySnapshot& output,
+                    HDCPState state,
+                    const SetHDCPStateCallback& callback) override;
   std::vector<ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
       const DisplaySnapshot& output) override;
   bool SetColorCalibrationProfile(const DisplaySnapshot& output,
diff --git a/ui/display/display.gyp b/ui/display/display.gyp
index ad17901..e8f45f7 100644
--- a/ui/display/display.gyp
+++ b/ui/display/display.gyp
@@ -45,13 +45,18 @@
       ],
       'sources': [
         # Note: file list duplicated in GN build.
+        'chromeos/apply_content_protection_task.cc',
+        'chromeos/apply_content_protection_task.h',
         'chromeos/configure_displays_task.cc',
         'chromeos/configure_displays_task.h',
         'chromeos/display_configurator.cc',
         'chromeos/display_configurator.h',
+        'chromeos/display_layout_manager.h',
         'chromeos/display_util.cc',
         'chromeos/display_util.h',
         'chromeos/ozone/display_configurator_ozone.cc',
+        'chromeos/query_content_protection_task.cc',
+        'chromeos/query_content_protection_task.h',
         'chromeos/update_display_configuration_task.cc',
         'chromeos/update_display_configuration_task.h',
         'chromeos/x11/display_configurator_x11.cc',
@@ -173,6 +178,8 @@
         'chromeos/test/action_logger.h',
         'chromeos/test/action_logger_util.cc',
         'chromeos/test/action_logger_util.h',
+        'chromeos/test/test_display_layout_manager.cc',
+        'chromeos/test/test_display_layout_manager.h',
         'chromeos/test/test_native_display_delegate.cc',
         'chromeos/test/test_native_display_delegate.h',
       ],
@@ -191,8 +198,10 @@
         '../..',
       ],
       'sources': [
+        'chromeos/apply_content_protection_task_unittest.cc',
         'chromeos/configure_displays_task_unittest.cc',
         'chromeos/display_configurator_unittest.cc',
+        'chromeos/query_content_protection_task_unittest.cc',
         'chromeos/update_display_configuration_task_unittest.cc',
         'chromeos/x11/display_util_x11_unittest.cc',
         'chromeos/x11/native_display_event_dispatcher_x11_unittest.cc',
diff --git a/ui/display/types/native_display_delegate.h b/ui/display/types/native_display_delegate.h
index 9019b71..aff8feb 100644
--- a/ui/display/types/native_display_delegate.h
+++ b/ui/display/types/native_display_delegate.h
@@ -27,6 +27,8 @@
 typedef base::Callback<void(const std::vector<ui::DisplaySnapshot*>&)>
     GetDisplaysCallback;
 typedef base::Callback<void(bool)> ConfigureCallback;
+typedef base::Callback<void(bool, ui::HDCPState)> GetHDCPStateCallback;
+typedef base::Callback<void(bool)> SetHDCPStateCallback;
 
 // Interface for classes that perform display configuration actions on behalf
 // of DisplayConfigurator.
@@ -81,10 +83,15 @@
   // Gets HDCP state of output.
   virtual bool GetHDCPState(const ui::DisplaySnapshot& output,
                             ui::HDCPState* state) = 0;
+  virtual void GetHDCPState(const ui::DisplaySnapshot& output,
+                            const GetHDCPStateCallback& callback) = 0;
 
   // Sets HDCP state of output.
   virtual bool SetHDCPState(const ui::DisplaySnapshot& output,
                             ui::HDCPState state) = 0;
+  virtual void SetHDCPState(const ui::DisplaySnapshot& output,
+                            ui::HDCPState state,
+                            const SetHDCPStateCallback& callback) = 0;
 
   // Gets the available list of color calibrations.
   virtual std::vector<ui::ColorCalibrationProfile>
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn
index 22f49b6..208cc183 100644
--- a/ui/events/BUILD.gn
+++ b/ui/events/BUILD.gn
@@ -33,6 +33,7 @@
     "gesture_event_details.h",
     "gestures/fling_curve.cc",
     "gestures/fling_curve.h",
+    "keycodes/dom_us_layout_data.h",
     "keycodes/keyboard_code_conversion.cc",
     "keycodes/keyboard_code_conversion.h",
     "keycodes/keyboard_code_conversion_android.cc",
@@ -297,6 +298,7 @@
     "gestures/blink/web_gesture_curve_impl_unittest.cc",
     "gestures/fling_curve_unittest.cc",
     "keycodes/dom4/keycode_converter_unittest.cc",
+    "keycodes/keyboard_code_conversion_unittest.cc",
     "latency_info_unittest.cc",
     "platform/platform_event_source_unittest.cc",
     "x/events_x_unittest.cc",
diff --git a/ui/events/cocoa/events_mac.mm b/ui/events/cocoa/events_mac.mm
index 64eb972e..e68c755 100644
--- a/ui/events/cocoa/events_mac.mm
+++ b/ui/events/cocoa/events_mac.mm
@@ -128,6 +128,8 @@
     case NSOtherMouseUp:
     case NSOtherMouseDragged:
       return EF_MIDDLE_MOUSE_BUTTON;
+    default:
+      break;
   }
   return 0;
 }
diff --git a/ui/events/event.cc b/ui/events/event.cc
index 54440199..4649e24d 100644
--- a/ui/events/event.cc
+++ b/ui/events/event.cc
@@ -697,7 +697,7 @@
                    int flags)
     : Event(type, EventTimeForNow(), flags),
       key_code_(key_code),
-      code_(DomCode::NONE),
+      code_(UsLayoutKeyboardCodeToDomCode(key_code)),
       is_char_(false),
       platform_keycode_(0),
       key_(DomKey::NONE),
@@ -786,34 +786,49 @@
     key_ = DomKey::UNIDENTIFIED;
     return;
   }
+  ui::DomCode code = code_;
+  if (code == DomCode::NONE) {
+    // Catch old code that tries to do layout without a physical key, and try
+    // to recover using the KeyboardCode. Once key events are fully defined
+    // on construction (see TODO in event.h) this will go away.
+    LOG(WARNING) << "DomCode::NONE keycode=" << key_code_;
+    code = UsLayoutKeyboardCodeToDomCode(key_code_);
+    if (code == DomCode::NONE) {
+      key_ = DomKey::UNIDENTIFIED;
+      return;
+    }
+  }
+  KeyboardCode dummy_key_code;
 #if defined(OS_WIN)
-  // Native Windows character events always have is_char_ == true,
-  // so this is a synthetic or native keystroke event.
-  // Therefore, perform only the fallback action.
-  GetMeaningFromKeyCode(key_code_, flags(), &key_, &character_);
+// Native Windows character events always have is_char_ == true,
+// so this is a synthetic or native keystroke event.
+// Therefore, perform only the fallback action.
 #elif defined(USE_X11)
   // When a control key is held, prefer ASCII characters to non ASCII
   // characters in order to use it for shortcut keys.  GetCharacterFromKeyCode
   // returns 'a' for VKEY_A even if the key is actually bound to 'à' in X11.
   // GetCharacterFromXEvent returns 'à' in that case.
-  character_ = (IsControlDown() || !native_event()) ?
-      GetCharacterFromKeyCode(key_code_, flags()) :
-      GetCharacterFromXEvent(native_event());
-  // TODO(kpschoedel): set key_ field for X11.
+  if (!IsControlDown() && native_event()) {
+    character_ = GetCharacterFromXEvent(native_event());
+    // TODO(kpschoedel): set key_ field for X11.
+    return;
+  }
 #elif defined(USE_OZONE)
-  KeyboardCode key_code;
-  if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup(
-      code_, flags(), &key_, &character_, &key_code, &platform_keycode_)) {
-    GetMeaningFromKeyCode(key_code_, flags(), &key_, &character_);
+  if (KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup(
+          code, flags(), &key_, &character_, &dummy_key_code,
+          &platform_keycode_)) {
+    return;
   }
 #else
   if (native_event()) {
     DCHECK(EventTypeFromNative(native_event()) == ET_KEY_PRESSED ||
            EventTypeFromNative(native_event()) == ET_KEY_RELEASED);
   }
-  // TODO(kpschoedel): revise to use DOM code_ instead of Windows key_code_
-  GetMeaningFromKeyCode(key_code_, flags(), &key_, &character_);
 #endif
+  if (!DomCodeToUsLayoutMeaning(code, flags(), &key_, &character_,
+                                &dummy_key_code)) {
+    key_ = DomKey::UNIDENTIFIED;
+  }
 }
 
 DomKey KeyEvent::GetDomKey() const {
@@ -832,9 +847,11 @@
 
 base::char16 KeyEvent::GetText() const {
   if ((flags() & EF_CONTROL_DOWN) != 0) {
-    // TODO(kpschoedel): revise to use DOM code_ instead of Windows key_code_
-    return GetControlCharacterForKeycode(key_code_,
-                                         (flags() & EF_SHIFT_DOWN) != 0);
+    base::char16 character;
+    ui::DomKey key;
+    ui::KeyboardCode key_code;
+    if (DomCodeToControlCharacter(code_, flags(), &key, &character, &key_code))
+      return character;
   }
   return GetUnmodifiedText();
 }
diff --git a/ui/events/event.h b/ui/events/event.h
index 6a27b0e9..349ed55c 100644
--- a/ui/events/event.h
+++ b/ui/events/event.h
@@ -779,7 +779,7 @@
   // TODO(kpschoedel): refactor so that key_ and character_ are not mutable.
   // This requires defining the KeyEvent completely at construction rather
   // than lazily under GetCharacter(), which likely also means removing
-  // the two 'incomplete' constructors.
+  // the two 'incomplete' constructors. crbug.com/444045
   //
   // DOM KeyboardEvent |key|
   // http://www.w3.org/TR/DOM-Level-3-Events-key/
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc
index 1297f30..6d94812 100644
--- a/ui/events/event_unittest.cc
+++ b/ui/events/event_unittest.cc
@@ -367,11 +367,10 @@
     EXPECT_EQ(kCodeForSpace, key.GetCodeString());
   }
   {
-    // If the synthetic event is initialized without code, it returns
-    // an empty string.
-    // TODO(komatsu): Fill a fallback value assuming the US keyboard layout.
+    // If the synthetic event is initialized without code, the code is
+    // determined from the KeyboardCode assuming a US keyboard layout.
     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
-    EXPECT_TRUE(key.GetCodeString().empty());
+    EXPECT_EQ(kCodeForSpace, key.GetCodeString());
   }
 #if defined(USE_X11)
   {
diff --git a/ui/events/event_utils.cc b/ui/events/event_utils.cc
index 2e3517e..021ac27 100644
--- a/ui/events/event_utils.cc
+++ b/ui/events/event_utils.cc
@@ -63,51 +63,6 @@
   return event.Pass();
 }
 
-// From third_party/WebKit/Source/web/gtk/WebInputEventFactory.cpp:
-base::char16 GetControlCharacterForKeycode(int windows_key_code, bool shift) {
-  if (windows_key_code >= ui::VKEY_A &&
-    windows_key_code <= ui::VKEY_Z) {
-    // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A
-    return windows_key_code - ui::VKEY_A + 1;
-  }
-  if (shift) {
-    // following graphics chars require shift key to input.
-    switch (windows_key_code) {
-      // ctrl-@ maps to \x00 (Null byte)
-      case ui::VKEY_2:
-        return 0;
-      // ctrl-^ maps to \x1E (Record separator, Information separator two)
-      case ui::VKEY_6:
-        return 0x1E;
-      // ctrl-_ maps to \x1F (Unit separator, Information separator one)
-      case ui::VKEY_OEM_MINUS:
-        return 0x1F;
-      // Returns 0 for all other keys to avoid inputting unexpected chars.
-      default:
-        break;
-    }
-  } else {
-    switch (windows_key_code) {
-      // ctrl-[ maps to \x1B (Escape)
-      case ui::VKEY_OEM_4:
-        return 0x1B;
-      // ctrl-\ maps to \x1C (File separator, Information separator four)
-      case ui::VKEY_OEM_5:
-        return 0x1C;
-      // ctrl-] maps to \x1D (Group separator, Information separator three)
-      case ui::VKEY_OEM_6:
-        return 0x1D;
-      // ctrl-Enter maps to \x0A (Line feed)
-      case ui::VKEY_RETURN:
-        return 0x0A;
-      // Returns 0 for all other keys to avoid inputting unexpected chars.
-      default:
-        break;
-    }
-  }
-  return 0;
-}
-
 int RegisterCustomEventType() {
   return ++g_custom_event_types;
 }
diff --git a/ui/events/event_utils.h b/ui/events/event_utils.h
index 1649bd7..e9c9093a 100644
--- a/ui/events/event_utils.h
+++ b/ui/events/event_utils.h
@@ -84,14 +84,11 @@
 // keyboard) from a native event.
 EVENTS_EXPORT DomCode CodeFromNative(const base::NativeEvent& native_event);
 
-// Returns the platform related key code. For X11, it is xksym value.
+// Returns the platform related key code (interpretation, not scan code).
+// For X11 and xkbcommon, this is the KeySym value.
 EVENTS_EXPORT uint32 PlatformKeycodeFromNative(
     const base::NativeEvent& native_event);
 
-// Returns a control character sequences from a |windows_key_code|.
-EVENTS_EXPORT base::char16 GetControlCharacterForKeycode(int windows_key_code,
-                                                         bool shift);
-
 // Returns true if the keyboard event is a character event rather than
 // a keystroke event.
 EVENTS_EXPORT bool IsCharFromNative(const base::NativeEvent& native_event);
diff --git a/ui/events/events.gyp b/ui/events/events.gyp
index 9e63434b..2f5757b 100644
--- a/ui/events/events.gyp
+++ b/ui/events/events.gyp
@@ -52,6 +52,7 @@
         'gesture_event_details.h',
         'gestures/fling_curve.cc',
         'gestures/fling_curve.h',
+        'keycodes/dom_us_layout_data.h',
         'keycodes/keyboard_code_conversion.cc',
         'keycodes/keyboard_code_conversion.h',
         'keycodes/keyboard_code_conversion_android.cc',
@@ -373,6 +374,7 @@
         'gestures/gesture_provider_aura_unittest.cc',
         'gestures/motion_event_aura_unittest.cc',
         'keycodes/dom4/keycode_converter_unittest.cc',
+        'keycodes/keyboard_code_conversion_unittest.cc',
         'latency_info_unittest.cc',
         'platform/platform_event_source_unittest.cc',
         'x/events_x_unittest.cc',
diff --git a/ui/events/ipc/latency_info_param_traits.h b/ui/events/ipc/latency_info_param_traits.h
index 289ecb4..e33a044 100644
--- a/ui/events/ipc/latency_info_param_traits.h
+++ b/ui/events/ipc/latency_info_param_traits.h
@@ -33,6 +33,7 @@
   IPC_STRUCT_TRAITS_MEMBER(input_coordinates_size)
   IPC_STRUCT_TRAITS_MEMBER(input_coordinates[0])
   IPC_STRUCT_TRAITS_MEMBER(input_coordinates[1])
+  IPC_STRUCT_TRAITS_MEMBER(trace_name)
 IPC_STRUCT_TRAITS_END()
 
 #endif // UI_EVENTS_IPC_LATENCY_INFO_PARAM_TRAITS_H_
diff --git a/ui/events/keycodes/dom4/keycode_converter.cc b/ui/events/keycodes/dom4/keycode_converter.cc
index 7c81862..d9a26a2 100644
--- a/ui/events/keycodes/dom4/keycode_converter.cc
+++ b/ui/events/keycodes/dom4/keycode_converter.cc
@@ -4,6 +4,7 @@
 
 #include "ui/events/keycodes/dom4/keycode_converter.h"
 
+#include "base/logging.h"
 #include "ui/events/keycodes/dom3/dom_code.h"
 #include "ui/events/keycodes/dom3/dom_key.h"
 
@@ -118,14 +119,17 @@
 
 // static
 DomCode KeycodeConverter::CodeStringToDomCode(const char* code) {
-  if (!code || !*code)
+  if (!code || !*code) {
+    LOG(WARNING) << "empty code string";
     return DomCode::NONE;
+  }
   for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
     if (usb_keycode_map[i].code &&
         strcmp(usb_keycode_map[i].code, code) == 0) {
       return static_cast<DomCode>(usb_keycode_map[i].usb_keycode);
     }
   }
+  LOG(WARNING) << "unrecognized code string '" << code << "'";
   return DomCode::NONE;
 }
 
diff --git a/ui/events/keycodes/dom4/keycode_converter_data.h b/ui/events/keycodes/dom4/keycode_converter_data.h
index 0d9fccd..2f7712ed 100644
--- a/ui/events/keycodes/dom4/keycode_converter_data.h
+++ b/ui/events/keycodes/dom4/keycode_converter_data.h
@@ -399,6 +399,12 @@
   USB_KEYMAP(0x0c0075, 0x00fc, 0x0000, 0xffff, NULL, BRIGHTNESS_AUTO),
 
   //            USB      XKB     Win     Mac
+  //USB_KEYMAP(0x0c00b0, 0x00d7, 0x????, 0x????, "MediaPlay", MEDIA_PLAY),
+  //USB_KEYMAP(0x0c00b1, 0x007f, 0x????, 0x????, "MediaPause", MEDIA_PAUSE),
+  //USB_KEYMAP(0x0c00b2, 0x00af, 0x????, 0x????, "MediaRecord", MEDIA_RECORD),
+  //USB_KEYMAP(0x0c00b3, 0x00d8, 0x????, 0x????, "MediaFastForward",
+  //           MEDIA_FAST_FORWARD),
+  //USB_KEYMAP(0x0c00b4, 0x00b0, 0x????, 0x????, "MediaRewind", MEDIA_REWIND),
   USB_KEYMAP(0x0c00b5, 0x0000, 0xe019, 0xffff, "MediaTrackNext",
              MEDIA_TRACK_NEXT),
   USB_KEYMAP(0x0c00b6, 0x0000, 0xe010, 0xffff, "MediaTrackPrevious",
@@ -441,6 +447,8 @@
   USB_KEYMAP(0x0c01b4, 0x0098, 0x0000, 0xffff, NULL, LAUNCH_FILE_BROWSER),
   // USB#0x0c01b7: AL Audio Browser
   //USB_KEYMAP(0x0c01b7, 0x0190, 0x0000, 0xffff, NULL, LAUNCH_AUDIO_BROWSER),
+  // USB#0x0c0208: AC Print
+  //USB_KEYMAP(0x0c0208, 0x00da, 0x0000, 0xffff, NULL, PRINT),
   // USB#0x0c0221:  AC_Search
   USB_KEYMAP(0x0c0221, 0x0000, 0xe065, 0xffff, "BrowserSearch", BROWSER_SEARCH),
   // USB#0x0c0223:  AC_Home
diff --git a/ui/events/keycodes/dom_us_layout_data.h b/ui/events/keycodes/dom_us_layout_data.h
new file mode 100644
index 0000000..c85aef2b
--- /dev/null
+++ b/ui/events/keycodes/dom_us_layout_data.h
@@ -0,0 +1,624 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_KEYCODES_DOM_US_LAYOUT_DATA_H_
+#define UI_EVENTS_KEYCODES_DOM_US_LAYOUT_DATA_H_
+
+namespace ui {
+
+// This table maps a DomCode to a printable character, assuming US layout.
+const struct PrintableCodeEntry {
+  DomCode dom_code;
+  base::char16 character[2];  // normal, shift
+} kPrintableCodeMap[] = {
+    {DomCode::KEY_A, {'a', 'A'}},
+    {DomCode::KEY_B, {'b', 'B'}},
+    {DomCode::KEY_C, {'c', 'C'}},
+    {DomCode::KEY_D, {'d', 'D'}},
+    {DomCode::KEY_E, {'e', 'E'}},
+    {DomCode::KEY_F, {'f', 'F'}},
+    {DomCode::KEY_G, {'g', 'G'}},
+    {DomCode::KEY_H, {'h', 'H'}},
+    {DomCode::KEY_I, {'i', 'I'}},
+    {DomCode::KEY_J, {'j', 'J'}},
+    {DomCode::KEY_K, {'k', 'K'}},
+    {DomCode::KEY_L, {'l', 'L'}},
+    {DomCode::KEY_M, {'m', 'M'}},
+    {DomCode::KEY_N, {'n', 'N'}},
+    {DomCode::KEY_O, {'o', 'O'}},
+    {DomCode::KEY_P, {'p', 'P'}},
+    {DomCode::KEY_Q, {'q', 'Q'}},
+    {DomCode::KEY_R, {'r', 'R'}},
+    {DomCode::KEY_S, {'s', 'S'}},
+    {DomCode::KEY_T, {'t', 'T'}},
+    {DomCode::KEY_U, {'u', 'U'}},
+    {DomCode::KEY_V, {'v', 'V'}},
+    {DomCode::KEY_W, {'w', 'W'}},
+    {DomCode::KEY_X, {'x', 'X'}},
+    {DomCode::KEY_Y, {'y', 'Y'}},
+    {DomCode::KEY_Z, {'z', 'Z'}},
+    {DomCode::DIGIT1, {'1', '!'}},
+    {DomCode::DIGIT2, {'2', '@'}},
+    {DomCode::DIGIT3, {'3', '#'}},
+    {DomCode::DIGIT4, {'4', '$'}},
+    {DomCode::DIGIT5, {'5', '%'}},
+    {DomCode::DIGIT6, {'6', '^'}},
+    {DomCode::DIGIT7, {'7', '&'}},
+    {DomCode::DIGIT8, {'8', '*'}},
+    {DomCode::DIGIT9, {'9', '('}},
+    {DomCode::DIGIT0, {'0', ')'}},
+    {DomCode::SPACE, {' ', ' '}},
+    {DomCode::MINUS, {'-', '_'}},
+    {DomCode::EQUAL, {'=', '+'}},
+    {DomCode::BRACKET_LEFT, {'[', '{'}},
+    {DomCode::BRACKET_RIGHT, {']', '}'}},
+    {DomCode::BACKSLASH, {'\\', '|'}},
+    {DomCode::SEMICOLON, {';', ':'}},
+    {DomCode::QUOTE, {'\'', '"'}},
+    {DomCode::BACKQUOTE, {'`', '~'}},
+    {DomCode::COMMA, {',', '<'}},
+    {DomCode::PERIOD, {'.', '>'}},
+    {DomCode::SLASH, {'/', '?'}},
+    {DomCode::INTL_BACKSLASH, {'\\', '|'}},
+    {DomCode::INTL_YEN, {0x00A5, '|'}},
+    {DomCode::NUMPAD_DIVIDE, {'/', '/'}},
+    {DomCode::NUMPAD_MULTIPLY, {'*', '*'}},
+    {DomCode::NUMPAD_SUBTRACT, {'-', '-'}},
+    {DomCode::NUMPAD_ADD, {'+', '+'}},
+    {DomCode::NUMPAD1, {'1', '1'}},
+    {DomCode::NUMPAD2, {'2', '2'}},
+    {DomCode::NUMPAD3, {'3', '3'}},
+    {DomCode::NUMPAD4, {'4', '4'}},
+    {DomCode::NUMPAD5, {'5', '5'}},
+    {DomCode::NUMPAD6, {'6', '6'}},
+    {DomCode::NUMPAD7, {'7', '7'}},
+    {DomCode::NUMPAD8, {'8', '8'}},
+    {DomCode::NUMPAD9, {'9', '9'}},
+    {DomCode::NUMPAD0, {'0', '0'}},
+    {DomCode::NUMPAD_DECIMAL, {'.', '.'}},
+    {DomCode::NUMPAD_EQUAL, {'=', '='}},
+    {DomCode::NUMPAD_COMMA, {',', ','}},
+    {DomCode::NUMPAD_PAREN_LEFT, {'(', '('}},
+    {DomCode::NUMPAD_PAREN_RIGHT, {')', ')'}},
+    {DomCode::NUMPAD_SIGN_CHANGE, {0x00B1, 0x00B1}},
+};
+
+// This table maps a DomCode to a DomKey, assuming US keyboard layout.
+const struct NonPrintableCodeEntry {
+  DomCode dom_code;
+  DomKey dom_key;
+  base::char16 character;
+} kNonPrintableCodeMap[] = {
+    {DomCode::ABORT, DomKey::CANCEL},
+    {DomCode::AGAIN, DomKey::AGAIN},
+    {DomCode::ALT_LEFT, DomKey::ALT},
+    {DomCode::ALT_RIGHT, DomKey::ALT},
+    {DomCode::ARROW_DOWN, DomKey::ARROW_DOWN},
+    {DomCode::ARROW_LEFT, DomKey::ARROW_LEFT},
+    {DomCode::ARROW_RIGHT, DomKey::ARROW_RIGHT},
+    {DomCode::ARROW_UP, DomKey::ARROW_UP},
+    {DomCode::BACKSPACE, DomKey::BACKSPACE, 0x0008},
+    {DomCode::BRIGHTNESS_DOWN, DomKey::BRIGHTNESS_DOWN},
+    {DomCode::BRIGHTNESS_UP, DomKey::BRIGHTNESS_UP},
+    // {DomCode::BRIGHTNESS_AUTO, DomKey::_}
+    // {DomCode::BRIGHTNESS_MAXIMUM, DomKey::_}
+    // {DomCode::BRIGHTNESS_MINIMIUM, DomKey::_}
+    // {DomCode::BRIGHTNESS_TOGGLE, DomKey::_}
+    {DomCode::BROWSER_BACK, DomKey::BROWSER_BACK},
+    {DomCode::BROWSER_FAVORITES, DomKey::BROWSER_FAVORITES},
+    {DomCode::BROWSER_FORWARD, DomKey::BROWSER_FORWARD},
+    {DomCode::BROWSER_HOME, DomKey::BROWSER_HOME},
+    {DomCode::BROWSER_REFRESH, DomKey::BROWSER_REFRESH},
+    {DomCode::BROWSER_SEARCH, DomKey::BROWSER_SEARCH},
+    {DomCode::BROWSER_STOP, DomKey::BROWSER_STOP},
+    {DomCode::CAPS_LOCK, DomKey::CAPS_LOCK},
+    {DomCode::CONTEXT_MENU, DomKey::CONTEXT_MENU},
+    {DomCode::CONTROL_LEFT, DomKey::CONTROL},
+    {DomCode::CONTROL_RIGHT, DomKey::CONTROL},
+    {DomCode::CONVERT, DomKey::CONVERT},
+    {DomCode::COPY, DomKey::COPY},
+    {DomCode::CUT, DomKey::CUT},
+    {DomCode::DEL, DomKey::DEL, 0x007F},
+    {DomCode::EJECT, DomKey::EJECT},
+    {DomCode::END, DomKey::END},
+    {DomCode::ENTER, DomKey::ENTER, 0x000D},
+    {DomCode::ESCAPE, DomKey::ESCAPE, 0x001B},
+    {DomCode::F1, DomKey::F1},
+    {DomCode::F2, DomKey::F2},
+    {DomCode::F3, DomKey::F3},
+    {DomCode::F4, DomKey::F4},
+    {DomCode::F5, DomKey::F5},
+    {DomCode::F6, DomKey::F6},
+    {DomCode::F7, DomKey::F7},
+    {DomCode::F8, DomKey::F8},
+    {DomCode::F9, DomKey::F9},
+    {DomCode::F10, DomKey::F10},
+    {DomCode::F11, DomKey::F11},
+    {DomCode::F12, DomKey::F12},
+    {DomCode::F13, DomKey::F13},
+    {DomCode::F14, DomKey::F14},
+    {DomCode::F15, DomKey::F15},
+    {DomCode::F16, DomKey::F16},
+    {DomCode::F17, DomKey::F17},
+    {DomCode::F18, DomKey::F18},
+    {DomCode::F19, DomKey::F19},
+    {DomCode::F20, DomKey::F20},
+    {DomCode::F21, DomKey::F21},
+    {DomCode::F22, DomKey::F22},
+    {DomCode::F23, DomKey::F23},
+    {DomCode::F24, DomKey::F24},
+    {DomCode::FIND, DomKey::FIND},
+    {DomCode::FN, DomKey::FN},
+    {DomCode::FN_LOCK, DomKey::FN_LOCK},
+    {DomCode::HELP, DomKey::HELP},
+    {DomCode::HOME, DomKey::HOME},
+    {DomCode::HYPER, DomKey::HYPER},
+    {DomCode::INSERT, DomKey::INSERT},
+    // {DomCode::INTL_RO, DomKey::_}
+    {DomCode::KANA_MODE, DomKey::KANA_MODE},
+    {DomCode::LANG1, DomKey::HANGUL_MODE},
+    {DomCode::LANG2, DomKey::HANJA_MODE},
+    {DomCode::LANG3, DomKey::KATAKANA},
+    {DomCode::LANG4, DomKey::HIRAGANA},
+    {DomCode::LANG5, DomKey::ZENKAKU_HANKAKU},
+    {DomCode::LAUNCH_APP1, DomKey::LAUNCH_MY_COMPUTER},
+    {DomCode::LAUNCH_APP2, DomKey::LAUNCH_CALCULATOR},
+    {DomCode::LAUNCH_MAIL, DomKey::LAUNCH_MAIL},
+    {DomCode::LAUNCH_SCREEN_SAVER, DomKey::LAUNCH_SCREEN_SAVER},
+    // {DomCode::LAUNCH_DOCUMENTS, DomKey::_}
+    // {DomCode::LAUNCH_FILE_BROWSER, DomKey::_}
+    // {DomCode::LAUNCH_KEYBOARD_LAYOUT, DomKey::_}
+    {DomCode::LOCK_SCREEN, DomKey::LAUNCH_SCREEN_SAVER},
+    {DomCode::MAIL_FORWARD, DomKey::MAIL_FORWARD},
+    {DomCode::MAIL_REPLY, DomKey::MAIL_REPLY},
+    {DomCode::MAIL_SEND, DomKey::MAIL_SEND},
+    {DomCode::MEDIA_PLAY_PAUSE, DomKey::MEDIA_PLAY_PAUSE},
+    {DomCode::MEDIA_SELECT, DomKey::MEDIA_SELECT},
+    {DomCode::MEDIA_STOP, DomKey::MEDIA_STOP},
+    {DomCode::MEDIA_TRACK_NEXT, DomKey::MEDIA_TRACK_NEXT},
+    {DomCode::MEDIA_TRACK_PREVIOUS, DomKey::MEDIA_TRACK_PREVIOUS},
+    // {DomCode::MENU, DomKey::_}
+    {DomCode::NON_CONVERT, DomKey::NON_CONVERT},
+    {DomCode::NUM_LOCK, DomKey::NUM_LOCK},
+    {DomCode::NUMPAD_BACKSPACE, DomKey::BACKSPACE, 0x0008},
+    {DomCode::NUMPAD_CLEAR, DomKey::CLEAR},
+    {DomCode::NUMPAD_ENTER, DomKey::ENTER, 0x000D},
+    // {DomCode::NUMPAD_CLEAR_ENTRY, DomKey::_}
+    // {DomCode::NUMPAD_MEMORY_ADD, DomKey::_}
+    // {DomCode::NUMPAD_MEMORY_CLEAR, DomKey::_}
+    // {DomCode::NUMPAD_MEMORY_RECALL, DomKey::_}
+    // {DomCode::NUMPAD_MEMORY_STORE, DomKey::_}
+    // {DomCode::NUMPAD_MEMORY_SUBTRACT, DomKey::_}
+    {DomCode::OPEN, DomKey::OPEN},
+    {DomCode::OS_LEFT, DomKey::OS},
+    {DomCode::OS_RIGHT, DomKey::OS},
+    {DomCode::PAGE_DOWN, DomKey::PAGE_DOWN},
+    {DomCode::PAGE_UP, DomKey::PAGE_UP},
+    {DomCode::PASTE, DomKey::PASTE},
+    {DomCode::PAUSE, DomKey::PAUSE},
+    {DomCode::POWER, DomKey::POWER},
+    {DomCode::PRINT_SCREEN, DomKey::PRINT_SCREEN},
+    {DomCode::PROPS, DomKey::PROPS},
+    {DomCode::SCROLL_LOCK, DomKey::SCROLL_LOCK},
+    {DomCode::SELECT, DomKey::SELECT},
+    // {DomCode::SELECT_TASK, DomKey::_}
+    {DomCode::SHIFT_LEFT, DomKey::SHIFT},
+    {DomCode::SHIFT_RIGHT, DomKey::SHIFT},
+    {DomCode::SUPER, DomKey::SUPER},
+    {DomCode::TAB, DomKey::TAB, 0x0009},
+    {DomCode::UNDO, DomKey::UNDO},
+    // {DomCode::VOICE_COMMAND, DomKey::_}
+    {DomCode::VOLUME_DOWN, DomKey::VOLUME_DOWN},
+    {DomCode::VOLUME_MUTE, DomKey::VOLUME_MUTE},
+    {DomCode::VOLUME_UP, DomKey::VOLUME_UP},
+    {DomCode::WAKE_UP, DomKey::WAKE_UP},
+    {DomCode::ZOOM_TOGGLE, DomKey::ZOOM_TOGGLE},
+};
+
+// This table maps a DomKey to a non-located KeyboardCode.
+const struct DomKeyToKeyboardCodeEntry {
+  DomKey dom_key;
+  KeyboardCode key_code;
+} kDomKeyToKeyboardCodeMap[] = {
+    // No value.
+    {DomKey::NONE, VKEY_UNKNOWN},
+    // Special Key Values
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-special
+    {DomKey::UNIDENTIFIED, VKEY_UNKNOWN},
+    // Modifier Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-modifier
+    {DomKey::ALT, VKEY_MENU},
+    {DomKey::ALT_GRAPH, VKEY_ALTGR},
+    {DomKey::CAPS_LOCK, VKEY_CAPITAL},
+    {DomKey::CONTROL, VKEY_CONTROL},
+    {DomKey::NUM_LOCK, VKEY_NUMLOCK},
+    {DomKey::OS, VKEY_LWIN},
+    {DomKey::SCROLL_LOCK, VKEY_SCROLL},
+    {DomKey::SHIFT, VKEY_SHIFT},
+    // Whitespace Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-whitespace
+    {DomKey::ENTER, VKEY_RETURN},
+    {DomKey::SEPARATOR, VKEY_SEPARATOR},
+    {DomKey::TAB, VKEY_TAB},
+    // Navigation Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-navigation
+    {DomKey::ARROW_DOWN, VKEY_DOWN},
+    {DomKey::ARROW_LEFT, VKEY_LEFT},
+    {DomKey::ARROW_RIGHT, VKEY_RIGHT},
+    {DomKey::ARROW_UP, VKEY_UP},
+    {DomKey::END, VKEY_END},
+    {DomKey::HOME, VKEY_HOME},
+    {DomKey::PAGE_DOWN, VKEY_NEXT},
+    {DomKey::PAGE_UP, VKEY_PRIOR},
+    // Editing Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-editing
+    {DomKey::BACKSPACE, VKEY_BACK},
+    {DomKey::CLEAR, VKEY_CLEAR},
+    {DomKey::CR_SEL, VKEY_CRSEL},
+    {DomKey::DEL, VKEY_DELETE},
+    {DomKey::ERASE_EOF, VKEY_EREOF},
+    {DomKey::EX_SEL, VKEY_EXSEL},
+    {DomKey::INSERT, VKEY_INSERT},
+    // UI Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-ui
+    {DomKey::ACCEPT, VKEY_ACCEPT},
+    {DomKey::ATTN, VKEY_ATTN},
+    {DomKey::CONTEXT_MENU, VKEY_APPS},
+    {DomKey::ESCAPE, VKEY_ESCAPE},
+    {DomKey::EXECUTE, VKEY_EXECUTE},
+    {DomKey::HELP, VKEY_HELP},
+    {DomKey::PAUSE, VKEY_PAUSE},
+    {DomKey::PLAY, VKEY_PLAY},
+    {DomKey::SELECT, VKEY_SELECT},
+    // Device Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-device
+#if defined(OS_POSIX)
+    {DomKey::BRIGHTNESS_DOWN, VKEY_BRIGHTNESS_DOWN},
+    {DomKey::BRIGHTNESS_UP, VKEY_BRIGHTNESS_UP},
+    {DomKey::POWER, VKEY_POWER},
+#endif
+    {DomKey::PRINT_SCREEN, VKEY_SNAPSHOT},
+// IME and Composition Keys
+// http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-composition
+#if defined(OS_POSIX)
+    {DomKey::COMPOSE, VKEY_COMPOSE},
+#endif
+    {DomKey::CONVERT, VKEY_CONVERT},
+    {DomKey::FINAL_MODE, VKEY_FINAL},
+    {DomKey::MODE_CHANGE, VKEY_MODECHANGE},
+    {DomKey::NON_CONVERT, VKEY_NONCONVERT},
+    {DomKey::PROCESS, VKEY_PROCESSKEY},
+    // Keys specific to Korean keyboards
+    {DomKey::HANGUL_MODE, VKEY_HANGUL},
+    {DomKey::HANJA_MODE, VKEY_HANJA},
+    {DomKey::JUNJA_MODE, VKEY_JUNJA},
+    // Keys specific to Japanese keyboards
+    {DomKey::HANKAKU, VKEY_DBE_SBCSCHAR},
+    {DomKey::KANA_MODE, VKEY_KANA},
+    {DomKey::KANJI_MODE, VKEY_KANJI},
+    {DomKey::ZENKAKU, VKEY_DBE_DBCSCHAR},
+    {DomKey::ZENKAKU_HANKAKU, VKEY_DBE_DBCSCHAR},
+    // General-Purpose Function Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-function
+    {DomKey::F1, VKEY_F1},
+    {DomKey::F2, VKEY_F2},
+    {DomKey::F3, VKEY_F3},
+    {DomKey::F4, VKEY_F4},
+    {DomKey::F5, VKEY_F5},
+    {DomKey::F6, VKEY_F6},
+    {DomKey::F7, VKEY_F7},
+    {DomKey::F8, VKEY_F8},
+    {DomKey::F9, VKEY_F9},
+    {DomKey::F10, VKEY_F10},
+    {DomKey::F11, VKEY_F11},
+    {DomKey::F12, VKEY_F12},
+    {DomKey::F13, VKEY_F13},
+    {DomKey::F14, VKEY_F14},
+    {DomKey::F15, VKEY_F15},
+    {DomKey::F16, VKEY_F16},
+    {DomKey::F17, VKEY_F17},
+    {DomKey::F18, VKEY_F18},
+    {DomKey::F19, VKEY_F19},
+    {DomKey::F20, VKEY_F20},
+    {DomKey::F21, VKEY_F21},
+    {DomKey::F22, VKEY_F22},
+    {DomKey::F23, VKEY_F23},
+    {DomKey::F24, VKEY_F24},
+    // Multimedia Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-multimedia
+    {DomKey::MEDIA_PLAY_PAUSE, VKEY_MEDIA_PLAY_PAUSE},
+    {DomKey::MEDIA_SELECT, VKEY_MEDIA_LAUNCH_MEDIA_SELECT},
+    {DomKey::MEDIA_STOP, VKEY_MEDIA_STOP},
+    {DomKey::MEDIA_TRACK_NEXT, VKEY_MEDIA_NEXT_TRACK},
+    {DomKey::MEDIA_TRACK_PREVIOUS, VKEY_MEDIA_PREV_TRACK},
+    {DomKey::PRINT, VKEY_PRINT},
+    {DomKey::VOLUME_DOWN, VKEY_VOLUME_DOWN},
+    {DomKey::VOLUME_MUTE, VKEY_VOLUME_MUTE},
+    {DomKey::VOLUME_UP, VKEY_VOLUME_UP},
+    // Application Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-apps
+    {DomKey::LAUNCH_CALCULATOR, VKEY_MEDIA_LAUNCH_APP2},
+    {DomKey::LAUNCH_MAIL, VKEY_MEDIA_LAUNCH_MAIL},
+    {DomKey::LAUNCH_MY_COMPUTER, VKEY_MEDIA_LAUNCH_APP1},
+    // Browser Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-browser
+    {DomKey::BROWSER_BACK, VKEY_BROWSER_BACK},
+    {DomKey::BROWSER_FAVORITES, VKEY_BROWSER_FAVORITES},
+    {DomKey::BROWSER_FORWARD, VKEY_BROWSER_FORWARD},
+    {DomKey::BROWSER_HOME, VKEY_BROWSER_HOME},
+    {DomKey::BROWSER_REFRESH, VKEY_BROWSER_REFRESH},
+    {DomKey::BROWSER_SEARCH, VKEY_BROWSER_SEARCH},
+    {DomKey::BROWSER_STOP, VKEY_BROWSER_STOP},
+    // Media Controller Keys
+    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-media-controller
+#if defined(OS_POSIX)
+    {DomKey::MEDIA_FAST_FORWARD, VKEY_OEM_104},
+#endif
+    {DomKey::MEDIA_PLAY, VKEY_PLAY},
+#if defined(OS_POSIX)
+    {DomKey::MEDIA_REWIND, VKEY_OEM_103},
+#endif
+    {DomKey::ZOOM_TOGGLE, VKEY_ZOOM},
+};
+
+// This table, used by DomCodeToUsLayoutKeyboardCode() and
+// UsLayoutKeyboardCodeToDomCode(), maps between DOM Level 3 .code values
+// and legacy Windows-based VKEY values, where the VKEYs are interpreted
+// positionally (located) following a base US English layout.
+const struct DomCodeToKeyboardCodeEntry {
+  DomCode dom_code;
+  KeyboardCode key_code;
+} kDomCodeToKeyboardCodeMap[] = {
+    // Entries are ordered by numeric value of the DomCode enum,
+    // which is the USB physical key code.
+    // DomCode::HYPER                              0x000010 Hyper
+    // DomCode::SUPER                              0x000011 Super
+    // DomCode::FN                                 0x000012 Fn
+    // DomCode::FN_LOCK                            0x000013 FLock
+    // DomCode::SUSPEND                            0x000014 Suspend
+    // DomCode::RESUME                             0x000015 Resume
+    // DomCode::TURBO                              0x000016 Turbo
+    {DomCode::SLEEP, VKEY_SLEEP},               // 0x010082 Sleep
+    // DomCode::WAKE_UP                            0x010083 WakeUp
+    {DomCode::KEY_A, VKEY_A},                   // 0x070004 KeyA
+    {DomCode::KEY_B, VKEY_B},                   // 0x070005 KeyB
+    {DomCode::KEY_C, VKEY_C},                   // 0x070006 KeyC
+    {DomCode::KEY_D, VKEY_D},                   // 0x070007 KeyD
+    {DomCode::KEY_E, VKEY_E},                   // 0x070008 KeyE
+    {DomCode::KEY_F, VKEY_F},                   // 0x070009 KeyF
+    {DomCode::KEY_G, VKEY_G},                   // 0x07000A KeyG
+    {DomCode::KEY_H, VKEY_H},                   // 0x07000B KeyH
+    {DomCode::KEY_I, VKEY_I},                   // 0x07000C KeyI
+    {DomCode::KEY_J, VKEY_J},                   // 0x07000D KeyJ
+    {DomCode::KEY_K, VKEY_K},                   // 0x07000E KeyK
+    {DomCode::KEY_L, VKEY_L},                   // 0x07000F KeyL
+    {DomCode::KEY_M, VKEY_M},                   // 0x070010 KeyM
+    {DomCode::KEY_N, VKEY_N},                   // 0x070011 KeyN
+    {DomCode::KEY_O, VKEY_O},                   // 0x070012 KeyO
+    {DomCode::KEY_P, VKEY_P},                   // 0x070013 KeyP
+    {DomCode::KEY_Q, VKEY_Q},                   // 0x070014 KeyQ
+    {DomCode::KEY_R, VKEY_R},                   // 0x070015 KeyR
+    {DomCode::KEY_S, VKEY_S},                   // 0x070016 KeyS
+    {DomCode::KEY_T, VKEY_T},                   // 0x070017 KeyT
+    {DomCode::KEY_U, VKEY_U},                   // 0x070018 KeyU
+    {DomCode::KEY_V, VKEY_V},                   // 0x070019 KeyV
+    {DomCode::KEY_W, VKEY_W},                   // 0x07001A KeyW
+    {DomCode::KEY_X, VKEY_X},                   // 0x07001B KeyX
+    {DomCode::KEY_Y, VKEY_Y},                   // 0x07001C KeyY
+    {DomCode::KEY_Z, VKEY_Z},                   // 0x07001D KeyZ
+    {DomCode::DIGIT1, VKEY_1},                  // 0x07001E Digit1
+    {DomCode::DIGIT2, VKEY_2},                  // 0x07001F Digit2
+    {DomCode::DIGIT3, VKEY_3},                  // 0x070020 Digit3
+    {DomCode::DIGIT4, VKEY_4},                  // 0x070021 Digit4
+    {DomCode::DIGIT5, VKEY_5},                  // 0x070022 Digit5
+    {DomCode::DIGIT6, VKEY_6},                  // 0x070023 Digit6
+    {DomCode::DIGIT7, VKEY_7},                  // 0x070024 Digit7
+    {DomCode::DIGIT8, VKEY_8},                  // 0x070025 Digit8
+    {DomCode::DIGIT9, VKEY_9},                  // 0x070026 Digit9
+    {DomCode::DIGIT0, VKEY_0},                  // 0x070027 Digit0
+    {DomCode::ENTER, VKEY_RETURN},              // 0x070028 Enter
+    {DomCode::ESCAPE, VKEY_ESCAPE},             // 0x070029 Escape
+    {DomCode::BACKSPACE, VKEY_BACK},            // 0x07002A Backspace
+    {DomCode::TAB, VKEY_TAB},                   // 0x07002B Tab
+    {DomCode::SPACE, VKEY_SPACE},               // 0x07002C Space
+    {DomCode::MINUS, VKEY_OEM_MINUS},           // 0x07002D Minus
+    {DomCode::EQUAL, VKEY_OEM_PLUS},            // 0x07002E Equal
+    {DomCode::BRACKET_LEFT, VKEY_OEM_4},        // 0x07002F BracketLeft
+    {DomCode::BRACKET_RIGHT, VKEY_OEM_6},       // 0x070030 BracketRight
+    {DomCode::BACKSLASH, VKEY_OEM_5},           // 0x070031 Backslash
+    // DomCode::INTL_HASH, VKEY_OEM_5           // 0x070032 IntlHash
+    {DomCode::SEMICOLON, VKEY_OEM_1},           // 0x070033 Semicolon
+    {DomCode::QUOTE, VKEY_OEM_7},               // 0x070034 Quote
+    {DomCode::BACKQUOTE, VKEY_OEM_3},           // 0x070035 Backquote
+    {DomCode::COMMA, VKEY_OEM_COMMA},           // 0x070036 Comma
+    {DomCode::PERIOD, VKEY_OEM_PERIOD},         // 0x070037 Period
+    {DomCode::SLASH, VKEY_OEM_2},               // 0x070038 Slash
+    {DomCode::CAPS_LOCK, VKEY_CAPITAL},         // 0x070039 CapsLock
+    {DomCode::F1, VKEY_F1},                     // 0x07003A F1
+    {DomCode::F2, VKEY_F2},                     // 0x07003B F2
+    {DomCode::F3, VKEY_F3},                     // 0x07003C F3
+    {DomCode::F4, VKEY_F4},                     // 0x07003D F4
+    {DomCode::F5, VKEY_F5},                     // 0x07003E F5
+    {DomCode::F6, VKEY_F6},                     // 0x07003F F6
+    {DomCode::F7, VKEY_F7},                     // 0x070040 F7
+    {DomCode::F8, VKEY_F8},                     // 0x070041 F8
+    {DomCode::F9, VKEY_F9},                     // 0x070042 F9
+    {DomCode::F10, VKEY_F10},                   // 0x070043 F10
+    {DomCode::F11, VKEY_F11},                   // 0x070044 F11
+    {DomCode::F12, VKEY_F12},                   // 0x070045 F12
+    {DomCode::PRINT_SCREEN, VKEY_SNAPSHOT},     // 0x070046 PrintScreen
+    {DomCode::SCROLL_LOCK, VKEY_SCROLL},        // 0x070047 ScrollLock
+    {DomCode::PAUSE, VKEY_PAUSE},               // 0x070048 Pause
+    {DomCode::INSERT, VKEY_INSERT},             // 0x070049 Insert
+    {DomCode::HOME, VKEY_HOME},                 // 0x07004A Home
+    {DomCode::PAGE_UP, VKEY_PRIOR},             // 0x07004B PageUp
+    {DomCode::DEL, VKEY_DELETE},                // 0x07004C Delete
+    {DomCode::END, VKEY_END},                   // 0x07004D End
+    {DomCode::PAGE_DOWN, VKEY_NEXT},            // 0x07004E PageDown
+    {DomCode::ARROW_RIGHT, VKEY_RIGHT},         // 0x07004F ArrowRight
+    {DomCode::ARROW_LEFT, VKEY_LEFT},           // 0x070050 ArrowLeft
+    {DomCode::ARROW_DOWN, VKEY_DOWN},           // 0x070051 ArrowDown
+    {DomCode::ARROW_UP, VKEY_UP},               // 0x070052 ArrowUp
+    {DomCode::NUM_LOCK, VKEY_NUMLOCK},          // 0x070053 NumLock
+    {DomCode::NUMPAD_DIVIDE, VKEY_DIVIDE},      // 0x070054 NumpadDivide
+    {DomCode::NUMPAD_MULTIPLY, VKEY_MULTIPLY},  // 0x070055 NumpadMultiply
+    {DomCode::NUMPAD_SUBTRACT, VKEY_SUBTRACT},  // 0x070056 NumpadSubtract
+    {DomCode::NUMPAD_ADD, VKEY_ADD},            // 0x070057 NumpadAdd
+    {DomCode::NUMPAD_ENTER, VKEY_RETURN},       // 0x070058 NumpadEnter
+    {DomCode::NUMPAD1, VKEY_NUMPAD1},           // 0x070059 Numpad1
+    {DomCode::NUMPAD2, VKEY_NUMPAD2},           // 0x07005A Numpad2
+    {DomCode::NUMPAD3, VKEY_NUMPAD3},           // 0x07005B Numpad3
+    {DomCode::NUMPAD4, VKEY_NUMPAD4},           // 0x07005C Numpad4
+    {DomCode::NUMPAD5, VKEY_NUMPAD5},           // 0x07005D Numpad5
+    {DomCode::NUMPAD6, VKEY_NUMPAD6},           // 0x07005E Numpad6
+    {DomCode::NUMPAD7, VKEY_NUMPAD7},           // 0x07005F Numpad7
+    {DomCode::NUMPAD8, VKEY_NUMPAD8},           // 0x070060 Numpad8
+    {DomCode::NUMPAD9, VKEY_NUMPAD9},           // 0x070061 Numpad9
+    {DomCode::NUMPAD0, VKEY_NUMPAD0},           // 0x070062 Numpad0
+    {DomCode::NUMPAD_DECIMAL, VKEY_DECIMAL},    // 0x070063 NumpadDecimal
+    {DomCode::INTL_BACKSLASH, VKEY_OEM_102},    // 0x070064 IntlBackslash
+    {DomCode::CONTEXT_MENU, VKEY_APPS},         // 0x070065 ContextMenu
+#if defined(OS_POSIX)
+    {DomCode::POWER, VKEY_POWER},               // 0x070066 Power
+#endif
+    // DomCode::NUMPAD_EQUAL                       0x070067 NumpadEqual
+    {DomCode::F13, VKEY_F13},                   // 0x070068 F13
+    {DomCode::F14, VKEY_F14},                   // 0x070069 F14
+    {DomCode::F15, VKEY_F15},                   // 0x07006A F15
+    {DomCode::F16, VKEY_F16},                   // 0x07006B F16
+    {DomCode::F17, VKEY_F17},                   // 0x07006C F17
+    {DomCode::F18, VKEY_F18},                   // 0x07006D F18
+    {DomCode::F19, VKEY_F19},                   // 0x07006E F19
+    {DomCode::F20, VKEY_F20},                   // 0x07006F F20
+    {DomCode::F21, VKEY_F21},                   // 0x070070 F21
+    {DomCode::F22, VKEY_F22},                   // 0x070071 F22
+    {DomCode::F23, VKEY_F23},                   // 0x070072 F23
+    {DomCode::F24, VKEY_F24},                   // 0x070073 F24
+    {DomCode::OPEN, VKEY_EXECUTE},              // 0x070074 Open
+    {DomCode::HELP, VKEY_HELP},                 // 0x070075 Help
+    {DomCode::SELECT, VKEY_SELECT},             // 0x070077 Select
+    // DomCode::AGAIN                              0x070079 Again
+    // DomCode::UNDO                               0x07007A Undo
+    // DomCode::CUT                                0x07007B Cut
+    // DomCode::COPY                               0x07007C Copy
+    // DomCode::PASTE                              0x07007D Paste
+    // DomCode::FIND                               0x07007E Find
+    {DomCode::VOLUME_MUTE, VKEY_VOLUME_MUTE},   // 0x07007F VolumeMute
+    {DomCode::VOLUME_UP, VKEY_VOLUME_UP},       // 0x070080 VolumeUp
+    {DomCode::VOLUME_DOWN, VKEY_VOLUME_DOWN},   // 0x070081 VolumeDown
+    {DomCode::NUMPAD_COMMA, VKEY_OEM_COMMA},    // 0x070085 NumpadComma
+    {DomCode::INTL_RO, VKEY_OEM_102},           // 0x070087 IntlRo
+    {DomCode::KANA_MODE, VKEY_KANA},            // 0x070088 KanaMode
+    {DomCode::INTL_YEN, VKEY_OEM_5},            // 0x070089 IntlYen
+    {DomCode::CONVERT, VKEY_CONVERT},           // 0x07008A Convert
+    {DomCode::NON_CONVERT, VKEY_NONCONVERT},    // 0x07008B NonConvert
+    {DomCode::LANG1, VKEY_KANA},                // 0x070090 Lang1
+    {DomCode::LANG2, VKEY_KANJI},               // 0x070091 Lang2
+    // DomCode::LANG3                              0x070092 Lang3
+    // DomCode::LANG4                              0x070093 Lang4
+    // DomCode::LANG5                              0x070094 Lang5
+    // DomCode::ABORT                              0x07009B Abort
+    // DomCode::PROPS                              0x0700A3 Props
+    // DomCode::NUMPAD_PAREN_LEFT                  0x0700B6 NumpadParenLeft
+    // DomCode::NUMPAD_PAREN_RIGHT                 0x0700B7 NumpadParenRight
+    {DomCode::NUMPAD_BACKSPACE, VKEY_BACK},     // 0x0700BB NumpadBackspace
+    // DomCode::NUMPAD_MEMORY_STORE                0x0700D0 NumpadMemoryStore
+    // DomCode::NUMPAD_MEMORY_RECALL               0x0700D1 NumpadMemoryRecall
+    // DomCode::NUMPAD_MEMORY_CLEAR                0x0700D2 NumpadMemoryClear
+    // DomCode::NUMPAD_MEMORY_ADD                  0x0700D3 NumpadMemoryAdd
+    // DomCode::NUMPAD_MEMORY_SUBTRACT             0x0700D4 NumpadMemorySubtract
+    {DomCode::NUMPAD_CLEAR, VKEY_CLEAR},        // 0x0700D8 NumpadClear
+    {DomCode::NUMPAD_CLEAR_ENTRY, VKEY_CLEAR},  // 0x0700D9 NumpadClearEntry
+    {DomCode::CONTROL_LEFT, VKEY_LCONTROL},     // 0x0700E0 ControlLeft
+    {DomCode::SHIFT_LEFT, VKEY_LSHIFT},         // 0x0700E1 ShiftLeft
+    {DomCode::ALT_LEFT, VKEY_LMENU},            // 0x0700E2 AltLeft
+    {DomCode::OS_LEFT, VKEY_LWIN},              // 0x0700E3 OSLeft
+    {DomCode::CONTROL_RIGHT, VKEY_RCONTROL},    // 0x0700E4 ControlRight
+    {DomCode::SHIFT_RIGHT, VKEY_RSHIFT},        // 0x0700E5 ShiftRight
+    {DomCode::ALT_RIGHT, VKEY_RMENU},           // 0x0700E6 AltRight
+    {DomCode::OS_RIGHT, VKEY_RWIN},             // 0x0700E7 OSRight
+#if defined(OS_POSIX)
+    {DomCode::BRIGHTNESS_UP,
+     VKEY_BRIGHTNESS_UP},                       // 0x0C006F BrightnessUp
+    {DomCode::BRIGHTNESS_DOWN,
+     VKEY_BRIGHTNESS_DOWN},                     // 0x0C0070 BrightnessDown
+#endif
+    {DomCode::MEDIA_TRACK_NEXT,
+     VKEY_MEDIA_NEXT_TRACK},                    // 0x0C00B5 MediaTrackNext
+    {DomCode::MEDIA_TRACK_PREVIOUS,
+     VKEY_MEDIA_PREV_TRACK},                    // 0x0C00B6 MediaTrackPrevious
+    {DomCode::MEDIA_STOP, VKEY_MEDIA_STOP},     // 0x0C00B7 MediaStop
+    // DomCode::EJECT                              0x0C00B8 Eject
+    {DomCode::MEDIA_PLAY_PAUSE,
+     VKEY_MEDIA_PLAY_PAUSE},                    // 0x0C00CD MediaPlayPause
+    {DomCode::MEDIA_SELECT,
+     VKEY_MEDIA_LAUNCH_MEDIA_SELECT},           // 0x0C0183 MediaSelect
+    {DomCode::LAUNCH_MAIL,
+     VKEY_MEDIA_LAUNCH_MAIL},                   // 0x0C018A LaunchMail
+    {DomCode::LAUNCH_APP2,
+     VKEY_MEDIA_LAUNCH_APP2},                   // 0x0C0192 LaunchApp2
+    {DomCode::LAUNCH_APP1,
+     VKEY_MEDIA_LAUNCH_APP1},                   // 0x0C0194 LaunchApp1
+    {DomCode::BROWSER_SEARCH,
+     VKEY_BROWSER_SEARCH},                      // 0x0C0221 BrowserSearch
+    {DomCode::BROWSER_HOME, VKEY_BROWSER_HOME}, // 0x0C0223 BrowserHome
+    {DomCode::BROWSER_BACK, VKEY_BROWSER_BACK}, // 0x0C0224 BrowserBack
+    {DomCode::BROWSER_FORWARD,
+     VKEY_BROWSER_FORWARD},                     // 0x0C0225 BrowserForward
+    {DomCode::BROWSER_STOP, VKEY_BROWSER_STOP}, // 0x0C0226 BrowserStop
+    {DomCode::BROWSER_REFRESH,
+     VKEY_BROWSER_REFRESH},                     // 0x0C0227 BrowserRefresh
+    {DomCode::BROWSER_FAVORITES,
+     VKEY_BROWSER_FAVORITES},                   // 0x0C022A BrowserFavorites
+    {DomCode::ZOOM_TOGGLE, VKEY_ZOOM},          // 0x0C0232 ZoomToggle
+};
+
+// This table, used by UsLayoutKeyboardCodeToDomCode(), maps legacy
+// Windows-based VKEY values that are not part of kDomCodeToKeyboardCodeMap[]
+// to suitable DomCode values, where practical.
+const DomCodeToKeyboardCodeEntry kFallbackKeyboardCodeToDomCodeMap[] = {
+    {DomCode::ALT_LEFT, VKEY_MENU},
+    {DomCode::ALT_RIGHT, VKEY_ALTGR},
+    {DomCode::BACKQUOTE, VKEY_DBE_SBCSCHAR},
+#if defined(OS_POSIX)
+    {DomCode::CONTEXT_MENU, VKEY_COMPOSE},
+#endif
+    {DomCode::CONTROL_LEFT, VKEY_CONTROL},
+    {DomCode::LANG1, VKEY_HANGUL},
+    {DomCode::LANG2, VKEY_HANJA},
+    {DomCode::LANG5, VKEY_DBE_DBCSCHAR},
+    {DomCode::NUMPAD_CLEAR, VKEY_OEM_CLEAR},
+    {DomCode::PROPS, VKEY_CRSEL},
+    {DomCode::SHIFT_LEFT, VKEY_SHIFT},
+    {DomCode::SUPER, VKEY_OEM_8},
+    //
+    // VKEYs with no existing corresponding DomCode, but a USB usage code:
+    //  {DomCode::SYS_REQ, VKEY_ATTN},          // 0x07009A SysReq
+    //  {DomCode::SEPARATOR, VKEY_SEPARATOR},   // 0x07009F Separator
+    //  {DomCode::EX_SEL, VKEY_EXSEL},          // 0x0700A4 ExSel
+    //  {DomCode::PRINT, VKEY_PRINT},           // 0x0C0208 AC Print
+    //  {DomCode::MEDIA_PLAY, VKEY_PLAY},       // 0x0C00B0 MediaPlay
+    //  {DomCode::MEDIA_REWIND, VKEY_OEM_103},  // 0x0C00B4 MediaRewind
+    //  {DomCode::MEDIA_FAST_FORWARD, VKEY_OEM_104},
+    //                                          // 0x0C00B3 MediaFastForward
+    //
+    // VKEYs with no corresponding DomCode and no obvious USB usage code:
+    //  VKEY_ACCEPT
+    //  VKEY_BACKTAB
+    //  VKEY_EREOF
+    //  VKEY_FINAL
+    //  VKEY_JUNJA
+    //  VKEY_KBD_BRIGHTNESS_DOWN
+    //  VKEY_KBD_BRIGHTNESS_UP
+    //  VKEY_MODECHANGE
+    //  VKEY_NONAME
+    //  VKEY_PA1
+    //  VKEY_PACKET
+    //  VKEY_PROCESSKEY
+    //  VKEY_WLAN
+};
+
+}  // namespace ui
+
+#endif  // UI_EVENTS_KEYCODES_DOM_US_LAYOUT_DATA_H_
diff --git a/ui/events/keycodes/keyboard_code_conversion.cc b/ui/events/keycodes/keyboard_code_conversion.cc
index b71dd6f0b..e31512b 100644
--- a/ui/events/keycodes/keyboard_code_conversion.cc
+++ b/ui/events/keycodes/keyboard_code_conversion.cc
@@ -4,9 +4,12 @@
 
 #include "ui/events/keycodes/keyboard_code_conversion.h"
 
+#include <algorithm>
+
 #include "ui/events/event_constants.h"
 #include "ui/events/keycodes/dom3/dom_code.h"
 #include "ui/events/keycodes/dom3/dom_key.h"
+#include "ui/events/keycodes/dom_us_layout_data.h"
 
 namespace ui {
 
@@ -130,6 +133,29 @@
          (code == DomCode::ALT_RIGHT) || (code == DomCode::OS_RIGHT);
 }
 
+bool IsModifierDomCode(DomCode code) {
+  return (code == DomCode::CONTROL_LEFT) || (code == DomCode::CONTROL_RIGHT) ||
+         (code == DomCode::SHIFT_LEFT) || (code == DomCode::SHIFT_RIGHT) ||
+         (code == DomCode::ALT_LEFT) || (code == DomCode::ALT_RIGHT) ||
+         (code == DomCode::OS_LEFT) || (code == DomCode::OS_RIGHT);
+}
+
+// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|,
+// assuming a base US English layout. The returned VKEY is located
+// (e.g. VKEY_LSHIFT).
+KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code) {
+  const DomCodeToKeyboardCodeEntry* end =
+      kDomCodeToKeyboardCodeMap + arraysize(kDomCodeToKeyboardCodeMap);
+  const DomCodeToKeyboardCodeEntry* found =
+      std::lower_bound(kDomCodeToKeyboardCodeMap, end, dom_code,
+                       [](const DomCodeToKeyboardCodeEntry& a, DomCode b) {
+    return static_cast<int>(a.dom_code) < static_cast<int>(b);
+  });
+  if ((found != end) && (found->dom_code == dom_code))
+    return found->key_code;
+  return VKEY_UNKNOWN;
+}
+
 }  // anonymous namespace
 
 base::char16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags) {
@@ -267,6 +293,151 @@
   return false;
 }
 
+bool DomCodeToUsLayoutMeaning(DomCode dom_code,
+                              int flags,
+                              DomKey* out_dom_key,
+                              base::char16* out_character,
+                              KeyboardCode* out_key_code) {
+  if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) {
+    if (DomCodeToControlCharacter(dom_code, flags, out_dom_key, out_character,
+                                  out_key_code)) {
+      return true;
+    }
+    if (!IsModifierDomCode(dom_code)) {
+      *out_dom_key = DomKey::UNIDENTIFIED;
+      *out_character = 0;
+      *out_key_code = LocatedToNonLocatedKeyboardCode(
+          DomCodeToUsLayoutKeyboardCode(dom_code));
+      return true;
+    }
+  } else {
+    for (const auto& it : kPrintableCodeMap) {
+      if (it.dom_code == dom_code) {
+        int state = ((flags & EF_SHIFT_DOWN) == EF_SHIFT_DOWN);
+        base::char16 ch = it.character[state];
+        *out_dom_key = DomKey::CHARACTER;
+        *out_character = ch;
+        if ((flags & EF_CAPS_LOCK_DOWN) == EF_CAPS_LOCK_DOWN) {
+          ch |= 0x20;
+          if ((ch >= 'a') && (ch <= 'z'))
+            *out_character = it.character[state ^ 1];
+        }
+        *out_key_code = LocatedToNonLocatedKeyboardCode(
+            DomCodeToUsLayoutKeyboardCode(dom_code));
+        return true;
+      }
+    }
+  }
+  for (const auto& it : kNonPrintableCodeMap) {
+    if (it.dom_code == dom_code) {
+      *out_dom_key = it.dom_key;
+      *out_character = it.character;
+      *out_key_code = NonPrintableDomKeyToKeyboardCode(it.dom_key);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool DomCodeToControlCharacter(DomCode dom_code,
+                               int flags,
+                               DomKey* dom_key,
+                               base::char16* character,
+                               KeyboardCode* key_code) {
+  if ((flags & EF_CONTROL_DOWN) == 0)
+    return false;
+
+  int code = static_cast<int>(dom_code);
+  const int kKeyA = static_cast<int>(DomCode::KEY_A);
+  // Control-A - Control-Z map to 0x01 - 0x1A.
+  if (code >= kKeyA && code <= static_cast<int>(DomCode::KEY_Z)) {
+    *character = static_cast<base::char16>(code - kKeyA + 1);
+    switch (dom_code) {
+      case DomCode::KEY_H:
+        *dom_key = DomKey::BACKSPACE;
+        *key_code = VKEY_BACK;
+        break;
+      case DomCode::KEY_I:
+        *dom_key = DomKey::TAB;
+        *key_code = VKEY_TAB;
+        break;
+      case DomCode::KEY_M:
+        *dom_key = DomKey::ENTER;
+        *key_code = VKEY_RETURN;
+        break;
+      default:
+        *dom_key = DomKey::CHARACTER;
+        *key_code = static_cast<KeyboardCode>(code - kKeyA + VKEY_A);
+        break;
+    }
+    return true;
+  }
+
+  if (flags & EF_SHIFT_DOWN) {
+    switch (dom_code) {
+      case DomCode::DIGIT2:
+        // NUL
+        *character = 0;
+        *dom_key = DomKey::CHARACTER;
+        *key_code = VKEY_2;
+        return true;
+      case DomCode::DIGIT6:
+        // RS
+        *character = 0x1E;
+        *dom_key = DomKey::CHARACTER;
+        *key_code = VKEY_6;
+        return true;
+      case DomCode::MINUS:
+        // US
+        *character = 0x1F;
+        *dom_key = DomKey::CHARACTER;
+        *key_code = VKEY_OEM_MINUS;
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  switch (dom_code) {
+    case DomCode::ENTER:
+      // NL
+      *character = 0x0A;
+      *dom_key = DomKey::CHARACTER;
+      *key_code = VKEY_RETURN;
+      return true;
+    case DomCode::BRACKET_LEFT:
+      // ESC
+      *character = 0x1B;
+      *dom_key = DomKey::ESCAPE;
+      *key_code = VKEY_OEM_4;
+      return true;
+    case DomCode::BACKSLASH:
+      // FS
+      *character = 0x1C;
+      *dom_key = DomKey::CHARACTER;
+      *key_code = VKEY_OEM_5;
+      return true;
+    case DomCode::BRACKET_RIGHT:
+      // GS
+      *character = 0x1D;
+      *dom_key = DomKey::CHARACTER;
+      *key_code = VKEY_OEM_6;
+      return true;
+    default:
+      return false;
+  }
+}
+
+// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
+// The returned VKEY is non-positional (e.g. VKEY_SHIFT).
+KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) {
+  for (const auto& it : kDomKeyToKeyboardCodeMap) {
+    if (it.dom_key == dom_key)
+      return it.key_code;
+  }
+  return VKEY_UNKNOWN;
+}
+
 // Determine the non-located VKEY corresponding to a located VKEY.
 KeyboardCode LocatedToNonLocatedKeyboardCode(KeyboardCode key_code) {
   switch (key_code) {
@@ -343,4 +514,17 @@
   }
 }
 
+DomCode UsLayoutKeyboardCodeToDomCode(KeyboardCode key_code) {
+  key_code = NonLocatedToLocatedKeyboardCode(key_code, DomCode::NONE);
+  for (const auto& it : kDomCodeToKeyboardCodeMap) {
+    if (it.key_code == key_code)
+      return it.dom_code;
+  }
+  for (const auto& it : kFallbackKeyboardCodeToDomCodeMap) {
+    if (it.key_code == key_code)
+      return it.dom_code;
+  }
+  return DomCode::NONE;
+}
+
 }  // namespace ui
diff --git a/ui/events/keycodes/keyboard_code_conversion.h b/ui/events/keycodes/keyboard_code_conversion.h
index 0c14ed74..8b92ba1 100644
--- a/ui/events/keycodes/keyboard_code_conversion.h
+++ b/ui/events/keycodes/keyboard_code_conversion.h
@@ -5,6 +5,7 @@
 #ifndef UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_
 #define UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_
 
+#include "base/compiler_specific.h"
 #include "base/strings/string16.h"
 #include "ui/events/events_base_export.h"
 #include "ui/events/keycodes/keyboard_codes.h"
@@ -18,22 +19,20 @@
 // platform independent way. It supports control characters as well.
 // It assumes a US keyboard layout is used, so it may only be used when there
 // is no native event or no better way to get the character.
+//
 // For example, if a virtual keyboard implementation can only generate key
 // events with key_code and flags information, then there is no way for us to
 // determine the actual character that should be generate by the key. Because
 // a key_code only represents a physical key on the keyboard, it has nothing
 // to do with the actual character printed on that key. In such case, the only
 // thing we can do is to assume that we are using a US keyboard and get the
-// character according to US keyboard layout definition.
-// If a virtual keyboard implementation wants to support other keyboard
-// layouts, that may generate different text for a certain key than on a US
-// keyboard, a special native event object should be introduced to carry extra
-// information to help determine the correct character.
-// Take XKeyEvent as an example, it contains not only keycode and modifier
-// flags but also group and other extra XKB information to help determine the
-// correct character. That's why we can use XLookupString() function to get
-// the correct text generated by a X key event (See how is GetCharacter()
-// implemented in event_x.cc).
+// character according to US keyboard layout definition. Preferably, such
+// events should be created using a full KeyEvent constructor, explicitly
+// specifying the character and DOM 3 values as well as the legacy VKEY.
+//
+// TODO(kpschoedel): replace remaining uses of the ...FromKeyCode() functions
+// and remove them, to avoid future creation of underspecified key events.
+// crbug.com/444045
 EVENTS_BASE_EXPORT base::char16 GetCharacterFromKeyCode(KeyboardCode key_code,
                                                         int flags);
 EVENTS_BASE_EXPORT bool GetMeaningFromKeyCode(KeyboardCode key_code,
@@ -41,6 +40,41 @@
                                               DomKey* dom_key,
                                               base::char16* character);
 
+// Helper function to map a physical key state (dom_code and flags)
+// to a meaning (dom_key and character, together corresponding to the
+// DOM keyboard event |key| value), along with a corresponding Windows-based
+// key_code.
+//
+// This follows a US keyboard layout, so it should only be used when there
+// is no other better way to obtain the meaning (e.g. actual keyboard layout).
+// Returns true and sets the output parameters if the (dom_code, flags) pair
+// has an interpretation in the US English layout; otherwise the output
+// parameters are untouched.
+EVENTS_BASE_EXPORT bool DomCodeToUsLayoutMeaning(DomCode dom_code,
+                                                 int flags,
+                                                 DomKey* dom_key,
+                                                 base::char16* character,
+                                                 KeyboardCode* key_code)
+    WARN_UNUSED_RESULT;
+
+// Obtains the control character corresponding to a physical key;
+// that is, the meaning of the physical key state (dom_code, and flags
+// containing EF_CONTROL_DOWN) under the base US English layout.
+// Returns true and sets the output parameters if the (dom_code, flags) pair
+// is interpreted as a control character; otherwise the output parameters
+// are untouched.
+EVENTS_BASE_EXPORT bool DomCodeToControlCharacter(DomCode dom_code,
+                                                  int flags,
+                                                  DomKey* dom_key,
+                                                  base::char16* character,
+                                                  KeyboardCode* key_code)
+    WARN_UNUSED_RESULT;
+
+// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
+// The returned VKEY is non-located (e.g. VKEY_SHIFT).
+EVENTS_BASE_EXPORT KeyboardCode
+NonPrintableDomKeyToKeyboardCode(DomKey dom_key);
+
 // Determine the non-located VKEY corresponding to a located VKEY.
 // Most modifier keys have two kinds of KeyboardCode: located (e.g.
 // VKEY_LSHIFT and VKEY_RSHIFT), that indentify one of two specific
@@ -53,6 +87,12 @@
 EVENTS_BASE_EXPORT KeyboardCode
 NonLocatedToLocatedKeyboardCode(KeyboardCode key_code, DomCode dom_code);
 
+// Returns a DOM Level 3 |code| from a Windows-based VKEY value.
+// This assumes a US layout and should only be used when |code| cannot be
+// determined from a physical scan code, for example when a key event was
+// generated synthetically by JavaScript with only a VKEY value supplied.
+EVENTS_BASE_EXPORT DomCode UsLayoutKeyboardCodeToDomCode(KeyboardCode key_code);
+
 }  // namespace ui
 
 #endif  // UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_
diff --git a/ui/events/keycodes/keyboard_code_conversion_unittest.cc b/ui/events/keycodes/keyboard_code_conversion_unittest.cc
new file mode 100644
index 0000000..e22208a
--- /dev/null
+++ b/ui/events/keycodes/keyboard_code_conversion_unittest.cc
@@ -0,0 +1,523 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/keycodes/keyboard_code_conversion.h"
+
+#include "base/basictypes.h"
+#include "base/strings/stringprintf.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event_constants.h"
+#include "ui/events/keycodes/dom3/dom_code.h"
+#include "ui/events/keycodes/dom3/dom_key.h"
+#include "ui/events/keycodes/dom4/keycode_converter.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+namespace {
+
+struct Meaning {
+  bool defined;
+  ui::DomKey dom_key;
+  base::char16 character;
+  ui::KeyboardCode legacy_key_code;
+};
+
+const Meaning kUndefined = {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN};
+
+void CheckDomCodeToMeaning(const char* label,
+                           bool f(ui::DomCode dom_code,
+                                  int flags,
+                                  ui::DomKey* out_dom_key,
+                                  base::char16* out_character,
+                                  ui::KeyboardCode* out_key_code),
+                           ui::DomCode dom_code,
+                           int event_flags,
+                           const Meaning& result) {
+  ui::DomKey result_dom_key = ui::DomKey::NONE;
+  base::char16 result_character = 0;
+  ui::KeyboardCode result_legacy_key_code = ui::VKEY_UNKNOWN;
+  bool success = f(dom_code, event_flags, &result_dom_key, &result_character,
+                   &result_legacy_key_code);
+  SCOPED_TRACE(
+      base::StringPrintf("%s %s %06X:%04X", label,
+                         ui::KeycodeConverter::DomCodeToCodeString(dom_code),
+                         static_cast<int>(dom_code), event_flags));
+  EXPECT_EQ(result.defined, success);
+  if (success) {
+    EXPECT_EQ(result.dom_key, result_dom_key);
+    EXPECT_EQ(result.character, result_character);
+    EXPECT_EQ(result.legacy_key_code, result_legacy_key_code);
+  } else {
+    // Should not have touched output parameters.
+    EXPECT_EQ(ui::DomKey::NONE, result_dom_key);
+    EXPECT_EQ(0, result_character);
+    EXPECT_EQ(ui::VKEY_UNKNOWN, result_legacy_key_code);
+  }
+}
+
+TEST(KeyboardCodeConversion, ControlCharacters) {
+  // The codes in this table are handled by |DomCodeToControlCharacter()|.
+  static const struct {
+    ui::DomCode dom_code;
+    Meaning control;
+    Meaning control_shift;
+  } kControlCharacters[] = {
+      {ui::DomCode::KEY_A,
+       {true, ui::DomKey::CHARACTER, 0x01, ui::VKEY_A},
+       {true, ui::DomKey::CHARACTER, 0x01, ui::VKEY_A}},
+      {ui::DomCode::KEY_B,
+       {true, ui::DomKey::CHARACTER, 0x02, ui::VKEY_B},
+       {true, ui::DomKey::CHARACTER, 0x02, ui::VKEY_B}},
+      {ui::DomCode::KEY_C,
+       {true, ui::DomKey::CHARACTER, 0x03, ui::VKEY_C},
+       {true, ui::DomKey::CHARACTER, 0x03, ui::VKEY_C}},
+      {ui::DomCode::KEY_D,
+       {true, ui::DomKey::CHARACTER, 0x04, ui::VKEY_D},
+       {true, ui::DomKey::CHARACTER, 0x04, ui::VKEY_D}},
+      {ui::DomCode::KEY_E,
+       {true, ui::DomKey::CHARACTER, 0x05, ui::VKEY_E},
+       {true, ui::DomKey::CHARACTER, 0x05, ui::VKEY_E}},
+      {ui::DomCode::KEY_F,
+       {true, ui::DomKey::CHARACTER, 0x06, ui::VKEY_F},
+       {true, ui::DomKey::CHARACTER, 0x06, ui::VKEY_F}},
+      {ui::DomCode::KEY_G,
+       {true, ui::DomKey::CHARACTER, 0x07, ui::VKEY_G},
+       {true, ui::DomKey::CHARACTER, 0x07, ui::VKEY_G}},
+      {ui::DomCode::KEY_H,
+       {true, ui::DomKey::BACKSPACE, 0x08, ui::VKEY_BACK},
+       {true, ui::DomKey::BACKSPACE, 0x08, ui::VKEY_BACK}},
+      {ui::DomCode::KEY_I,
+       {true, ui::DomKey::TAB, 0x09, ui::VKEY_TAB},
+       {true, ui::DomKey::TAB, 0x09, ui::VKEY_TAB}},
+      {ui::DomCode::KEY_J,
+       {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_J},
+       {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_J}},
+      {ui::DomCode::KEY_K,
+       {true, ui::DomKey::CHARACTER, 0x0B, ui::VKEY_K},
+       {true, ui::DomKey::CHARACTER, 0x0B, ui::VKEY_K}},
+      {ui::DomCode::KEY_L,
+       {true, ui::DomKey::CHARACTER, 0x0C, ui::VKEY_L},
+       {true, ui::DomKey::CHARACTER, 0x0C, ui::VKEY_L}},
+      {ui::DomCode::KEY_M,
+       {true, ui::DomKey::ENTER, 0x0D, ui::VKEY_RETURN},
+       {true, ui::DomKey::ENTER, 0x0D, ui::VKEY_RETURN}},
+      {ui::DomCode::KEY_N,
+       {true, ui::DomKey::CHARACTER, 0x0E, ui::VKEY_N},
+       {true, ui::DomKey::CHARACTER, 0x0E, ui::VKEY_N}},
+      {ui::DomCode::KEY_O,
+       {true, ui::DomKey::CHARACTER, 0x0F, ui::VKEY_O},
+       {true, ui::DomKey::CHARACTER, 0x0F, ui::VKEY_O}},
+      {ui::DomCode::KEY_P,
+       {true, ui::DomKey::CHARACTER, 0x10, ui::VKEY_P},
+       {true, ui::DomKey::CHARACTER, 0x10, ui::VKEY_P}},
+      {ui::DomCode::KEY_Q,
+       {true, ui::DomKey::CHARACTER, 0x11, ui::VKEY_Q},
+       {true, ui::DomKey::CHARACTER, 0x11, ui::VKEY_Q}},
+      {ui::DomCode::KEY_R,
+       {true, ui::DomKey::CHARACTER, 0x12, ui::VKEY_R},
+       {true, ui::DomKey::CHARACTER, 0x12, ui::VKEY_R}},
+      {ui::DomCode::KEY_S,
+       {true, ui::DomKey::CHARACTER, 0x13, ui::VKEY_S},
+       {true, ui::DomKey::CHARACTER, 0x13, ui::VKEY_S}},
+      {ui::DomCode::KEY_T,
+       {true, ui::DomKey::CHARACTER, 0x14, ui::VKEY_T},
+       {true, ui::DomKey::CHARACTER, 0x14, ui::VKEY_T}},
+      {ui::DomCode::KEY_U,
+       {true, ui::DomKey::CHARACTER, 0x15, ui::VKEY_U},
+       {true, ui::DomKey::CHARACTER, 0x15, ui::VKEY_U}},
+      {ui::DomCode::KEY_V,
+       {true, ui::DomKey::CHARACTER, 0x16, ui::VKEY_V},
+       {true, ui::DomKey::CHARACTER, 0x16, ui::VKEY_V}},
+      {ui::DomCode::KEY_W,
+       {true, ui::DomKey::CHARACTER, 0x17, ui::VKEY_W},
+       {true, ui::DomKey::CHARACTER, 0x17, ui::VKEY_W}},
+      {ui::DomCode::KEY_X,
+       {true, ui::DomKey::CHARACTER, 0x18, ui::VKEY_X},
+       {true, ui::DomKey::CHARACTER, 0x18, ui::VKEY_X}},
+      {ui::DomCode::KEY_Y,
+       {true, ui::DomKey::CHARACTER, 0x19, ui::VKEY_Y},
+       {true, ui::DomKey::CHARACTER, 0x19, ui::VKEY_Y}},
+      {ui::DomCode::KEY_Z,
+       {true, ui::DomKey::CHARACTER, 0x1A, ui::VKEY_Z},
+       {true, ui::DomKey::CHARACTER, 0x1A, ui::VKEY_Z}},
+  };
+  for (const auto& it : kControlCharacters) {
+    // Verify |DomCodeToControlCharacter()|.
+    CheckDomCodeToMeaning("c_cc_n", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_NONE, kUndefined);
+    CheckDomCodeToMeaning("c_cc_c", ui::DomCodeToControlCharacter, it.dom_code,
+                           ui::EF_CONTROL_DOWN, it.control);
+    CheckDomCodeToMeaning("c_cc_cs", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
+                          it.control_shift);
+    // Verify |DomCodeToUsLayoutMeaning()|.
+    CheckDomCodeToMeaning("c_us_c", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_CONTROL_DOWN, it.control);
+    CheckDomCodeToMeaning("c_us_cs", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
+                          it.control_shift);
+  }
+
+  // The codes in this table are sensitive to the Shift state, so they are
+  // handled differently by |DomCodeToControlCharacter()|, which returns false
+  // for unknown combinations, vs |DomCodeToUsLayoutMeaning()|, which returns
+  // true with DomKey::UNIDENTIFIED.
+  static const struct {
+    ui::DomCode dom_code;
+    Meaning cc_control;
+    Meaning cc_control_shift;
+    Meaning us_control;
+    Meaning us_control_shift;
+  } kShiftControlCharacters[] = {
+      {ui::DomCode::DIGIT2,
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0, ui::VKEY_2},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_2},
+       {true, ui::DomKey::CHARACTER, 0, ui::VKEY_2}},
+      {ui::DomCode::DIGIT6,
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0x1E, ui::VKEY_6},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_6},
+       {true, ui::DomKey::CHARACTER, 0x1E, ui::VKEY_6}},
+      {ui::DomCode::MINUS,
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0x1F, ui::VKEY_OEM_MINUS},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_MINUS},
+       {true, ui::DomKey::CHARACTER, 0x1F, ui::VKEY_OEM_MINUS}},
+      {ui::DomCode::ENTER,
+       {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_RETURN},
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_RETURN},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_RETURN}},
+      {ui::DomCode::BRACKET_LEFT,
+       {true, ui::DomKey::ESCAPE, 0x1B, ui::VKEY_OEM_4},
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::ESCAPE, 0x1B, ui::VKEY_OEM_4},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_4}},
+      {ui::DomCode::BACKSLASH,
+       {true, ui::DomKey::CHARACTER, 0x1C, ui::VKEY_OEM_5},
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0x1C, ui::VKEY_OEM_5},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_5}},
+      {ui::DomCode::BRACKET_RIGHT,
+       {true, ui::DomKey::CHARACTER, 0x1D, ui::VKEY_OEM_6},
+       {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0x1D, ui::VKEY_OEM_6},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_6}},
+  };
+  for (const auto& it : kShiftControlCharacters) {
+    // Verify |DomCodeToControlCharacter()|.
+    CheckDomCodeToMeaning("s_cc_n", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_NONE, kUndefined);
+    CheckDomCodeToMeaning("s_cc_c", ui::DomCodeToControlCharacter, it.dom_code,
+                           ui::EF_CONTROL_DOWN, it.cc_control);
+    CheckDomCodeToMeaning("s_cc_cs", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
+                          it.cc_control_shift);
+    // Verify |DomCodeToUsLayoutMeaning()|.
+    CheckDomCodeToMeaning("s_us_c", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_CONTROL_DOWN, it.us_control);
+    CheckDomCodeToMeaning("s_us_cs", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
+                          it.us_control_shift);
+  }
+
+  // These codes are not handled by |DomCodeToControlCharacter()| directly.
+  static const struct {
+    ui::DomCode dom_code;
+    Meaning normal;
+    Meaning control;
+  } kNonControlCharacters[] = {
+      // Modifiers are handled by |DomCodeToUsLayoutMeaning()| without regard
+      // to whether Control is down.
+      {ui::DomCode::CONTROL_LEFT,
+       {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL},
+       {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL}},
+      {ui::DomCode::CONTROL_RIGHT,
+       {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL},
+       {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL}},
+      {ui::DomCode::SHIFT_LEFT,
+       {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT},
+       {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT}},
+      {ui::DomCode::SHIFT_RIGHT,
+       {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT},
+       {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT}},
+      {ui::DomCode::ALT_LEFT,
+       {true, ui::DomKey::ALT, 0, ui::VKEY_MENU},
+       {true, ui::DomKey::ALT, 0, ui::VKEY_MENU}},
+      {ui::DomCode::ALT_RIGHT,
+       {true, ui::DomKey::ALT, 0, ui::VKEY_MENU},
+       {true, ui::DomKey::ALT, 0, ui::VKEY_MENU}},
+      {ui::DomCode::OS_LEFT,
+       {true, ui::DomKey::OS, 0, ui::VKEY_LWIN},
+       {true, ui::DomKey::OS, 0, ui::VKEY_LWIN}},
+      {ui::DomCode::OS_RIGHT,
+       {true, ui::DomKey::OS, 0, ui::VKEY_LWIN},
+       {true, ui::DomKey::OS, 0, ui::VKEY_LWIN}},
+      // Non-modifiers (a representative sample here) succeed with
+      // DomKey::UNIDENTIFIED when Control is down.
+      {ui::DomCode::DIGIT1,
+       {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_1}},
+      {ui::DomCode::EQUAL,
+       {true, ui::DomKey::CHARACTER, '=', ui::VKEY_OEM_PLUS},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_PLUS}},
+      {ui::DomCode::TAB,
+       {true, ui::DomKey::TAB, 9, ui::VKEY_TAB},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_TAB}},
+      {ui::DomCode::F1,
+       {true, ui::DomKey::F1, 0, ui::VKEY_F1},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_F1}},
+      {ui::DomCode::VOLUME_UP,
+       {true, ui::DomKey::VOLUME_UP, 0, ui::VKEY_VOLUME_UP},
+       {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_VOLUME_UP}},
+  };
+  for (const auto& it : kNonControlCharacters) {
+    // Verify |DomCodeToControlCharacter()|.
+    CheckDomCodeToMeaning("n_cc_n", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_NONE, kUndefined);
+    CheckDomCodeToMeaning("n_cc_c", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_CONTROL_DOWN, kUndefined);
+    CheckDomCodeToMeaning("n_cc_cs", ui::DomCodeToControlCharacter, it.dom_code,
+                          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, kUndefined);
+    // Verify |DomCodeToUsLayoutMeaning()|.
+    CheckDomCodeToMeaning("n_us_n", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_NONE, it.normal);
+    CheckDomCodeToMeaning("n_us_c", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_CONTROL_DOWN, it.control);
+    CheckDomCodeToMeaning("n_us_cs", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, it.control);
+  }
+}
+
+TEST(KeyboardCodeConversion, UsLayout) {
+  static const struct {
+    ui::DomCode dom_code;
+    Meaning normal;
+    Meaning shift;
+  } kPrintableUsLayout[] = {
+      {ui::DomCode::KEY_A,
+       {true, ui::DomKey::CHARACTER, 'a', ui::VKEY_A},
+       {true, ui::DomKey::CHARACTER, 'A', ui::VKEY_A}},
+      {ui::DomCode::KEY_B,
+       {true, ui::DomKey::CHARACTER, 'b', ui::VKEY_B},
+       {true, ui::DomKey::CHARACTER, 'B', ui::VKEY_B}},
+      {ui::DomCode::KEY_C,
+       {true, ui::DomKey::CHARACTER, 'c', ui::VKEY_C},
+       {true, ui::DomKey::CHARACTER, 'C', ui::VKEY_C}},
+      {ui::DomCode::KEY_D,
+       {true, ui::DomKey::CHARACTER, 'd', ui::VKEY_D},
+       {true, ui::DomKey::CHARACTER, 'D', ui::VKEY_D}},
+      {ui::DomCode::KEY_E,
+       {true, ui::DomKey::CHARACTER, 'e', ui::VKEY_E},
+       {true, ui::DomKey::CHARACTER, 'E', ui::VKEY_E}},
+      {ui::DomCode::KEY_F,
+       {true, ui::DomKey::CHARACTER, 'f', ui::VKEY_F},
+       {true, ui::DomKey::CHARACTER, 'F', ui::VKEY_F}},
+      {ui::DomCode::KEY_G,
+       {true, ui::DomKey::CHARACTER, 'g', ui::VKEY_G},
+       {true, ui::DomKey::CHARACTER, 'G', ui::VKEY_G}},
+      {ui::DomCode::KEY_H,
+       {true, ui::DomKey::CHARACTER, 'h', ui::VKEY_H},
+       {true, ui::DomKey::CHARACTER, 'H', ui::VKEY_H}},
+      {ui::DomCode::KEY_I,
+       {true, ui::DomKey::CHARACTER, 'i', ui::VKEY_I},
+       {true, ui::DomKey::CHARACTER, 'I', ui::VKEY_I}},
+      {ui::DomCode::KEY_J,
+       {true, ui::DomKey::CHARACTER, 'j', ui::VKEY_J},
+       {true, ui::DomKey::CHARACTER, 'J', ui::VKEY_J}},
+      {ui::DomCode::KEY_K,
+       {true, ui::DomKey::CHARACTER, 'k', ui::VKEY_K},
+       {true, ui::DomKey::CHARACTER, 'K', ui::VKEY_K}},
+      {ui::DomCode::KEY_L,
+       {true, ui::DomKey::CHARACTER, 'l', ui::VKEY_L},
+       {true, ui::DomKey::CHARACTER, 'L', ui::VKEY_L}},
+      {ui::DomCode::KEY_M,
+       {true, ui::DomKey::CHARACTER, 'm', ui::VKEY_M},
+       {true, ui::DomKey::CHARACTER, 'M', ui::VKEY_M}},
+      {ui::DomCode::KEY_N,
+       {true, ui::DomKey::CHARACTER, 'n', ui::VKEY_N},
+       {true, ui::DomKey::CHARACTER, 'N', ui::VKEY_N}},
+      {ui::DomCode::KEY_O,
+       {true, ui::DomKey::CHARACTER, 'o', ui::VKEY_O},
+       {true, ui::DomKey::CHARACTER, 'O', ui::VKEY_O}},
+      {ui::DomCode::KEY_P,
+       {true, ui::DomKey::CHARACTER, 'p', ui::VKEY_P},
+       {true, ui::DomKey::CHARACTER, 'P', ui::VKEY_P}},
+      {ui::DomCode::KEY_Q,
+       {true, ui::DomKey::CHARACTER, 'q', ui::VKEY_Q},
+       {true, ui::DomKey::CHARACTER, 'Q', ui::VKEY_Q}},
+      {ui::DomCode::KEY_R,
+       {true, ui::DomKey::CHARACTER, 'r', ui::VKEY_R},
+       {true, ui::DomKey::CHARACTER, 'R', ui::VKEY_R}},
+      {ui::DomCode::KEY_S,
+       {true, ui::DomKey::CHARACTER, 's', ui::VKEY_S},
+       {true, ui::DomKey::CHARACTER, 'S', ui::VKEY_S}},
+      {ui::DomCode::KEY_T,
+       {true, ui::DomKey::CHARACTER, 't', ui::VKEY_T},
+       {true, ui::DomKey::CHARACTER, 'T', ui::VKEY_T}},
+      {ui::DomCode::KEY_U,
+       {true, ui::DomKey::CHARACTER, 'u', ui::VKEY_U},
+       {true, ui::DomKey::CHARACTER, 'U', ui::VKEY_U}},
+      {ui::DomCode::KEY_V,
+       {true, ui::DomKey::CHARACTER, 'v', ui::VKEY_V},
+       {true, ui::DomKey::CHARACTER, 'V', ui::VKEY_V}},
+      {ui::DomCode::KEY_W,
+       {true, ui::DomKey::CHARACTER, 'w', ui::VKEY_W},
+       {true, ui::DomKey::CHARACTER, 'W', ui::VKEY_W}},
+      {ui::DomCode::KEY_X,
+       {true, ui::DomKey::CHARACTER, 'x', ui::VKEY_X},
+       {true, ui::DomKey::CHARACTER, 'X', ui::VKEY_X}},
+      {ui::DomCode::KEY_Y,
+       {true, ui::DomKey::CHARACTER, 'y', ui::VKEY_Y},
+       {true, ui::DomKey::CHARACTER, 'Y', ui::VKEY_Y}},
+      {ui::DomCode::KEY_Z,
+       {true, ui::DomKey::CHARACTER, 'z', ui::VKEY_Z},
+       {true, ui::DomKey::CHARACTER, 'Z', ui::VKEY_Z}},
+      {ui::DomCode::DIGIT1,
+       {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1},
+       {true, ui::DomKey::CHARACTER, '!', ui::VKEY_1}},
+      {ui::DomCode::DIGIT2,
+       {true, ui::DomKey::CHARACTER, '2', ui::VKEY_2},
+       {true, ui::DomKey::CHARACTER, '@', ui::VKEY_2}},
+      {ui::DomCode::DIGIT3,
+       {true, ui::DomKey::CHARACTER, '3', ui::VKEY_3},
+       {true, ui::DomKey::CHARACTER, '#', ui::VKEY_3}},
+      {ui::DomCode::DIGIT4,
+       {true, ui::DomKey::CHARACTER, '4', ui::VKEY_4},
+       {true, ui::DomKey::CHARACTER, '$', ui::VKEY_4}},
+      {ui::DomCode::DIGIT5,
+       {true, ui::DomKey::CHARACTER, '5', ui::VKEY_5},
+       {true, ui::DomKey::CHARACTER, '%', ui::VKEY_5}},
+      {ui::DomCode::DIGIT6,
+       {true, ui::DomKey::CHARACTER, '6', ui::VKEY_6},
+       {true, ui::DomKey::CHARACTER, '^', ui::VKEY_6}},
+      {ui::DomCode::DIGIT7,
+       {true, ui::DomKey::CHARACTER, '7', ui::VKEY_7},
+       {true, ui::DomKey::CHARACTER, '&', ui::VKEY_7}},
+      {ui::DomCode::DIGIT8,
+       {true, ui::DomKey::CHARACTER, '8', ui::VKEY_8},
+       {true, ui::DomKey::CHARACTER, '*', ui::VKEY_8}},
+      {ui::DomCode::DIGIT9,
+       {true, ui::DomKey::CHARACTER, '9', ui::VKEY_9},
+       {true, ui::DomKey::CHARACTER, '(', ui::VKEY_9}},
+      {ui::DomCode::DIGIT0,
+       {true, ui::DomKey::CHARACTER, '0', ui::VKEY_0},
+       {true, ui::DomKey::CHARACTER, ')', ui::VKEY_0}},
+      {ui::DomCode::SPACE,
+       {true, ui::DomKey::CHARACTER, ' ', ui::VKEY_SPACE},
+       {true, ui::DomKey::CHARACTER, ' ', ui::VKEY_SPACE}},
+      {ui::DomCode::MINUS,
+       {true, ui::DomKey::CHARACTER, '-', ui::VKEY_OEM_MINUS},
+       {true, ui::DomKey::CHARACTER, '_', ui::VKEY_OEM_MINUS}},
+      {ui::DomCode::EQUAL,
+       {true, ui::DomKey::CHARACTER, '=', ui::VKEY_OEM_PLUS},
+       {true, ui::DomKey::CHARACTER, '+', ui::VKEY_OEM_PLUS}},
+      {ui::DomCode::BRACKET_LEFT,
+       {true, ui::DomKey::CHARACTER, '[', ui::VKEY_OEM_4},
+       {true, ui::DomKey::CHARACTER, '{', ui::VKEY_OEM_4}},
+      {ui::DomCode::BRACKET_RIGHT,
+       {true, ui::DomKey::CHARACTER, ']', ui::VKEY_OEM_6},
+       {true, ui::DomKey::CHARACTER, '}', ui::VKEY_OEM_6}},
+      {ui::DomCode::BACKSLASH,
+       {true, ui::DomKey::CHARACTER, '\\', ui::VKEY_OEM_5},
+       {true, ui::DomKey::CHARACTER, '|', ui::VKEY_OEM_5}},
+      {ui::DomCode::SEMICOLON,
+       {true, ui::DomKey::CHARACTER, ';', ui::VKEY_OEM_1},
+       {true, ui::DomKey::CHARACTER, ':', ui::VKEY_OEM_1}},
+      {ui::DomCode::QUOTE,
+       {true, ui::DomKey::CHARACTER, '\'', ui::VKEY_OEM_7},
+       {true, ui::DomKey::CHARACTER, '"', ui::VKEY_OEM_7}},
+      {ui::DomCode::BACKQUOTE,
+       {true, ui::DomKey::CHARACTER, '`', ui::VKEY_OEM_3},
+       {true, ui::DomKey::CHARACTER, '~', ui::VKEY_OEM_3}},
+      {ui::DomCode::COMMA,
+       {true, ui::DomKey::CHARACTER, ',', ui::VKEY_OEM_COMMA},
+       {true, ui::DomKey::CHARACTER, '<', ui::VKEY_OEM_COMMA}},
+      {ui::DomCode::PERIOD,
+       {true, ui::DomKey::CHARACTER, '.', ui::VKEY_OEM_PERIOD},
+       {true, ui::DomKey::CHARACTER, '>', ui::VKEY_OEM_PERIOD}},
+      {ui::DomCode::SLASH,
+       {true, ui::DomKey::CHARACTER, '/', ui::VKEY_OEM_2},
+       {true, ui::DomKey::CHARACTER, '?', ui::VKEY_OEM_2}},
+      {ui::DomCode::INTL_BACKSLASH,
+       {true, ui::DomKey::CHARACTER, '\\', ui::VKEY_OEM_102},
+       {true, ui::DomKey::CHARACTER, '|', ui::VKEY_OEM_102}},
+      {ui::DomCode::INTL_YEN,
+       {true, ui::DomKey::CHARACTER, 0x00A5, ui::VKEY_OEM_5},
+       {true, ui::DomKey::CHARACTER, '|', ui::VKEY_OEM_5}},
+      {ui::DomCode::NUMPAD_DIVIDE,
+       {true, ui::DomKey::CHARACTER, '/', ui::VKEY_DIVIDE},
+       {true, ui::DomKey::CHARACTER, '/', ui::VKEY_DIVIDE}},
+      {ui::DomCode::NUMPAD_MULTIPLY,
+       {true, ui::DomKey::CHARACTER, '*', ui::VKEY_MULTIPLY},
+       {true, ui::DomKey::CHARACTER, '*', ui::VKEY_MULTIPLY}},
+      {ui::DomCode::NUMPAD_SUBTRACT,
+       {true, ui::DomKey::CHARACTER, '-', ui::VKEY_SUBTRACT},
+       {true, ui::DomKey::CHARACTER, '-', ui::VKEY_SUBTRACT}},
+      {ui::DomCode::NUMPAD_ADD,
+       {true, ui::DomKey::CHARACTER, '+', ui::VKEY_ADD},
+       {true, ui::DomKey::CHARACTER, '+', ui::VKEY_ADD}},
+      {ui::DomCode::NUMPAD1,
+       {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1},
+       {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1}},
+      {ui::DomCode::NUMPAD2,
+       {true, ui::DomKey::CHARACTER, '2', ui::VKEY_2},
+       {true, ui::DomKey::CHARACTER, '2', ui::VKEY_2}},
+      {ui::DomCode::NUMPAD3,
+       {true, ui::DomKey::CHARACTER, '3', ui::VKEY_3},
+       {true, ui::DomKey::CHARACTER, '3', ui::VKEY_3}},
+      {ui::DomCode::NUMPAD4,
+       {true, ui::DomKey::CHARACTER, '4', ui::VKEY_4},
+       {true, ui::DomKey::CHARACTER, '4', ui::VKEY_4}},
+      {ui::DomCode::NUMPAD5,
+       {true, ui::DomKey::CHARACTER, '5', ui::VKEY_5},
+       {true, ui::DomKey::CHARACTER, '5', ui::VKEY_5}},
+      {ui::DomCode::NUMPAD6,
+       {true, ui::DomKey::CHARACTER, '6', ui::VKEY_6},
+       {true, ui::DomKey::CHARACTER, '6', ui::VKEY_6}},
+      {ui::DomCode::NUMPAD7,
+       {true, ui::DomKey::CHARACTER, '7', ui::VKEY_7},
+       {true, ui::DomKey::CHARACTER, '7', ui::VKEY_7}},
+      {ui::DomCode::NUMPAD8,
+       {true, ui::DomKey::CHARACTER, '8', ui::VKEY_8},
+       {true, ui::DomKey::CHARACTER, '8', ui::VKEY_8}},
+      {ui::DomCode::NUMPAD9,
+       {true, ui::DomKey::CHARACTER, '9', ui::VKEY_9},
+       {true, ui::DomKey::CHARACTER, '9', ui::VKEY_9}},
+      {ui::DomCode::NUMPAD0,
+       {true, ui::DomKey::CHARACTER, '0', ui::VKEY_0},
+       {true, ui::DomKey::CHARACTER, '0', ui::VKEY_0}},
+      {ui::DomCode::NUMPAD_DECIMAL,
+       {true, ui::DomKey::CHARACTER, '.', ui::VKEY_DECIMAL},
+       {true, ui::DomKey::CHARACTER, '.', ui::VKEY_DECIMAL}},
+      {ui::DomCode::NUMPAD_EQUAL,
+       {true, ui::DomKey::CHARACTER, '=', ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, '=', ui::VKEY_UNKNOWN}},
+      {ui::DomCode::NUMPAD_COMMA,
+       {true, ui::DomKey::CHARACTER, ',', ui::VKEY_OEM_COMMA},
+       {true, ui::DomKey::CHARACTER, ',', ui::VKEY_OEM_COMMA}},
+      {ui::DomCode::NUMPAD_PAREN_LEFT,
+       {true, ui::DomKey::CHARACTER, '(', ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, '(', ui::VKEY_UNKNOWN}},
+      {ui::DomCode::NUMPAD_PAREN_RIGHT,
+       {true, ui::DomKey::CHARACTER, ')', ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, ')', ui::VKEY_UNKNOWN}},
+      {ui::DomCode::NUMPAD_SIGN_CHANGE,
+       {true, ui::DomKey::CHARACTER, 0xB1, ui::VKEY_UNKNOWN},
+       {true, ui::DomKey::CHARACTER, 0xB1, ui::VKEY_UNKNOWN}},
+  };
+
+  for (const auto& it : kPrintableUsLayout) {
+    CheckDomCodeToMeaning("p_us_n", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_NONE, it.normal);
+    CheckDomCodeToMeaning("p_us_s", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_SHIFT_DOWN, it.shift);
+    CheckDomCodeToMeaning("p_us_a", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_ALTGR_DOWN, it.normal);
+    CheckDomCodeToMeaning("p_us_a", ui::DomCodeToUsLayoutMeaning, it.dom_code,
+                          ui::EF_ALTGR_DOWN|ui::EF_SHIFT_DOWN, it.shift);
+  }
+}
+
+}  // namespace
diff --git a/ui/events/latency_info.cc b/ui/events/latency_info.cc
index 9718aa4..112cc462 100644
--- a/ui/events/latency_info.cc
+++ b/ui/events/latency_info.cc
@@ -2,14 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ui/events/latency_info.h"
+
+#include <algorithm>
+#include <string>
+
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
-#include "ui/events/latency_info.h"
-
-#include <algorithm>
 
 namespace {
 
@@ -216,8 +218,17 @@
 void LatencyInfo::AddLatencyNumber(LatencyComponentType component,
                                    int64 id,
                                    int64 component_sequence_number) {
-  AddLatencyNumberWithTimestamp(component, id, component_sequence_number,
-                                base::TimeTicks::Now(), 1);
+  AddLatencyNumberWithTimestampImpl(component, id, component_sequence_number,
+                                    base::TimeTicks::Now(), 1, nullptr);
+}
+
+void LatencyInfo::AddLatencyNumberWithTraceName(
+    LatencyComponentType component,
+    int64 id,
+    int64 component_sequence_number,
+    const char* trace_name_str) {
+  AddLatencyNumberWithTimestampImpl(component, id, component_sequence_number,
+                                    base::TimeTicks::Now(), 1, trace_name_str);
 }
 
 void LatencyInfo::AddLatencyNumberWithTimestamp(LatencyComponentType component,
@@ -225,10 +236,24 @@
                                                 int64 component_sequence_number,
                                                 base::TimeTicks time,
                                                 uint32 event_count) {
+  AddLatencyNumberWithTimestampImpl(component, id, component_sequence_number,
+                                    time, event_count, nullptr);
+}
+
+void LatencyInfo::AddLatencyNumberWithTimestampImpl(
+    LatencyComponentType component,
+    int64 id,
+    int64 component_sequence_number,
+    base::TimeTicks time,
+    uint32 event_count,
+    const char* trace_name_str) {
 
   const unsigned char* benchmark_enabled =
       g_benchmark_enabled.Get().benchmark_enabled;
 
+  if (*benchmark_enabled && trace_name_str)
+    trace_name = trace_name_str;
+
   if (IsBeginComponent(component)) {
     // Should only ever add begin component once.
     CHECK_EQ(-1, trace_id);
@@ -260,9 +285,9 @@
       } else {
         ts = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue();
       }
-      TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(
+      TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(
           "benchmark",
-          "InputLatency",
+          ("InputLatency::" + trace_name).c_str(),
           TRACE_ID_DONT_MANGLE(trace_id),
           ts);
     }
@@ -296,10 +321,10 @@
     terminated = true;
 
     if (*benchmark_enabled) {
-      TRACE_EVENT_ASYNC_END1("benchmark",
-                             "InputLatency",
-                             TRACE_ID_DONT_MANGLE(trace_id),
-                             "data", AsTraceableData(*this));
+      TRACE_EVENT_COPY_ASYNC_END1("benchmark",
+                                  ("InputLatency::" + trace_name).c_str(),
+                                  TRACE_ID_DONT_MANGLE(trace_id),
+                                  "data", AsTraceableData(*this));
     }
 
     TRACE_EVENT_FLOW_END0(
@@ -336,11 +361,4 @@
   latency_components.clear();
 }
 
-void LatencyInfo::TraceEventType(const char* event_type) {
-  TRACE_EVENT_ASYNC_STEP_INTO0("benchmark",
-                               "InputLatency",
-                               TRACE_ID_DONT_MANGLE(trace_id),
-                               event_type);
-}
-
 }  // namespace ui
diff --git a/ui/events/latency_info.h b/ui/events/latency_info.h
index eaac5ce..1c6ceef 100644
--- a/ui/events/latency_info.h
+++ b/ui/events/latency_info.h
@@ -5,6 +5,7 @@
 #ifndef UI_EVENTS_LATENCY_INFO_H_
 #define UI_EVENTS_LATENCY_INFO_H_
 
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -143,6 +144,14 @@
                         int64 id,
                         int64 component_sequence_number);
 
+  // Similar to |AddLatencyNumber|, and also appends |trace_name_str| to
+  // the trace event's name.
+  // This function should only be called when adding a BEGIN component.
+  void AddLatencyNumberWithTraceName(LatencyComponentType component,
+                                     int64 id,
+                                     int64 component_sequence_number,
+                                     const char* trace_name_str);
+
   // Modifies the current sequence number and adds a certain number of events
   // for a specific component.
   void AddLatencyNumberWithTimestamp(LatencyComponentType component,
@@ -151,6 +160,13 @@
                                      base::TimeTicks time,
                                      uint32 event_count);
 
+  void AddLatencyNumberWithTimestampImpl(LatencyComponentType component,
+                                         int64 id,
+                                         int64 component_sequence_number,
+                                         base::TimeTicks time,
+                                         uint32 event_count,
+                                         const char* trace_name_str);
+
   // Returns true if the a component with |type| and |id| is found in
   // the latency_components and the component is stored to |output| if
   // |output| is not NULL. Returns false if no such component is found.
@@ -162,8 +178,9 @@
 
   void Clear();
 
-  // Records the |event_type| in trace buffer as TRACE_EVENT_ASYNC_STEP.
-  void TraceEventType(const char* event_type);
+  // Shown as part of the name of the trace event for this LatencyInfo.
+  // String is empty if no tracing is enabled.
+  std::string trace_name;
 
   LatencyMap latency_components;
 
diff --git a/ui/events/latency_info_nacl.gyp b/ui/events/latency_info_nacl.gyp
index c44e499..1b7e402 100644
--- a/ui/events/latency_info_nacl.gyp
+++ b/ui/events/latency_info_nacl.gyp
@@ -23,7 +23,6 @@
             '../../base/base_nacl.gyp:base_nacl_nonsfi',
             '../../ipc/ipc_nacl.gyp:ipc_nacl',
             '../../ipc/ipc_nacl.gyp:ipc_nacl_nonsfi',
-            '../../native_client/tools.gyp:prep_toolchain'
           ],
           'variables': {
             'nacl_untrusted_build': 1,
diff --git a/ui/events/ozone/device/udev/device_manager_udev.cc b/ui/events/ozone/device/udev/device_manager_udev.cc
index 884e418..4e28e39 100644
--- a/ui/events/ozone/device/udev/device_manager_udev.cc
+++ b/ui/events/ozone/device/udev/device_manager_udev.cc
@@ -134,7 +134,7 @@
 void DeviceManagerUdev::OnFileCanReadWithoutBlocking(int fd) {
   // The netlink socket should never become disconnected. There's no need
   // to handle broken connections here.
-  TRACE_EVENT1("ozone", "UdevDeviceChange", "socket", fd);
+  TRACE_EVENT1("evdev", "UdevDeviceChange", "socket", fd);
 
   device::ScopedUdevDevicePtr device(
       device::udev_monitor_receive_device(monitor_.get()));
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc
index e9098db41..6eb45d9 100644
--- a/ui/events/ozone/evdev/event_factory_evdev.cc
+++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -150,12 +150,16 @@
 }
 
 void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) {
+  TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchKeyEvent", "device",
+               params.device_id);
   keyboard_.OnKeyChange(params.code, params.down, params.timestamp,
                         params.device_id);
 }
 
 void EventFactoryEvdev::DispatchMouseMoveEvent(
     const MouseMoveEventParams& params) {
+  TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseMoveEvent", "device",
+               params.device_id);
   MouseEvent event(ui::ET_MOUSE_MOVED, params.location, params.location,
                    params.timestamp, modifiers_.GetModifierFlags(),
                    /* changed_button_flags */ 0);
@@ -165,6 +169,9 @@
 
 void EventFactoryEvdev::DispatchMouseButtonEvent(
     const MouseButtonEventParams& params) {
+  TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseButtonEvent", "device",
+               params.device_id);
+
   // Mouse buttons can be remapped, touchpad taps & clicks cannot.
   unsigned int button = params.button;
   if (params.allow_remap)
@@ -204,6 +211,8 @@
 
 void EventFactoryEvdev::DispatchMouseWheelEvent(
     const MouseWheelEventParams& params) {
+  TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseWheelEvent", "device",
+               params.device_id);
   MouseWheelEvent event(params.delta, params.location, params.location,
                         params.timestamp, modifiers_.GetModifierFlags(),
                         0 /* changed_button_flags */);
@@ -212,6 +221,8 @@
 }
 
 void EventFactoryEvdev::DispatchScrollEvent(const ScrollEventParams& params) {
+  TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchScrollEvent", "device",
+               params.device_id);
   ScrollEvent event(params.type, params.location, params.timestamp,
                     modifiers_.GetModifierFlags(), params.delta.x(),
                     params.delta.y(), params.ordinal_delta.x(),
@@ -221,6 +232,9 @@
 }
 
 void EventFactoryEvdev::DispatchTouchEvent(const TouchEventParams& params) {
+  TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchTouchEvent", "device",
+               params.device_id);
+
   float x = params.location.x();
   float y = params.location.y();
   double radius_x = params.radii.x();
@@ -257,18 +271,22 @@
 
 void EventFactoryEvdev::DispatchKeyboardDevicesUpdated(
     const std::vector<KeyboardDevice>& devices) {
+  TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchKeyboardDevicesUpdated");
   DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
   observer->OnKeyboardDevicesUpdated(devices);
 }
 
 void EventFactoryEvdev::DispatchTouchscreenDevicesUpdated(
     const std::vector<TouchscreenDevice>& devices) {
+  TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchTouchscreenDevicesUpdated");
   DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
   observer->OnTouchscreenDevicesUpdated(devices);
 }
 
 void EventFactoryEvdev::DispatchMouseDevicesUpdated(
     const std::vector<InputDevice>& devices) {
+  TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchMouseDevicesUpdated");
+
   // There's no list of mice in DeviceDataManager.
   input_controller_.set_has_mouse(devices.size() != 0);
   DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
@@ -277,6 +295,8 @@
 
 void EventFactoryEvdev::DispatchTouchpadDevicesUpdated(
     const std::vector<InputDevice>& devices) {
+  TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchTouchpadDevicesUpdated");
+
   // There's no list of touchpads in DeviceDataManager.
   input_controller_.set_has_touchpad(devices.size() != 0);
   DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
@@ -291,12 +311,14 @@
   switch (event.action_type()) {
     case DeviceEvent::ADD:
     case DeviceEvent::CHANGE: {
-      TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value());
+      TRACE_EVENT1("evdev", "EventFactoryEvdev::OnDeviceAdded", "path",
+                   event.path().value());
       input_device_factory_proxy_->AddInputDevice(NextDeviceId(), event.path());
       break;
     }
     case DeviceEvent::REMOVE: {
-      TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value());
+      TRACE_EVENT1("evdev", "EventFactoryEvdev::OnDeviceRemoved", "path",
+                   event.path().value());
       input_device_factory_proxy_->RemoveInputDevice(event.path());
       break;
     }
@@ -339,6 +361,7 @@
 
 void EventFactoryEvdev::OnThreadStarted(
     scoped_ptr<InputDeviceFactoryEvdevProxy> input_device_factory) {
+  TRACE_EVENT0("evdev", "EventFactoryEvdev::OnThreadStarted");
   input_device_factory_proxy_ = input_device_factory.Pass();
 
   // Hook up device configuration.
diff --git a/ui/events/ozone/evdev/event_thread_evdev.cc b/ui/events/ozone/evdev/event_thread_evdev.cc
index d6c5ffc..efee406 100644
--- a/ui/events/ozone/evdev/event_thread_evdev.cc
+++ b/ui/events/ozone/evdev/event_thread_evdev.cc
@@ -33,7 +33,7 @@
   ~EvdevThread() override { Stop(); }
 
   void Init() override {
-    TRACE_EVENT0("ozone", "EvdevThread::Init");
+    TRACE_EVENT0("evdev", "EvdevThread::Init");
     input_device_factory_ =
         new InputDeviceFactoryEvdev(dispatcher_.Pass(), cursor_);
 
@@ -46,7 +46,7 @@
   }
 
   void CleanUp() override {
-    TRACE_EVENT0("ozone", "EvdevThread::CleanUp");
+    TRACE_EVENT0("evdev", "EvdevThread::CleanUp");
     delete input_device_factory_;
   }
 
@@ -72,7 +72,7 @@
 void EventThreadEvdev::Start(scoped_ptr<DeviceEventDispatcherEvdev> dispatcher,
                              CursorDelegateEvdev* cursor,
                              const EventThreadStartCallback& callback) {
-  TRACE_EVENT0("ozone", "EventThreadEvdev::Start");
+  TRACE_EVENT0("evdev", "EventThreadEvdev::Start");
   thread_.reset(new EvdevThread(dispatcher.Pass(), cursor, callback));
   if (!thread_->StartWithOptions(
           base::Thread::Options(base::MessageLoop::TYPE_UI, 0)))
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc
index d8997ca..11a8f1e 100644
--- a/ui/events/ozone/evdev/input_device_factory_evdev.cc
+++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -130,7 +130,7 @@
   const base::FilePath& path = params->path;
   scoped_ptr<EventConverterEvdev> converter;
 
-  TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value());
+  TRACE_EVENT1("evdev", "OpenInputDevice", "path", path.value());
 
   int fd = open(path.value().c_str(), O_RDWR | O_NONBLOCK);
   if (fd < 0) {
@@ -170,7 +170,7 @@
 // run it on the FILE thread.
 void CloseInputDevice(const base::FilePath& path,
                       scoped_ptr<EventConverterEvdev> converter) {
-  TRACE_EVENT1("ozone", "CloseInputDevice", "path", path.value());
+  TRACE_EVENT1("evdev", "CloseInputDevice", "path", path.value());
   converter.reset();
 }
 
@@ -232,7 +232,7 @@
   if (converter.get()) {
     const base::FilePath& path = converter->path();
 
-    TRACE_EVENT1("ozone", "AttachInputDevice", "path", path.value());
+    TRACE_EVENT1("evdev", "AttachInputDevice", "path", path.value());
     DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
     // If we have an existing device, detach it. We don't want two
@@ -255,7 +255,7 @@
 }
 
 void InputDeviceFactoryEvdev::DetachInputDevice(const base::FilePath& path) {
-  TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value());
+  TRACE_EVENT1("evdev", "DetachInputDevice", "path", path.value());
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
   // Remove device from map.
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
index b4c09292..5b7b2596 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -28,6 +28,7 @@
 #include "ui/events/event.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/event_switches.h"
+#include "ui/events/event_utils.h"
 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
 #include "ui/events/ozone/evdev/touch_evdev_types.h"
 #include "ui/events/ozone/evdev/touch_noise/touch_noise_finder.h"
@@ -74,6 +75,8 @@
   }
 }
 
+const int kTrackingIdForUnusedSlot = -1;
+
 }  // namespace
 
 namespace ui {
@@ -154,8 +157,8 @@
     for (size_t i = 0; i < events_.size(); ++i) {
       events_[i].x = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_X, i, 0);
       events_[i].y = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_Y, i, 0);
-      events_[i].tracking_id =
-          info.GetAbsMtSlotValueWithDefault(ABS_MT_TRACKING_ID, i, -1);
+      events_[i].tracking_id = info.GetAbsMtSlotValueWithDefault(
+          ABS_MT_TRACKING_ID, i, kTrackingIdForUnusedSlot);
       events_[i].touching = (events_[i].tracking_id >= 0);
       events_[i].slot = i;
 
@@ -176,7 +179,7 @@
     // TODO(spang): Add key state to EventDeviceInfo to allow initial contact.
     events_[0].x = 0;
     events_[0].y = 0;
-    events_[0].tracking_id = -1;
+    events_[0].tracking_id = kTrackingIdForUnusedSlot;
     events_[0].touching = false;
     events_[0].slot = 0;
     events_[0].radius_x = 0;
@@ -206,6 +209,10 @@
   return touch_points_;
 }
 
+void TouchEventConverterEvdev::OnStopped() {
+  ReleaseTouches();
+}
+
 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
   input_event inputs[kNumTouchEvdevSlots * 6 + 1];
   ssize_t read_size = read(fd, inputs, sizeof(inputs));
@@ -263,7 +270,8 @@
   } else if (event.type == EV_KEY && event.code == BTN_TOUCH) {
     emulated_event.type = EV_ABS;
     emulated_event.code = ABS_MT_TRACKING_ID;
-    emulated_event.value = event.value ? NextTrackingId() : -1;
+    emulated_event.value =
+        event.value ? NextTrackingId() : kTrackingIdForUnusedSlot;
     ProcessMultitouchEvent(emulated_event);
   }
 }
@@ -295,13 +303,7 @@
       events_[current_slot_].y = input.value;
       break;
     case ABS_MT_TRACKING_ID:
-      if (input.value < 0) {
-        events_[current_slot_].touching = false;
-      } else {
-        events_[current_slot_].touching = true;
-        events_[current_slot_].cancelled = false;
-      }
-      events_[current_slot_].tracking_id = input.value;
+      UpdateTrackingId(current_slot_, input.value);
       break;
     case ABS_MT_PRESSURE:
       events_[current_slot_].pressure = ScalePressure(input.value);
@@ -392,6 +394,27 @@
   }
 }
 
+void TouchEventConverterEvdev::UpdateTrackingId(int slot, int tracking_id) {
+  InProgressTouchEvdev* event = &events_[slot];
+
+  if (event->tracking_id == tracking_id)
+    return;
+
+  event->tracking_id = tracking_id;
+  event->touching = (tracking_id >= 0);
+  event->altered = true;
+
+  if (tracking_id >= 0)
+    event->cancelled = false;
+}
+
+void TouchEventConverterEvdev::ReleaseTouches() {
+  for (size_t slot = 0; slot < events_.size(); slot++)
+    UpdateTrackingId(slot, kTrackingIdForUnusedSlot);
+
+  ReportEvents(EventTimeForNow());
+}
+
 float TouchEventConverterEvdev::ScalePressure(int32_t value) {
   float pressure = value - pressure_min_;
   if (pressure_max_ - pressure_min_)
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h
index 6012f86c..7cd7576a2 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -38,6 +38,7 @@
   bool HasTouchscreen() const override;
   gfx::Size GetTouchscreenSize() const override;
   int GetTouchPoints() const override;
+  void OnStopped() override;
 
   // Unsafe part of initialization.
   virtual void Initialize(const EventDeviceInfo& info);
@@ -65,6 +66,9 @@
                    const base::TimeDelta& delta);
   void ReportEvents(base::TimeDelta delta);
 
+  void UpdateTrackingId(int slot, int tracking_id);
+  void ReleaseTouches();
+
   // Normalize pressure value to [0, 1].
   float ScalePressure(int32_t value);
 
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 59a5f48..77eeef6 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -168,20 +168,20 @@
     dispatcher_.reset(new ui::MockDeviceEventDispatcherEvdev(
         base::Bind(&TouchEventConverterEvdevTest::DispatchCallback,
                    base::Unretained(this))));
-    device_ = new ui::MockTouchEventConverterEvdev(
+    device_.reset(new ui::MockTouchEventConverterEvdev(
         events_in_, base::FilePath(kTestDevicePath), devinfo,
-        dispatcher_.get());
+        dispatcher_.get()));
     loop_ = new base::MessageLoopForUI;
 
     ui::DeviceDataManager::CreateInstance();
   }
 
   void TearDown() override {
-    delete device_;
+    device_.reset();
     delete loop_;
   }
 
-  ui::MockTouchEventConverterEvdev* device() { return device_; }
+  ui::MockTouchEventConverterEvdev* device() { return device_.get(); }
 
   unsigned size() { return dispatched_events_.size(); }
   const ui::TouchEventParams& dispatched_event(unsigned index) {
@@ -191,9 +191,11 @@
 
   void ClearDispatchedEvents() { dispatched_events_.clear(); }
 
+  void DestroyDevice() { device_.reset(); }
+
  private:
   base::MessageLoop* loop_;
-  ui::MockTouchEventConverterEvdev* device_;
+  scoped_ptr<ui::MockTouchEventConverterEvdev> device_;
   scoped_ptr<ui::MockDeviceEventDispatcherEvdev> dispatcher_;
 
   int events_out_;
@@ -501,6 +503,44 @@
   EXPECT_FLOAT_EQ(0.50196081f, ev.pressure);
 }
 
+TEST_F(TouchEventConverterEvdevTest, ShouldReleaseContactsOnStop) {
+  ui::MockTouchEventConverterEvdev* dev = device();
+
+  InitPixelTouchscreen(dev);
+
+  // Captured from Chromebook Pixel (Link).
+  timeval time;
+  time = {1429651083, 686882};
+  struct input_event mock_kernel_queue_press[] = {
+      {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
+      {time, EV_ABS, ABS_MT_POSITION_X, 1003},
+      {time, EV_ABS, ABS_MT_POSITION_Y, 749},
+      {time, EV_ABS, ABS_MT_PRESSURE, 50},
+      {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
+      {time, EV_KEY, BTN_TOUCH, 1},
+      {time, EV_ABS, ABS_X, 1003},
+      {time, EV_ABS, ABS_Y, 749},
+      {time, EV_ABS, ABS_PRESSURE, 50},
+      {time, EV_SYN, SYN_REPORT, 0},
+  };
+
+  dev->ConfigureReadMock(mock_kernel_queue_press,
+                         arraysize(mock_kernel_queue_press), 0);
+  dev->ReadNow();
+  EXPECT_EQ(1u, size());
+
+  ui::TouchEventParams ev1 = dispatched_event(0);
+  EXPECT_EQ(ET_TOUCH_PRESSED, ev1.type);
+  EXPECT_EQ(0, ev1.slot);
+
+  DestroyDevice();
+  EXPECT_EQ(2u, size());
+
+  ui::TouchEventParams ev2 = dispatched_event(1);
+  EXPECT_EQ(ET_TOUCH_RELEASED, ev2.type);
+  EXPECT_EQ(0, ev2.slot);
+}
+
 // crbug.com/407386
 TEST_F(TouchEventConverterEvdevTest,
        DontChangeMultitouchPositionFromLegacyAxes) {
diff --git a/ui/events/ozone/layout/layout_util.cc b/ui/events/ozone/layout/layout_util.cc
index b36bf57..e19c22d 100644
--- a/ui/events/ozone/layout/layout_util.cc
+++ b/ui/events/ozone/layout/layout_util.cc
@@ -4,542 +4,11 @@
 
 #include "ui/events/ozone/layout/layout_util.h"
 
-#include <algorithm>
-
 #include "ui/events/event_constants.h"
-#include "ui/events/keycodes/dom3/dom_code.h"
 #include "ui/events/keycodes/dom3/dom_key.h"
-#include "ui/events/keycodes/keyboard_code_conversion.h"
 
 namespace ui {
 
-namespace {
-
-// This table, used by DomKeyToKeyboardCode(), maps DOM Level 3 .code
-// values to legacy Windows-based VKEY values, where the VKEYs are
-// interpreted positionally.
-const struct DomCodeToKeyboardCodeEntry {
-  DomCode dom_code;
-  KeyboardCode key_code;
-} dom_code_to_keyboard_code[] = {
-    // Entries are ordered by numeric value of the DomCode enum,
-    // which is the USB physical key code.
-    // DomCode::HYPER                              0x000010 Hyper
-    // DomCode::SUPER                              0x000011 Super
-    // DomCode::FN                                 0x000012 Fn
-    // DomCode::FN_LOCK                            0x000013 FLock
-    // DomCode::SUSPEND                            0x000014 Suspend
-    // DomCode::RESUME                             0x000015 Resume
-    // DomCode::TURBO                              0x000016 Turbo
-    {DomCode::SLEEP, VKEY_SLEEP},  // 0x010082 Sleep
-    // DomCode::WAKE_UP                            0x010083 WakeUp
-    {DomCode::KEY_A, VKEY_A},              // 0x070004 KeyA
-    {DomCode::KEY_B, VKEY_B},              // 0x070005 KeyB
-    {DomCode::KEY_C, VKEY_C},              // 0x070006 KeyC
-    {DomCode::KEY_D, VKEY_D},              // 0x070007 KeyD
-    {DomCode::KEY_E, VKEY_E},              // 0x070008 KeyE
-    {DomCode::KEY_F, VKEY_F},              // 0x070009 KeyF
-    {DomCode::KEY_G, VKEY_G},              // 0x07000A KeyG
-    {DomCode::KEY_H, VKEY_H},              // 0x07000B KeyH
-    {DomCode::KEY_I, VKEY_I},              // 0x07000C KeyI
-    {DomCode::KEY_J, VKEY_J},              // 0x07000D KeyJ
-    {DomCode::KEY_K, VKEY_K},              // 0x07000E KeyK
-    {DomCode::KEY_L, VKEY_L},              // 0x07000F KeyL
-    {DomCode::KEY_M, VKEY_M},              // 0x070010 KeyM
-    {DomCode::KEY_N, VKEY_N},              // 0x070011 KeyN
-    {DomCode::KEY_O, VKEY_O},              // 0x070012 KeyO
-    {DomCode::KEY_P, VKEY_P},              // 0x070013 KeyP
-    {DomCode::KEY_Q, VKEY_Q},              // 0x070014 KeyQ
-    {DomCode::KEY_R, VKEY_R},              // 0x070015 KeyR
-    {DomCode::KEY_S, VKEY_S},              // 0x070016 KeyS
-    {DomCode::KEY_T, VKEY_T},              // 0x070017 KeyT
-    {DomCode::KEY_U, VKEY_U},              // 0x070018 KeyU
-    {DomCode::KEY_V, VKEY_V},              // 0x070019 KeyV
-    {DomCode::KEY_W, VKEY_W},              // 0x07001A KeyW
-    {DomCode::KEY_X, VKEY_X},              // 0x07001B KeyX
-    {DomCode::KEY_Y, VKEY_Y},              // 0x07001C KeyY
-    {DomCode::KEY_Z, VKEY_Z},              // 0x07001D KeyZ
-    {DomCode::DIGIT1, VKEY_1},             // 0x07001E Digit1
-    {DomCode::DIGIT2, VKEY_2},             // 0x07001F Digit2
-    {DomCode::DIGIT3, VKEY_3},             // 0x070020 Digit3
-    {DomCode::DIGIT4, VKEY_4},             // 0x070021 Digit4
-    {DomCode::DIGIT5, VKEY_5},             // 0x070022 Digit5
-    {DomCode::DIGIT6, VKEY_6},             // 0x070023 Digit6
-    {DomCode::DIGIT7, VKEY_7},             // 0x070024 Digit7
-    {DomCode::DIGIT8, VKEY_8},             // 0x070025 Digit8
-    {DomCode::DIGIT9, VKEY_9},             // 0x070026 Digit9
-    {DomCode::DIGIT0, VKEY_0},             // 0x070027 Digit0
-    {DomCode::ENTER, VKEY_RETURN},         // 0x070028 Enter
-    {DomCode::ESCAPE, VKEY_ESCAPE},        // 0x070029 Escape
-    {DomCode::BACKSPACE, VKEY_BACK},       // 0x07002A Backspace
-    {DomCode::TAB, VKEY_TAB},              // 0x07002B Tab
-    {DomCode::SPACE, VKEY_SPACE},          // 0x07002C Space
-    {DomCode::MINUS, VKEY_OEM_MINUS},      // 0x07002D Minus
-    {DomCode::EQUAL, VKEY_OEM_PLUS},       // 0x07002E Equal
-    {DomCode::BRACKET_LEFT, VKEY_OEM_4},   // 0x07002F BracketLeft
-    {DomCode::BRACKET_RIGHT, VKEY_OEM_6},  // 0x070030 BracketRight
-    {DomCode::BACKSLASH, VKEY_OEM_5},      // 0x070031 Backslash
-    // DomCode::INTL_HASH, VKEY_OEM_5           // 0x070032 IntlHash
-    {DomCode::SEMICOLON, VKEY_OEM_1},           // 0x070033 Semicolon
-    {DomCode::QUOTE, VKEY_OEM_7},               // 0x070034 Quote
-    {DomCode::BACKQUOTE, VKEY_OEM_3},           // 0x070035 Backquote
-    {DomCode::COMMA, VKEY_OEM_COMMA},           // 0x070036 Comma
-    {DomCode::PERIOD, VKEY_OEM_PERIOD},         // 0x070037 Period
-    {DomCode::SLASH, VKEY_OEM_2},               // 0x070038 Slash
-    {DomCode::CAPS_LOCK, VKEY_CAPITAL},         // 0x070039 CapsLock
-    {DomCode::F1, VKEY_F1},                     // 0x07003A F1
-    {DomCode::F2, VKEY_F2},                     // 0x07003B F2
-    {DomCode::F3, VKEY_F3},                     // 0x07003C F3
-    {DomCode::F4, VKEY_F4},                     // 0x07003D F4
-    {DomCode::F5, VKEY_F5},                     // 0x07003E F5
-    {DomCode::F6, VKEY_F6},                     // 0x07003F F6
-    {DomCode::F7, VKEY_F7},                     // 0x070040 F7
-    {DomCode::F8, VKEY_F8},                     // 0x070041 F8
-    {DomCode::F9, VKEY_F9},                     // 0x070042 F9
-    {DomCode::F10, VKEY_F10},                   // 0x070043 F10
-    {DomCode::F11, VKEY_F11},                   // 0x070044 F11
-    {DomCode::F12, VKEY_F12},                   // 0x070045 F12
-    {DomCode::PRINT_SCREEN, VKEY_SNAPSHOT},     // 0x070046 PrintScreen
-    {DomCode::SCROLL_LOCK, VKEY_SCROLL},        // 0x070047 ScrollLock
-    {DomCode::PAUSE, VKEY_PAUSE},               // 0x070048 Pause
-    {DomCode::INSERT, VKEY_INSERT},             // 0x070049 Insert
-    {DomCode::HOME, VKEY_HOME},                 // 0x07004A Home
-    {DomCode::PAGE_UP, VKEY_PRIOR},             // 0x07004B PageUp
-    {DomCode::DEL, VKEY_DELETE},                // 0x07004C Delete
-    {DomCode::END, VKEY_END},                   // 0x07004D End
-    {DomCode::PAGE_DOWN, VKEY_NEXT},            // 0x07004E PageDown
-    {DomCode::ARROW_RIGHT, VKEY_RIGHT},         // 0x07004F ArrowRight
-    {DomCode::ARROW_LEFT, VKEY_LEFT},           // 0x070050 ArrowLeft
-    {DomCode::ARROW_DOWN, VKEY_DOWN},           // 0x070051 ArrowDown
-    {DomCode::ARROW_UP, VKEY_UP},               // 0x070052 ArrowUp
-    {DomCode::NUM_LOCK, VKEY_NUMLOCK},          // 0x070053 NumLock
-    {DomCode::NUMPAD_DIVIDE, VKEY_DIVIDE},      // 0x070054 NumpadDivide
-    {DomCode::NUMPAD_MULTIPLY, VKEY_MULTIPLY},  // 0x070055 NumpadMultiply
-    {DomCode::NUMPAD_SUBTRACT, VKEY_SUBTRACT},  // 0x070056 NumpadSubtract
-    {DomCode::NUMPAD_ADD, VKEY_ADD},            // 0x070057 NumpadAdd
-    {DomCode::NUMPAD_ENTER, VKEY_RETURN},       // 0x070058 NumpadEnter
-    {DomCode::NUMPAD1, VKEY_NUMPAD1},           // 0x070059 Numpad1
-    {DomCode::NUMPAD2, VKEY_NUMPAD2},           // 0x07005A Numpad2
-    {DomCode::NUMPAD3, VKEY_NUMPAD3},           // 0x07005B Numpad3
-    {DomCode::NUMPAD4, VKEY_NUMPAD4},           // 0x07005C Numpad4
-    {DomCode::NUMPAD5, VKEY_NUMPAD5},           // 0x07005D Numpad5
-    {DomCode::NUMPAD6, VKEY_NUMPAD6},           // 0x07005E Numpad6
-    {DomCode::NUMPAD7, VKEY_NUMPAD7},           // 0x07005F Numpad7
-    {DomCode::NUMPAD8, VKEY_NUMPAD8},           // 0x070060 Numpad8
-    {DomCode::NUMPAD9, VKEY_NUMPAD9},           // 0x070061 Numpad9
-    {DomCode::NUMPAD0, VKEY_NUMPAD0},           // 0x070062 Numpad0
-    {DomCode::NUMPAD_DECIMAL, VKEY_DECIMAL},    // 0x070063 NumpadDecimal
-    {DomCode::INTL_BACKSLASH, VKEY_OEM_102},    // 0x070064 IntlBackslash
-    {DomCode::CONTEXT_MENU, VKEY_APPS},         // 0x070065 ContextMenu
-    {DomCode::POWER, VKEY_POWER},               // 0x070066 Power
-    // DomCode::NUMPAD_EQUAL                       0x070067 NumpadEqual
-    // DomCode::OPEN                               0x070074 Open
-    {DomCode::HELP, VKEY_HELP},      // 0x070075 Help
-    {DomCode::SELECT, VKEY_SELECT},  // 0x070077 Select
-    // DomCode::AGAIN                             0x070079 Again
-    // DomCode::UNDO                              0x07007A Undo
-    // DomCode::CUT                               0x07007B Cut
-    // DomCode::COPY                              0x07007C Copy
-    // DomCode::PASTE                             0x07007D Paste
-    // DomCode::FIND                              0x07007E Find
-    {DomCode::VOLUME_MUTE, VKEY_VOLUME_MUTE},  // 0x07007F VolumeMute
-    {DomCode::VOLUME_UP, VKEY_VOLUME_UP},      // 0x070080 VolumeUp
-    {DomCode::VOLUME_DOWN, VKEY_VOLUME_DOWN},  // 0x070081 VolumeDown
-    {DomCode::NUMPAD_COMMA, VKEY_OEM_COMMA},   // 0x070085 NumpadComma
-    {DomCode::INTL_RO, VKEY_OEM_102},          // 0x070087 IntlRo
-    {DomCode::KANA_MODE, VKEY_KANA},           // 0x070088 KanaMode
-    {DomCode::INTL_YEN, VKEY_OEM_5},           // 0x070089 IntlYen
-    {DomCode::CONVERT, VKEY_CONVERT},          // 0x07008A Convert
-    {DomCode::NON_CONVERT, VKEY_NONCONVERT},   // 0x07008B NonConvert
-    {DomCode::LANG1, VKEY_KANA},               // 0x070090 Lang1
-    {DomCode::LANG2, VKEY_KANJI},              // 0x070091 Lang2
-    // DomCode::LANG3                             0x070092 Lang3
-    // DomCode::LANG4                             0x070093 Lang4
-    // DomCode::LANG5                             0x070094 Lang5
-    // DomCode::ABORT                             0x07009B Abort
-    // DomCode::PROPS                             0x0700A3 Props
-    // DomCode::NUMPAD_PAREN_LEFT                 0x0700B6 NumpadParenLeft
-    // DomCode::NUMPAD_PAREN_RIGHT                0x0700B7 NumpadParenRight
-    {DomCode::NUMPAD_BACKSPACE, VKEY_BACK},  // 0x0700BB NumpadBackspace
-    // DomCode::NUMPAD_MEMORY_STORE                0x0700D0 NumpadMemoryStore
-    // DomCode::NUMPAD_MEMORY_RECALL               0x0700D1 NumpadMemoryRecall
-    // DomCode::NUMPAD_MEMORY_CLEAR                0x0700D2 NumpadMemoryClear
-    // DomCode::NUMPAD_MEMORY_ADD                  0x0700D3 NumpadMemoryAdd
-    // DomCode::NUMPAD_MEMORY_SUBTRACT             0x0700D4
-    // NumpadMemorySubtract
-    {DomCode::NUMPAD_CLEAR, VKEY_CLEAR},        // 0x0700D8 NumpadClear
-    {DomCode::NUMPAD_CLEAR_ENTRY, VKEY_CLEAR},  // 0x0700D9 NumpadClearEntry
-    {DomCode::CONTROL_LEFT, VKEY_LCONTROL},     // 0x0700E0 ControlLeft
-    {DomCode::SHIFT_LEFT, VKEY_LSHIFT},         // 0x0700E1 ShiftLeft
-    {DomCode::ALT_LEFT, VKEY_LMENU},            // 0x0700E2 AltLeft
-    {DomCode::OS_LEFT, VKEY_LWIN},              // 0x0700E3 OSLeft
-    {DomCode::CONTROL_RIGHT, VKEY_RCONTROL},    // 0x0700E4 ControlRight
-    {DomCode::SHIFT_RIGHT, VKEY_RSHIFT},        // 0x0700E5 ShiftRight
-    {DomCode::ALT_RIGHT, VKEY_RMENU},           // 0x0700E6 AltRight
-    {DomCode::OS_RIGHT, VKEY_RWIN},             // 0x0700E7 OSRight
-    {DomCode::MEDIA_TRACK_NEXT,
-     VKEY_MEDIA_NEXT_TRACK},  // 0x0C00B5 MediaTrackNext
-    {DomCode::MEDIA_TRACK_PREVIOUS,
-     VKEY_MEDIA_PREV_TRACK},                 // 0x0C00B6 MediaTrackPrevious
-    {DomCode::MEDIA_STOP, VKEY_MEDIA_STOP},  // 0x0C00B7 MediaStop
-    // DomCode::EJECT                           0x0C00B8 Eject
-    {DomCode::MEDIA_PLAY_PAUSE,
-     VKEY_MEDIA_PLAY_PAUSE},  // 0x0C00CD MediaPlayPause
-    {DomCode::MEDIA_SELECT,
-     VKEY_MEDIA_LAUNCH_MEDIA_SELECT},                // 0x0C0183 MediaSelect
-    {DomCode::LAUNCH_MAIL, VKEY_MEDIA_LAUNCH_MAIL},  // 0x0C018A LaunchMail
-    {DomCode::LAUNCH_APP2, VKEY_MEDIA_LAUNCH_APP2},  // 0x0C0192 LaunchApp2
-    {DomCode::LAUNCH_APP1, VKEY_MEDIA_LAUNCH_APP1},  // 0x0C0194 LaunchApp1
-    {DomCode::BROWSER_SEARCH, VKEY_BROWSER_SEARCH},  // 0x0C0221 BrowserSearch
-    {DomCode::BROWSER_HOME, VKEY_BROWSER_HOME},      // 0x0C0223 BrowserHome
-    {DomCode::BROWSER_BACK, VKEY_BROWSER_BACK},      // 0x0C0224 BrowserBack
-    {DomCode::BROWSER_FORWARD,
-     VKEY_BROWSER_FORWARD},                      // 0x0C0225 BrowserForward
-    {DomCode::BROWSER_STOP, VKEY_BROWSER_STOP},  // 0x0C0226 BrowserStop
-    {DomCode::BROWSER_REFRESH,
-     VKEY_BROWSER_REFRESH},  // 0x0C0227 BrowserRefresh
-    {DomCode::BROWSER_FAVORITES,
-     VKEY_BROWSER_FAVORITES},  // 0x0C022A BrowserFavorites
-};
-
-}  // anonymous namespace
-
-// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
-// The returned VKEY is non-positional (e.g. VKEY_SHIFT).
-KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) {
-  switch (dom_key) {
-    // No value.
-    case DomKey::NONE:
-      return VKEY_UNKNOWN;
-    // Character values.
-    // Special Key Values
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-special
-    case DomKey::UNIDENTIFIED:
-      return VKEY_UNKNOWN;
-    // Modifier Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-modifier
-    case DomKey::ALT:
-      return VKEY_MENU;
-    case DomKey::ALT_GRAPH:
-      return VKEY_ALTGR;
-    case DomKey::CAPS_LOCK:
-      return VKEY_CAPITAL;
-    case DomKey::CONTROL:
-      return VKEY_CONTROL;
-    case DomKey::NUM_LOCK:
-      return VKEY_NUMLOCK;
-    case DomKey::OS:
-      return VKEY_LWIN;
-    case DomKey::SCROLL_LOCK:
-      return VKEY_SCROLL;
-    case DomKey::SHIFT:
-      return VKEY_SHIFT;
-    // Whitespace Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-whitespace
-    case DomKey::ENTER:
-      return VKEY_RETURN;
-    case DomKey::SEPARATOR:
-      return VKEY_SEPARATOR;
-    case DomKey::TAB:
-      return VKEY_TAB;
-    // Navigation Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-navigation
-    case DomKey::ARROW_DOWN:
-      return VKEY_DOWN;
-    case DomKey::ARROW_LEFT:
-      return VKEY_LEFT;
-    case DomKey::ARROW_RIGHT:
-      return VKEY_RIGHT;
-    case DomKey::ARROW_UP:
-      return VKEY_UP;
-    case DomKey::END:
-      return VKEY_END;
-    case DomKey::HOME:
-      return VKEY_HOME;
-    case DomKey::PAGE_DOWN:
-      return VKEY_NEXT;
-    case DomKey::PAGE_UP:
-      return VKEY_PRIOR;
-    // Editing Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-editing
-    case DomKey::BACKSPACE:
-      return VKEY_BACK;
-    case DomKey::CLEAR:
-      return VKEY_CLEAR;
-    case DomKey::CR_SEL:
-      return VKEY_CRSEL;
-    case DomKey::DEL:
-      return VKEY_DELETE;
-    case DomKey::ERASE_EOF:
-      return VKEY_EREOF;
-    case DomKey::EX_SEL:
-      return VKEY_EXSEL;
-    case DomKey::INSERT:
-      return VKEY_INSERT;
-    // UI Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-ui
-    case DomKey::ACCEPT:
-      return VKEY_ACCEPT;
-    case DomKey::ATTN:
-      return VKEY_ATTN;
-    case DomKey::CONTEXT_MENU:
-      return VKEY_APPS;
-    case DomKey::ESCAPE:
-      return VKEY_ESCAPE;
-    case DomKey::EXECUTE:
-      return VKEY_EXECUTE;
-    case DomKey::HELP:
-      return VKEY_HELP;
-    case DomKey::PAUSE:
-      return VKEY_PAUSE;
-    case DomKey::PLAY:
-      return VKEY_PLAY;
-    case DomKey::SELECT:
-      return VKEY_SELECT;
-    // Device Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-device
-    case DomKey::BRIGHTNESS_DOWN:
-      return VKEY_BRIGHTNESS_DOWN;
-    case DomKey::BRIGHTNESS_UP:
-      return VKEY_BRIGHTNESS_UP;
-    case DomKey::POWER:
-      return VKEY_POWER;
-    case DomKey::PRINT_SCREEN:
-      return VKEY_SNAPSHOT;
-// IME and Composition Keys
-// http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-composition
-#if 0  // TODO(kpschoedel)
-    case DomKey::COMPOSE:
-      return VKEY_COMPOSE;
-#endif
-    case DomKey::CONVERT:
-      return VKEY_CONVERT;
-    case DomKey::FINAL_MODE:
-      return VKEY_FINAL;
-    case DomKey::MODE_CHANGE:
-      return VKEY_MODECHANGE;
-    case DomKey::NON_CONVERT:
-      return VKEY_NONCONVERT;
-    case DomKey::PROCESS:
-      return VKEY_PROCESSKEY;
-    // Keys specific to Korean keyboards
-    case DomKey::HANGUL_MODE:
-      return VKEY_HANGUL;
-    case DomKey::HANJA_MODE:
-      return VKEY_HANJA;
-    case DomKey::JUNJA_MODE:
-      return VKEY_JUNJA;
-    // Keys specific to Japanese keyboards
-    case DomKey::HANKAKU:
-      return VKEY_DBE_SBCSCHAR;
-    case DomKey::KANA_MODE:
-      return VKEY_KANA;
-    case DomKey::KANJI_MODE:
-      return VKEY_KANJI;
-    case DomKey::ZENKAKU:
-      return VKEY_DBE_DBCSCHAR;
-    case DomKey::ZENKAKU_HANKAKU:
-      return VKEY_DBE_DBCSCHAR;
-    // General-Purpose Function Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-function
-    case DomKey::F1:
-      return VKEY_F1;
-    case DomKey::F2:
-      return VKEY_F2;
-    case DomKey::F3:
-      return VKEY_F3;
-    case DomKey::F4:
-      return VKEY_F4;
-    case DomKey::F5:
-      return VKEY_F5;
-    case DomKey::F6:
-      return VKEY_F6;
-    case DomKey::F7:
-      return VKEY_F7;
-    case DomKey::F8:
-      return VKEY_F8;
-    case DomKey::F9:
-      return VKEY_F9;
-    case DomKey::F10:
-      return VKEY_F10;
-    case DomKey::F11:
-      return VKEY_F11;
-    case DomKey::F12:
-      return VKEY_F12;
-    case DomKey::F13:
-      return VKEY_F13;
-    case DomKey::F14:
-      return VKEY_F14;
-    case DomKey::F15:
-      return VKEY_F15;
-    case DomKey::F16:
-      return VKEY_F16;
-    case DomKey::F17:
-      return VKEY_F17;
-    case DomKey::F18:
-      return VKEY_F18;
-    case DomKey::F19:
-      return VKEY_F19;
-    case DomKey::F20:
-      return VKEY_F20;
-    case DomKey::F21:
-      return VKEY_F21;
-    case DomKey::F22:
-      return VKEY_F22;
-    case DomKey::F23:
-      return VKEY_F23;
-    case DomKey::F24:
-      return VKEY_F24;
-    // Multimedia Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-multimedia
-    case DomKey::MEDIA_PLAY_PAUSE:
-      return VKEY_MEDIA_PLAY_PAUSE;
-    case DomKey::MEDIA_SELECT:
-      return VKEY_MEDIA_LAUNCH_MEDIA_SELECT;
-    case DomKey::MEDIA_STOP:
-      return VKEY_MEDIA_STOP;
-    case DomKey::MEDIA_TRACK_NEXT:
-      return VKEY_MEDIA_NEXT_TRACK;
-    case DomKey::MEDIA_TRACK_PREVIOUS:
-      return VKEY_MEDIA_PREV_TRACK;
-    case DomKey::PRINT:
-      return VKEY_PRINT;
-    case DomKey::VOLUME_DOWN:
-      return VKEY_VOLUME_DOWN;
-    case DomKey::VOLUME_MUTE:
-      return VKEY_VOLUME_MUTE;
-    case DomKey::VOLUME_UP:
-      return VKEY_VOLUME_UP;
-    // Application Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-apps
-    case DomKey::LAUNCH_CALCULATOR:
-      return VKEY_MEDIA_LAUNCH_APP2;
-    case DomKey::LAUNCH_MAIL:
-      return VKEY_MEDIA_LAUNCH_MAIL;
-    case DomKey::LAUNCH_MY_COMPUTER:
-      return VKEY_MEDIA_LAUNCH_APP1;
-    // Browser Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-browser
-    case DomKey::BROWSER_BACK:
-      return VKEY_BROWSER_BACK;
-    case DomKey::BROWSER_FAVORITES:
-      return VKEY_BROWSER_FAVORITES;
-    case DomKey::BROWSER_FORWARD:
-      return VKEY_BROWSER_FORWARD;
-    case DomKey::BROWSER_HOME:
-      return VKEY_BROWSER_HOME;
-    case DomKey::BROWSER_REFRESH:
-      return VKEY_BROWSER_REFRESH;
-    case DomKey::BROWSER_SEARCH:
-      return VKEY_BROWSER_SEARCH;
-    case DomKey::BROWSER_STOP:
-      return VKEY_BROWSER_STOP;
-    // Media Controller Keys
-    // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-media-controller
-    case DomKey::ZOOM_TOGGLE:
-      return VKEY_ZOOM;
-    // No value.
-    default:
-      return VKEY_UNKNOWN;
-  }
-}
-
-// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
-// The returned VKEY is located (e.g. VKEY_LSHIFT).
-KeyboardCode DomCodeToKeyboardCode(DomCode dom_code) {
-  const DomCodeToKeyboardCodeEntry* end =
-      dom_code_to_keyboard_code + arraysize(dom_code_to_keyboard_code);
-  const DomCodeToKeyboardCodeEntry* found =
-      std::lower_bound(dom_code_to_keyboard_code, end, dom_code,
-                       [](const DomCodeToKeyboardCodeEntry& a, DomCode b) {
-        return static_cast<int>(a.dom_code) < static_cast<int>(b);
-      });
-  if ((found != end) && (found->dom_code == dom_code))
-    return found->key_code;
-  return VKEY_UNKNOWN;
-}
-
-// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
-// The returned VKEY is non-located (e.g. VKEY_SHIFT).
-KeyboardCode DomCodeToNonLocatedKeyboardCode(DomCode dom_code) {
-  return LocatedToNonLocatedKeyboardCode(DomCodeToKeyboardCode(dom_code));
-}
-
-bool LookupControlCharacter(DomCode dom_code,
-                            int flags,
-                            DomKey* dom_key,
-                            base::char16* character,
-                            KeyboardCode* key_code) {
-  if ((flags & EF_CONTROL_DOWN) == 0)
-    return false;
-
-  int code = static_cast<int>(dom_code);
-  const int kKeyA = static_cast<int>(DomCode::KEY_A);
-  // Control-A - Control-Z map to 0x01 - 0x1A.
-  if (code >= kKeyA && code <= static_cast<int>(DomCode::KEY_Z)) {
-    *character = static_cast<base::char16>(code - kKeyA + 1);
-    *key_code = static_cast<KeyboardCode>(code - kKeyA + VKEY_A);
-    switch (dom_code) {
-      case DomCode::KEY_H:
-        *dom_key = DomKey::BACKSPACE;
-      case DomCode::KEY_I:
-        *dom_key = DomKey::TAB;
-      case DomCode::KEY_M:
-        *dom_key = DomKey::ENTER;
-      default:
-        *dom_key = DomKey::CHARACTER;
-    }
-    return true;
-  }
-
-  switch (dom_code) {
-    case DomCode::DIGIT2:
-      // NUL
-      *character = 0;
-      *dom_key = DomKey::CHARACTER;
-      *key_code = VKEY_2;
-      return true;
-    case DomCode::ENTER:
-      // NL
-      *character = 0x0A;
-      *dom_key = DomKey::CHARACTER;
-      *key_code = VKEY_RETURN;
-      return true;
-    case DomCode::BRACKET_LEFT:
-      // ESC
-      *character = 0x1B;
-      *dom_key = DomKey::ESCAPE;
-      *key_code = VKEY_OEM_4;
-      return true;
-    case DomCode::BACKSLASH:
-      // FS
-      *character = 0x1C;
-      *dom_key = DomKey::CHARACTER;
-      *key_code = VKEY_OEM_5;
-      return true;
-    case DomCode::BRACKET_RIGHT:
-      // GS
-      *character = 0x1D;
-      *dom_key = DomKey::CHARACTER;
-      *key_code = VKEY_OEM_6;
-      return true;
-    case DomCode::DIGIT6:
-      // RS
-      *character = 0x1E;
-      *dom_key = DomKey::CHARACTER;
-      *key_code = VKEY_6;
-      return true;
-    case DomCode::MINUS:
-      // US
-      *character = 0x1F;
-      *dom_key = DomKey::CHARACTER;
-      *key_code = VKEY_OEM_MINUS;
-      return true;
-    default:
-      return false;
-  }
-}
-
 int ModifierDomKeyToEventFlag(DomKey key) {
   switch (key) {
     case DomKey::ALT:
diff --git a/ui/events/ozone/layout/layout_util.h b/ui/events/ozone/layout/layout_util.h
index 7eb8f779..84d9d1d 100644
--- a/ui/events/ozone/layout/layout_util.h
+++ b/ui/events/ozone/layout/layout_util.h
@@ -13,31 +13,8 @@
 
 namespace ui {
 
-enum class DomCode;
 enum class DomKey;
 
-// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
-// The returned VKEY is non-located (e.g. VKEY_SHIFT).
-EVENTS_OZONE_LAYOUT_EXPORT KeyboardCode
-NonPrintableDomKeyToKeyboardCode(DomKey dom_key);
-
-// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
-// The returned VKEY is located (e.g. VKEY_LSHIFT).
-EVENTS_OZONE_LAYOUT_EXPORT KeyboardCode DomCodeToKeyboardCode(DomCode dom_code);
-
-// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
-// The returned VKEY is non-located (e.g. VKEY_SHIFT).
-EVENTS_OZONE_LAYOUT_EXPORT KeyboardCode
-DomCodeToNonLocatedKeyboardCode(DomCode dom_code);
-
-// Returns true control character corresponding to a physical key.
-// In some contexts this is used instead of the key layout.
-EVENTS_OZONE_LAYOUT_EXPORT bool LookupControlCharacter(DomCode dom_code,
-                                                       int flags,
-                                                       DomKey* dom_key,
-                                                       base::char16* character,
-                                                       KeyboardCode* key_code);
-
 // Returns the ui::EventFlags value associated with a modifier key,
 // or 0 (EF_NONE) if the key is not a modifier.
 EVENTS_OZONE_LAYOUT_EXPORT int ModifierDomKeyToEventFlag(DomKey key);
diff --git a/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc b/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc
index 4279901..9a522df6 100644
--- a/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc
+++ b/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc
@@ -15,221 +15,6 @@
 
 namespace ui {
 
-namespace {
-
-// All of the characters have low ordinals, so we use bit 15 to flag dead keys.
-#define DK  0x8000
-
-const struct PrintableCodeEntry {
-  DomCode dom_code;
-  base::char16 character[4];
-} printable_code_map[] = {
-    // Stub table based on X US international.
-    {DomCode::KEY_A,                    {'a', 'A', 0x00E1, 0x00C1}},
-    {DomCode::KEY_B,                    {'b', 'B', 'b', 'B'}},
-    {DomCode::KEY_C,                    {'c', 'C', 0x00A9, 0x00A2}},
-    {DomCode::KEY_D,                    {'d', 'D', 0x00F0, 0x00D0}},
-    {DomCode::KEY_E,                    {'e', 'E', 0x00E9, 0x00C9}},
-    {DomCode::KEY_F,                    {'f', 'F', 'f', 'F'}},
-    {DomCode::KEY_G,                    {'g', 'G', 'g', 'G'}},
-    {DomCode::KEY_H,                    {'h', 'H', 'h', 'H'}},
-    {DomCode::KEY_I,                    {'i', 'I', 0x00ED, 0x00CD}},
-    {DomCode::KEY_J,                    {'j', 'J', 'j', 'J'}},
-    {DomCode::KEY_K,                    {'k', 'K', 0x0153, 0x0152}},
-    {DomCode::KEY_L,                    {'l', 'L', 0x00F8, 0x00D8}},
-    {DomCode::KEY_M,                    {'m', 'M', 0x00B5, 0x00B5}},
-    {DomCode::KEY_N,                    {'n', 'N', 0x00F1, 0x00D1}},
-    {DomCode::KEY_O,                    {'o', 'O', 0x00F3, 0x00D3}},
-    {DomCode::KEY_P,                    {'p', 'P', 0x00F6, 0x00D6}},
-    {DomCode::KEY_Q,                    {'q', 'Q', 0x00E4, 0x00C4}},
-    {DomCode::KEY_R,                    {'r', 'R', 0x00AE, 0x00AE}},
-    {DomCode::KEY_S,                    {'s', 'S', 0x00DF, 0x00A7}},
-    {DomCode::KEY_T,                    {'t', 'T', 0x00FE, 0x00DE}},
-    {DomCode::KEY_U,                    {'u', 'U', 0x00FA, 0x00DA}},
-    {DomCode::KEY_V,                    {'v', 'V', 'v', 'V'}},
-    {DomCode::KEY_W,                    {'w', 'W', 0x00E5, 0x00C5}},
-    {DomCode::KEY_X,                    {'x', 'X', 'x', 'X'}},
-    {DomCode::KEY_Y,                    {'y', 'Y', 0x00FC, 0x00DC}},
-    {DomCode::KEY_Z,                    {'z', 'Z', 0x00E6, 0x00C6}},
-    {DomCode::DIGIT1,                   {'1', '!', 0x00A1, 0x00B9}},
-    {DomCode::DIGIT2,                   {'2', '@', 0x00B2, DK|0x030B}},
-    {DomCode::DIGIT3,                   {'3', '#', 0x00B3, DK|0x0304}},
-    {DomCode::DIGIT4,                   {'4', '$', 0x00A4, 0x00A3}},
-    {DomCode::DIGIT5,                   {'5', '%', 0x20AC, DK|0x0327}},
-    {DomCode::DIGIT6,                   {'6', '^', DK|0x0302, 0x00BC}},
-    {DomCode::DIGIT7,                   {'7', '&', 0x00BD, DK|0x031B}},
-    {DomCode::DIGIT8,                   {'8', '*', 0x00BE, DK|0x0328}},
-    {DomCode::DIGIT9,                   {'9', '(', 0x2018, DK|0x0306}},
-    {DomCode::DIGIT0,                   {'0', ')', 0x2019, DK|0x030A}},
-    {DomCode::SPACE,                    {' ', ' ', 0x00A0, 0x00A0}},
-    {DomCode::MINUS,                    {'-', '_', 0x00A5, DK|0x0323}},
-    {DomCode::EQUAL,                    {'=', '+', 0x00D7, 0x00F7}},
-    {DomCode::BRACKET_LEFT,             {'[', '{', 0x00AB, 0x201C}},
-    {DomCode::BRACKET_RIGHT,            {']', '}', 0x00BB, 0x201D}},
-    {DomCode::BACKSLASH,                {'\\', '|', 0x00AC, 0x00A6}},
-    {DomCode::SEMICOLON,                {';', ':', 0x00B6, 0x00B0}},
-    {DomCode::QUOTE,                    {'\'', '"', DK|0x0301, DK|0x0308}},
-    {DomCode::BACKQUOTE,                {'`', '~', DK|0x0300, DK|0x0303}},
-    {DomCode::COMMA,                    {',', '<', 0x00E7, 0x00C7}},
-    {DomCode::PERIOD,                   {'.', '>', DK|0x0307, DK|0x030C}},
-    {DomCode::SLASH,                    {'/', '?', 0x00BF, DK|0x0309}},
-    {DomCode::INTL_BACKSLASH,           {'\\', '|', '\\', '|'}},
-    {DomCode::INTL_YEN,                 {0x00A5, '|', 0x00A5, '|'}},
-    {DomCode::NUMPAD_DIVIDE,            {'/', '/', '/', '/'}},
-    {DomCode::NUMPAD_MULTIPLY,          {'*', '*', '*', '*'}},
-    {DomCode::NUMPAD_SUBTRACT,          {'-', '-', '-', '-'}},
-    {DomCode::NUMPAD_ADD,               {'+', '+', '+', '+'}},
-    {DomCode::NUMPAD1,                  {'1', '1', '1', '1'}},
-    {DomCode::NUMPAD2,                  {'2', '2', '2', '2'}},
-    {DomCode::NUMPAD3,                  {'3', '3', '3', '3'}},
-    {DomCode::NUMPAD4,                  {'4', '4', '4', '4'}},
-    {DomCode::NUMPAD5,                  {'5', '5', '5', '5'}},
-    {DomCode::NUMPAD6,                  {'6', '6', '6', '6'}},
-    {DomCode::NUMPAD7,                  {'7', '7', '7', '7'}},
-    {DomCode::NUMPAD8,                  {'8', '8', '8', '8'}},
-    {DomCode::NUMPAD9,                  {'9', '9', '9', '9'}},
-    {DomCode::NUMPAD0,                  {'0', '0', '0', '0'}},
-    {DomCode::NUMPAD_DECIMAL,           {'.', '.', '.', '.'}},
-    {DomCode::NUMPAD_EQUAL,             {'=', '=', '=', '='}},
-    {DomCode::NUMPAD_COMMA,             {',', ',', ',', ','}},
-    {DomCode::NUMPAD_PAREN_LEFT,        {'(', '(', '(', '('}},
-    {DomCode::NUMPAD_PAREN_RIGHT,       {')', ')', ')', ')'}},
-    {DomCode::NUMPAD_SIGN_CHANGE,       {0x00B1, 0x00B1, 0x2213, 0x2213}},
-};
-
-const struct NonPrintableCodeEntry {
-  DomCode dom_code;
-  DomKey dom_key;
-  base::char16 character;
-} non_printable_code_map[] = {
-    {DomCode::ABORT, DomKey::CANCEL},
-    {DomCode::AGAIN, DomKey::AGAIN},
-    {DomCode::ALT_LEFT, DomKey::ALT},
-    {DomCode::ALT_RIGHT, DomKey::ALT},
-    {DomCode::ARROW_DOWN, DomKey::ARROW_DOWN},
-    {DomCode::ARROW_LEFT, DomKey::ARROW_LEFT},
-    {DomCode::ARROW_RIGHT, DomKey::ARROW_RIGHT},
-    {DomCode::ARROW_UP, DomKey::ARROW_UP},
-    {DomCode::BACKSPACE, DomKey::BACKSPACE, 0x0008},
-    {DomCode::BRIGHTNESS_DOWN, DomKey::BRIGHTNESS_DOWN},
-    {DomCode::BRIGHTNESS_UP, DomKey::BRIGHTNESS_UP},
-    // {DomCode::BRIGHTNESS_AUTO, DomKey::_}
-    // {DomCode::BRIGHTNESS_MAXIMUM, DomKey::_}
-    // {DomCode::BRIGHTNESS_MINIMIUM, DomKey::_}
-    // {DomCode::BRIGHTNESS_TOGGLE, DomKey::_}
-    {DomCode::BROWSER_BACK, DomKey::BROWSER_BACK},
-    {DomCode::BROWSER_FAVORITES, DomKey::BROWSER_FAVORITES},
-    {DomCode::BROWSER_FORWARD, DomKey::BROWSER_FORWARD},
-    {DomCode::BROWSER_HOME, DomKey::BROWSER_HOME},
-    {DomCode::BROWSER_REFRESH, DomKey::BROWSER_REFRESH},
-    {DomCode::BROWSER_SEARCH, DomKey::BROWSER_SEARCH},
-    {DomCode::BROWSER_STOP, DomKey::BROWSER_STOP},
-    {DomCode::CAPS_LOCK, DomKey::CAPS_LOCK},
-    {DomCode::CONTEXT_MENU, DomKey::CONTEXT_MENU},
-    {DomCode::CONTROL_LEFT, DomKey::CONTROL},
-    {DomCode::CONTROL_RIGHT, DomKey::CONTROL},
-    {DomCode::CONVERT, DomKey::CONVERT},
-    {DomCode::COPY, DomKey::COPY},
-    {DomCode::CUT, DomKey::CUT},
-    {DomCode::DEL, DomKey::DEL, 0x007F},
-    {DomCode::EJECT, DomKey::EJECT},
-    {DomCode::END, DomKey::END},
-    {DomCode::ENTER, DomKey::ENTER, 0x000D},
-    {DomCode::ESCAPE, DomKey::ESCAPE, 0x001B},
-    {DomCode::F1, DomKey::F1},
-    {DomCode::F2, DomKey::F2},
-    {DomCode::F3, DomKey::F3},
-    {DomCode::F4, DomKey::F4},
-    {DomCode::F5, DomKey::F5},
-    {DomCode::F6, DomKey::F6},
-    {DomCode::F7, DomKey::F7},
-    {DomCode::F8, DomKey::F8},
-    {DomCode::F9, DomKey::F9},
-    {DomCode::F10, DomKey::F10},
-    {DomCode::F11, DomKey::F11},
-    {DomCode::F12, DomKey::F12},
-    {DomCode::F13, DomKey::F13},
-    {DomCode::F14, DomKey::F14},
-    {DomCode::F15, DomKey::F15},
-    {DomCode::F16, DomKey::F16},
-    {DomCode::F17, DomKey::F17},
-    {DomCode::F18, DomKey::F18},
-    {DomCode::F19, DomKey::F19},
-    {DomCode::F20, DomKey::F20},
-    {DomCode::F21, DomKey::F21},
-    {DomCode::F22, DomKey::F22},
-    {DomCode::F23, DomKey::F23},
-    {DomCode::F24, DomKey::F24},
-    {DomCode::FIND, DomKey::FIND},
-    {DomCode::FN, DomKey::FN},
-    {DomCode::FN_LOCK, DomKey::FN_LOCK},
-    {DomCode::HELP, DomKey::HELP},
-    {DomCode::HOME, DomKey::HOME},
-    {DomCode::HYPER, DomKey::HYPER},
-    {DomCode::INSERT, DomKey::INSERT},
-    // {DomCode::INTL_RO, DomKey::_}
-    {DomCode::KANA_MODE, DomKey::KANA_MODE},
-    {DomCode::LANG1, DomKey::HANGUL_MODE},
-    {DomCode::LANG2, DomKey::HANJA_MODE},
-    {DomCode::LANG3, DomKey::KATAKANA},
-    {DomCode::LANG4, DomKey::HIRAGANA},
-    {DomCode::LANG5, DomKey::ZENKAKU_HANKAKU},
-    {DomCode::LAUNCH_APP1, DomKey::LAUNCH_MY_COMPUTER},
-    {DomCode::LAUNCH_APP2, DomKey::LAUNCH_CALCULATOR},
-    {DomCode::LAUNCH_MAIL, DomKey::LAUNCH_MAIL},
-    {DomCode::LAUNCH_SCREEN_SAVER, DomKey::LAUNCH_SCREEN_SAVER},
-    // {DomCode::LAUNCH_DOCUMENTS, DomKey::_}
-    // {DomCode::LAUNCH_FILE_BROWSER, DomKey::_}
-    // {DomCode::LAUNCH_KEYBOARD_LAYOUT, DomKey::_}
-    {DomCode::LOCK_SCREEN, DomKey::LAUNCH_SCREEN_SAVER},
-    {DomCode::MAIL_FORWARD, DomKey::MAIL_FORWARD},
-    {DomCode::MAIL_REPLY, DomKey::MAIL_REPLY},
-    {DomCode::MAIL_SEND, DomKey::MAIL_SEND},
-    {DomCode::MEDIA_PLAY_PAUSE, DomKey::MEDIA_PLAY_PAUSE},
-    {DomCode::MEDIA_SELECT, DomKey::MEDIA_SELECT},
-    {DomCode::MEDIA_STOP, DomKey::MEDIA_STOP},
-    {DomCode::MEDIA_TRACK_NEXT, DomKey::MEDIA_TRACK_NEXT},
-    {DomCode::MEDIA_TRACK_PREVIOUS, DomKey::MEDIA_TRACK_PREVIOUS},
-    // {DomCode::MENU, DomKey::_}
-    {DomCode::NON_CONVERT, DomKey::NON_CONVERT},
-    {DomCode::NUM_LOCK, DomKey::NUM_LOCK},
-    {DomCode::NUMPAD_BACKSPACE, DomKey::BACKSPACE, 0x0008},
-    {DomCode::NUMPAD_CLEAR, DomKey::CLEAR},
-    {DomCode::NUMPAD_ENTER, DomKey::ENTER, 0x000D},
-    // {DomCode::NUMPAD_CLEAR_ENTRY, DomKey::_}
-    // {DomCode::NUMPAD_MEMORY_ADD, DomKey::_}
-    // {DomCode::NUMPAD_MEMORY_CLEAR, DomKey::_}
-    // {DomCode::NUMPAD_MEMORY_RECALL, DomKey::_}
-    // {DomCode::NUMPAD_MEMORY_STORE, DomKey::_}
-    // {DomCode::NUMPAD_MEMORY_SUBTRACT, DomKey::_}
-    {DomCode::OPEN, DomKey::OPEN},
-    {DomCode::OS_LEFT, DomKey::OS},
-    {DomCode::OS_RIGHT, DomKey::OS},
-    {DomCode::PAGE_DOWN, DomKey::PAGE_DOWN},
-    {DomCode::PAGE_UP, DomKey::PAGE_UP},
-    {DomCode::PASTE, DomKey::PASTE},
-    {DomCode::PAUSE, DomKey::PAUSE},
-    {DomCode::POWER, DomKey::POWER},
-    {DomCode::PRINT_SCREEN, DomKey::PRINT_SCREEN},
-    {DomCode::PROPS, DomKey::PROPS},
-    {DomCode::SCROLL_LOCK, DomKey::SCROLL_LOCK},
-    {DomCode::SELECT, DomKey::SELECT},
-    // {DomCode::SELECT_TASK, DomKey::_}
-    {DomCode::SHIFT_LEFT, DomKey::SHIFT},
-    {DomCode::SHIFT_RIGHT, DomKey::SHIFT},
-    {DomCode::SUPER, DomKey::SUPER},
-    {DomCode::TAB, DomKey::TAB, 0x0009},
-    {DomCode::UNDO, DomKey::UNDO},
-    // {DomCode::VOICE_COMMAND, DomKey::_}
-    {DomCode::VOLUME_DOWN, DomKey::VOLUME_DOWN},
-    {DomCode::VOLUME_MUTE, DomKey::VOLUME_MUTE},
-    {DomCode::VOLUME_UP, DomKey::VOLUME_UP},
-    {DomCode::WAKE_UP, DomKey::WAKE_UP},
-    {DomCode::ZOOM_TOGGLE, DomKey::ZOOM_TOGGLE},
-};
-
-}  // anonymous namespace
-
 StubKeyboardLayoutEngine::StubKeyboardLayoutEngine() {
 }
 
@@ -259,42 +44,8 @@
                                       base::char16* out_character,
                                       KeyboardCode* out_key_code,
                                       uint32* platform_keycode) const {
-  if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) {
-    if (LookupControlCharacter(dom_code, flags, out_dom_key, out_character,
-                               out_key_code)) {
-      return true;
-    }
-  } else {
-    for (size_t i = 0; i < arraysize(printable_code_map); ++i) {
-      const PrintableCodeEntry* e = &printable_code_map[i];
-      if (e->dom_code == dom_code) {
-        int state = (((flags & EF_ALTGR_DOWN) == EF_ALTGR_DOWN) << 1) |
-                    ((flags & EF_SHIFT_DOWN) == EF_SHIFT_DOWN);
-        base::char16 ch = e->character[state];
-        *out_dom_key = (ch & DK) ? DomKey::DEAD : DomKey::CHARACTER;
-        *out_character = ch;
-        if ((flags & EF_CAPS_LOCK_DOWN) == EF_CAPS_LOCK_DOWN) {
-          ch = (ch & ~DK) | 0x20;
-          if ((ch >= 'a') && (ch <= 'z'))
-            *out_character = e->character[state ^ 1];
-        }
-        *out_key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
-        return true;
-      }
-    }
-  }
-
-  for (size_t i = 0; i < arraysize(non_printable_code_map); ++i) {
-    const NonPrintableCodeEntry* e = &non_printable_code_map[i];
-    if (e->dom_code == dom_code) {
-      *out_dom_key = e->dom_key;
-      *out_character = e->character;
-      *out_key_code = NonPrintableDomKeyToKeyboardCode(e->dom_key);
-      return true;
-    }
-  }
-
-  return false;
+  return DomCodeToUsLayoutMeaning(dom_code, flags, out_dom_key, out_character,
+                                  out_key_code);
 }
 
 }  // namespace ui
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
index 63b89fe..2d47cafe2 100644
--- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
+++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
@@ -657,6 +657,17 @@
 }
 #endif
 
+KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code) {
+  DomKey dummy_dom_key;
+  base::char16 dummy_character;
+  KeyboardCode key_code;
+  if (DomCodeToUsLayoutMeaning(dom_code, EF_NONE, &dummy_dom_key,
+                               &dummy_character, &key_code)) {
+    return key_code;
+  }
+  return VKEY_UNKNOWN;
+}
+
 }  // anonymous namespace
 
 XkbKeyCodeConverter::XkbKeyCodeConverter() {
@@ -775,21 +786,21 @@
       *key_code = DifficultKeyboardCode(dom_code, flags, xkb_keycode, xkb_flags,
                                         xkb_keysym, *dom_key, *character);
       if (*key_code == VKEY_UNKNOWN)
-        *key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
+        *key_code = DomCodeToUsLayoutKeyboardCode(dom_code);
     }
 
     if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) {
-      // Use GetCharacterFromKeyCode() to set |character| to 0x0 for key codes
-      // that we do not care about.
+      // Use GetCharacterFromKeyCode() to set |character| to 0x0 for keys that
+      // are not part of the accepted set of Control+Key combinations.
       *character = GetCharacterFromKeyCode(*key_code, flags);
     }
   } else if (*dom_key == DomKey::DEAD) {
     *character = DeadXkbKeySymToCombiningCharacter(xkb_keysym);
-    *key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
+    *key_code = DomCodeToUsLayoutKeyboardCode(dom_code);
   } else {
     *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key);
     if (*key_code == VKEY_UNKNOWN)
-      *key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
+      *key_code = DomCodeToUsLayoutKeyboardCode(dom_code);
   }
   return true;
 }
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h
index 382a9d3..099d7fd4 100644
--- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h
+++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h
@@ -58,7 +58,8 @@
 
   // Determines the Windows-based KeyboardCode (VKEY) for a character key,
   // accounting for non-US layouts. May return VKEY_UNKNOWN, in which case the
-  // caller should use |DomCodeToNonLocatedKeyboardCode()| as a last resort.
+  // caller should, as a last resort, obtain a KeyboardCode using
+  // |DomCodeToUsLayoutMeaning()|.
   KeyboardCode DifficultKeyboardCode(DomCode dom_code,
                                      int ui_flags,
                                      xkb_keycode_t xkb_keycode,
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc
index 87b4c55..f5195d0 100644
--- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc
+++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc
@@ -6,8 +6,8 @@
 #include "ui/events/event_constants.h"
 #include "ui/events/keycodes/dom3/dom_code.h"
 #include "ui/events/keycodes/dom3/dom_key.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
-#include "ui/events/ozone/layout/layout_util.h"
 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
 
 namespace ui {
@@ -72,16 +72,21 @@
     KeyboardCode key_code = DifficultKeyboardCode(
         dom_code, flags, key_code_converter_.DomCodeToXkbKeyCode(dom_code),
         flags, CharacterToKeySym(character), DomKey::CHARACTER, character);
-    if (key_code == VKEY_UNKNOWN)
-      key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
+    if (key_code == VKEY_UNKNOWN) {
+      DomKey dummy_dom_key;
+      base::char16 dummy_character;
+      // If this fails, key_code remains VKEY_UNKNOWN.
+      ignore_result(DomCodeToUsLayoutMeaning(dom_code, EF_NONE, &dummy_dom_key,
+                                             &dummy_character, &key_code));
+    }
     return key_code;
   }
 
   // XkbKeyboardLayoutEngine overrides:
   bool XkbLookup(xkb_keycode_t xkb_keycode,
-                         xkb_mod_mask_t xkb_flags,
-                         xkb_keysym_t* xkb_keysym,
-                         base::char16* character) const override {
+                 xkb_mod_mask_t xkb_flags,
+                 xkb_keysym_t* xkb_keysym,
+                 base::char16* character) const override {
     if (!entry_ ||
         (xkb_keycode != static_cast<xkb_keycode_t>(entry_->dom_code)))
       return false;
@@ -731,14 +736,14 @@
     if (e->shift_character) {
       // Test with predetermined shifted character.
       key_code = layout_engine_->GetKeyboardCode(e->dom_code, EF_SHIFT_DOWN,
-                                                e->shift_character);
+                                                 e->shift_character);
       EXPECT_EQ(e->key_code, key_code);
     }
 
     if (e->altgr_character) {
       // Test with predetermined AltGr character.
       key_code = layout_engine_->GetKeyboardCode(e->dom_code, EF_ALTGR_DOWN,
-          e->altgr_character);
+                                                 e->altgr_character);
       EXPECT_EQ(e->key_code, key_code);
     }
 
diff --git a/ui/file_manager/file_manager/foreground/css/cws_widget_container.css b/ui/file_manager/file_manager/foreground/css/cws_widget_container.css
index 8e4c5812..39f4a32 100644
--- a/ui/file_manager/file_manager/foreground/css/cws_widget_container.css
+++ b/ui/file_manager/file_manager/foreground/css/cws_widget_container.css
@@ -12,26 +12,30 @@
   position: relative;
 }
 
-.cws-widget-webview-container.cws-widget-show-spinner webview {
-  pointer-events: none;
-}
-
-.cws-widget-webview-container:not(.cws-widget-show-spinner)
-    .cws-widget-spinner-layer {
-  display: none;
-}
-
 .cws-widget-spinner-layer {
   background: url(../images/common/spinner.svg) center / 16px no-repeat;
   background-color: rgba(255, 255, 255, 0.7);
   bottom: 0;
   left: 0;
+  outline: none;
   position: absolute;
   right: 0;
   top: 0;
+  transition: opacity 500ms;
   z-index: 525;
 }
 
+.cws-widget-spinner-layer:not(.cws-widget-show-spinner) {
+  background: none;
+  opacity: 0;
+  pointer-events: none;
+}
+
+.cws-widget-spinner-layer.cws-widget-hiding-spinner {
+  /* Transition end event would not fire if opacity was set to 0. */
+  opacity: 0.01;
+}
+
 .cws-widget-buttons {
   background: #eee;
   width: 100%;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index b7e7b2c0..ff5f158b 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1162,7 +1162,7 @@
 }
 
 body:not(.check-select) .thumbnail-grid.image-dominant
-    .thumbnail-loaded:not([selected]) .thumbnail-bottom {
+    .can-hide-filename.thumbnail-loaded:not([selected]) .thumbnail-bottom {
   display: none;
 }
 
diff --git a/ui/file_manager/file_manager/foreground/js/cws_widget_container.js b/ui/file_manager/file_manager/foreground/js/cws_widget_container.js
index 45548c1..ad7eb42 100644
--- a/ui/file_manager/file_manager/foreground/js/cws_widget_container.js
+++ b/ui/file_manager/file_manager/foreground/js/cws_widget_container.js
@@ -75,7 +75,14 @@
    */
   var spinnerLayer = document.createElement('div');
   spinnerLayer.className = 'cws-widget-spinner-layer';
-  this.webviewContainer_.appendChild(spinnerLayer);
+  spinnerLayer.setAttribute('role', 'img');
+  // TODO(tbarzic): Set something meaningfull.
+  spinnerLayer.setAttribute('alt', '');
+  parentNode.appendChild(spinnerLayer);
+
+  /** @private {!CWSWidgetContainer.SpinnerLayerController} */
+  this.spinnerLayerController_ =
+      new CWSWidgetContainer.SpinnerLayerController(spinnerLayer);
 
   /**
    * The widget container's button strip.
@@ -376,7 +383,8 @@
     });
     this.webviewContainer_.appendChild(this.webview_);
 
-    this.webviewContainer_.classList.add('cws-widget-show-spinner');
+    this.spinnerLayerController_.setElementToFocusOnHide(this.webview_);
+    this.spinnerLayerController_.setVisible(true);
 
     this.webviewClient_ = new CWSContainerClient(
         this.webview_,
@@ -436,9 +444,9 @@
   CWSWidgetContainer.Metrics.recordLoad(
       CWSWidgetContainer.Metrics.LOAD.SUCCEEDED);
 
-  this.webviewContainer_.classList.remove('cws-widget-show-spinner');
   this.state_ = CWSWidgetContainer.State.INITIALIZED;
 
+  this.spinnerLayerController_.setVisible(false);
   this.webview_.focus();
 };
 
@@ -450,7 +458,7 @@
 CWSWidgetContainer.prototype.onWidgetLoadFailed_ = function(event) {
   CWSWidgetContainer.Metrics.recordLoad(CWSWidgetContainer.Metrics.LOAD.FAILED);
 
-  this.webviewContainer_.classList.remove('cws-widget-show-spinner');
+  this.spinnerLayerController_.setVisible(false);
   this.state_ = CWSWidgetContainer.State.INITIALIZE_FAILED_CLOSING;
   this.reportDone_();
 };
@@ -477,7 +485,7 @@
   this.appInstaller_ = new AppInstaller(itemId);
   this.appInstaller_.install(this.onItemInstalled_.bind(this));
 
-  this.webviewContainer_.classList.add('cws-widget-show-spinner');
+  this.spinnerLayerController_.setVisible(true);
   this.state_ = CWSWidgetContainer.State.INSTALLING;
 };
 
@@ -488,7 +496,7 @@
  * @private
  */
 CWSWidgetContainer.prototype.onInstallDone_ = function(e) {
-  this.webviewContainer_.classList.remove('cws-widget-show-spinner');
+  this.spinnerLayerController_.setVisible(false);
   this.state_ = CWSWidgetContainer.State.INSTALLED_CLOSING;
   this.reportDone_();
 };
@@ -505,7 +513,7 @@
   // If install succeeded, the spinner will be removed once
   // |this.webviewClient_| dispatched INSTALL_DONE event.
   if (!success)
-    this.webviewContainer_.classList.remove('cws-widget-show-spinner');
+    this.spinnerLayerController_.setVisible(false);
 
   this.state_ = success ?
                 CWSWidgetContainer.State.WAITING_FOR_CONFIRMATION :
@@ -640,6 +648,8 @@
     this.resolveStart_ = null;
   }
 
+  this.spinnerLayerController_.reset();
+
   if (this.webviewClient_) {
     this.webviewClient_.dispose();
     this.webviewClient_ = null;
@@ -658,6 +668,138 @@
 };
 
 /**
+ * Controls showing and hiding spinner layer.
+ * @param {!Element} spinnerLayer The spinner layer element.
+ * @constructor
+ */
+CWSWidgetContainer.SpinnerLayerController = function(spinnerLayer) {
+  /** @private {!Element} */
+  this.spinnerLayer_ = spinnerLayer;
+
+  /** @private {boolean} */
+  this.visible_ = false;
+
+  /**
+   * Set only if spinner is transitioning between visible and hidden states.
+   * Calling the function clears event handlers set for handling the transition,
+   * and updates spinner layer class list to its final state.
+   * @type {?function()}
+   * @private
+   */
+  this.clearTransition_ = null;
+
+  /**
+   * Reference to the timeout set to ensure {@code this.clearTransision_} gets
+   * called even if 'transitionend' event does not fire.
+   * @type {?number}
+   * @private
+   */
+  this.clearTransitionTimeout_ = null;
+
+  /**
+   * Element to be focused when the layer is hidden.
+   * @type {Element}
+   * @private
+   */
+  this.focusOnHide_ = null;
+
+  spinnerLayer.tabIndex = -1;
+
+  // Prevent default Tab key handling in order to prevent the widget from
+  // taking the focus while the spinner layer is active.
+  // NOTE: This assumes that there are no elements allowed to become active
+  // while the spinner is shown. Something smarter would be needed if this
+  // assumption becomes invalid.
+  spinnerLayer.addEventListener('keydown', this.handleKeyDown_.bind(this));
+};
+
+/**
+ * Sets element to be focused when the layer is hidden.
+ * @param {!Element} el
+ */
+CWSWidgetContainer.SpinnerLayerController.prototype.setElementToFocusOnHide =
+    function(el) {
+  this.focusOnHide_ = el;
+};
+
+/**
+ * Prevents default Tab key handling in order to prevent spinner layer from
+ * losing focus.
+ * @param {Event} e The key down event.
+ * @private
+ */
+CWSWidgetContainer.SpinnerLayerController.prototype.handleKeyDown_ =
+    function(e) {
+  if (!this.visible_)
+    return;
+  if (e.keyCode === 9 /* Tab */)
+    e.preventDefault();
+};
+
+/**
+ * Resets the spinner layer controllers state, and makes sure the spinner
+ * layre gets hidden.
+ */
+CWSWidgetContainer.SpinnerLayerController.prototype.reset = function() {
+  this.visible_ = false;
+  this.focusOnHide_ = null;
+  if (this.clearTransision_)
+    this.clearTransition_();
+};
+
+/**
+ * Shows or hides the spinner layer and handles the layer's opacity transition.
+ * @param {boolean} visible Whether the layer should become visible.
+ */
+CWSWidgetContainer.SpinnerLayerController.prototype.setVisible =
+    function(visible) {
+  if (this.visible_ === visible)
+    return;
+
+  if (this.clearTransition_)
+    this.clearTransition_();
+
+  this.visible_ = visible;
+
+  // Spinner should be shown during transition.
+  if (!this.spinnerLayer_.classList.contains('cws-widget-show-spinner'))
+    this.spinnerLayer_.classList.add('cws-widget-show-spinner');
+
+  if (this.visible_) {
+    this.spinnerLayer_.focus();
+   } else if (this.focusOnHide_) {
+        this.focusOnHide_.focus();
+   }
+
+  if (!this.visible_)
+    this.spinnerLayer_.classList.add('cws-widget-hiding-spinner');
+
+  this.clearTransition_ = function() {
+    if (this.clearTransitionTimeout_)
+      clearTimeout(this.clearTransitionTimeout_);
+    this.clearTransitionTimeout_ = null;
+
+    this.spinnerLayer_.removeEventListener(
+        'transitionend', this.clearTransition_);
+    this.clearTransition_ = null;
+
+    if (!this.visible_) {
+      this.spinnerLayer_.classList.remove('cws-widget-hiding-spinner');
+      this.spinnerLayer_.classList.remove('cws-widget-show-spinner');
+    }
+  }.bind(this);
+
+  this.spinnerLayer_.addEventListener('transitionend', this.clearTransition_);
+
+  // Ensure the transition state gets cleared, even if transitionend is not
+  // fired.
+  this.clearTransitionTimeout_ = setTimeout(function() {
+    this.clearTransitionTimeout_ = null;
+    this.clearTransition_();
+  }.bind(this), 550 /* ms */);
+};
+
+/**
  * Utility methods and constants to record histograms.
  */
 CWSWidgetContainer.Metrics = {};
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 5b34d88..4dd71e8d 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -946,23 +946,17 @@
 
           var previousDirEntry =
               this.currentDirContents_.getDirectoryEntry();
+          this.clearAndScan_(
+               newDirectoryContents,
+               function(result) {
+                 // Calls the callback of the method when successful.
+                 if (result && opt_callback)
+                   opt_callback();
 
-          var promises = [];
-
-          promises.push(
-              new Promise(
-                  /** @this {DirectoryModel} */
-                  function(resolve) {
-                    this.clearAndScan_(
-                        newDirectoryContents,
-                        function(result) {
-                          // Calls the callback of the method when successful.
-                          if (result && opt_callback)
-                            opt_callback();
-
-                          resolve(undefined);
-                        });
-                  }.bind(this)));
+                 // Notify that the current task of this.directoryChangeQueue_
+                 // is completed.
+                 setTimeout(queueTaskCallback, 0);
+               });
 
           // For tests that open the dialog to empty directories, everything
           // is loaded at this point.
@@ -976,13 +970,11 @@
           event.previousDirEntry = previousDirEntry;
           event.newDirEntry = dirEntry;
           event.volumeChanged = previousVolumeInfo !== currentVolumeInfo;
+          this.dispatchEvent(event);
 
           if (event.volumeChanged) {
-            promises.push(this.onVolumeChanged_(currentVolumeInfo));
+            this.onVolumeChanged_(assert(currentVolumeInfo));
           }
-
-          this.dispatchEvent(event);
-          Promise.all(promises).then(queueTaskCallback);
         }.bind(this));
   }.bind(this, this.changeDirectorySequence_));
 };
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 5fa935ff..14fc3b7 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -247,7 +247,7 @@
 
   /**
    * The document object of this app.
-   * @type {HTMLDocument}
+   * @type {Document}
    * @private
    */
   this.document_ = null;
@@ -297,7 +297,7 @@
     return this.ui_.directoryTree;
   },
   /**
-   * @return {HTMLDocument}
+   * @return {Document}
    */
   get document() {
     return this.document_;
@@ -450,9 +450,9 @@
             this.importController_ = new importer.ImportController(
                 new importer.RuntimeControllerEnvironment(
                     this,
-                    this.selectionHandler_),
-                this.mediaScanner_,
-                this.mediaImportHandler_,
+                    assert(this.selectionHandler_)),
+                assert(this.mediaScanner_),
+                assert(this.mediaImportHandler_),
                 new importer.RuntimeCommandWidget(),
                 assert(this.tracker_));
           }
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 2eeb6a7..ce4b01a 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
@@ -16,7 +16,7 @@
 var FileAsyncData;
 
 /**
- * @param {!HTMLDocument} doc Owning document.
+ * @param {!Document} doc Owning document.
  * @param {!DirectoryTree} directoryTree Directory tree.
  * @param {!ListContainer} listContainer List container.
  * @param {!MultiProfileShareDialog} multiProfileShareDialog Share dialog to be
@@ -44,7 +44,7 @@
                                 volumeManager,
                                 selectionHandler) {
   /**
-   * @type {!HTMLDocument}
+   * @type {!Document}
    * @private
    * @const
    */
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 89ab4b5..7049bae3 100644
--- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
+++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
@@ -188,7 +188,7 @@
   this.canvasUpToDate_ = false;
   this.image_ = new Image();
   this.image_.onload = function() {
-    this.attachImage(box, fillMode);
+    this.attachImage(assert(box), fillMode);
     if (opt_onSuccess)
       opt_onSuccess(this.image_, this.transform_);
   }.bind(this);
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 cfb1fa4f..bf208d0 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
@@ -36,8 +36,10 @@
     if (this.dataModel)
       this.dataModel.removeEventListener('splice', this.onSplice_.bind(this));
     this.dataModelDescriptor_.set.call(this, model);
-    if (this.dataModel)
+    if (this.dataModel) {
       this.dataModel.addEventListener('splice', this.onSplice_.bind(this));
+      this.classList.toggle('image-dominant', this.dataModel.isImageDominant());
+    }
   }
 };
 
@@ -591,6 +593,7 @@
     box.setAttribute('generic-thumbnail', mediaType);
     li.classList.toggle('thumbnail-loaded', false);
   }
+  li.classList.toggle('can-hide-filename', FileType.isImage(entry));
 };
 
 /**
@@ -890,6 +893,8 @@
     return -1;
 
   var row = this.grid_.getItemRow(index);
+  if (row - 1 < 0)
+    return 0;
   var col = this.grid_.getItemColumn(index);
   var nextIndex = this.grid_.getItemIndex(row - 1, col);
   if (nextIndex === -1) {
diff --git a/ui/file_manager/gallery/css/gallery.css b/ui/file_manager/gallery/css/gallery.css
index 3caae070..7b933b20 100644
--- a/ui/file_manager/gallery/css/gallery.css
+++ b/ui/file_manager/gallery/css/gallery.css
@@ -104,7 +104,7 @@
   pointer-events: none;
   position: absolute;
   /* Duration and timing function are set in Javascript. */
-  transition-property: -webkit-transform, opacity;
+  transition-property: transform, opacity;
 }
 
 .gallery .image-container > .image[fade] {
@@ -113,7 +113,8 @@
 
 /* Full resolution image is invisible unless printing. */
 .gallery .image-container > canvas.fullres {
-  display: none;
+  opacity: 0;
+  position: absolute;
 }
 
 @media print {
@@ -138,8 +139,13 @@
   /* Print the full resolution image instead. */
   .gallery .image-container > canvas.fullres {
     display: block !important;
+    height: auto !important;
     max-height: 100%;
     max-width: 100%;
+    position: static !important;
+    transform: none !important;
+    visibility: visible !important;
+    width: auto !important;
   }
 }
 
@@ -392,7 +398,7 @@
 }
 
 .gallery .filename-spacer .saved[highlighted] {
-  -webkit-transform: scaleX(1.1) scaleY(1.1) rotate(0);
+  transform: scaleX(1.1) scaleY(1.1) rotate(0);
   opacity: 1;
 }
 
@@ -1152,7 +1158,7 @@
   top: 0;
 
   /* transition-duration is set in Javascript. */
-  transition-property: -webkit-transform;
+  transition-property: transform;
   transition-timing-function: linear;
 }
 
@@ -1172,7 +1178,7 @@
   position: absolute;
   /* Tile's zoom factor is animated on hover. We apply the transform to
   the entire tile so that the image outline is included into the animation. */
-  transition: -webkit-transform 150ms linear;
+  transition: transform 150ms linear;
   z-index: 50;
 }
 
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 76b837f..0737ce8 100644
--- a/ui/file_manager/gallery/js/image_editor/image_view.js
+++ b/ui/file_manager/gallery/js/image_editor/image_view.js
@@ -179,6 +179,11 @@
 ImageView.prototype.draw = function() {
   if (!this.contentCanvas_)  // Do nothing if the image content is not set.
     return;
+  this.setTransform_(
+      this.contentCanvas_,
+      this.viewport_,
+      new ImageView.Effect.None(),
+      ImageView.Effect.DEFAULT_DURATION);
   if ((this.screenImage_ && this.setupDeviceBuffer(this.screenImage_)) ||
       this.displayedContentGeneration_ !== this.contentGeneration_) {
     this.displayedContentGeneration_ = this.contentGeneration_;
@@ -194,13 +199,23 @@
  * change or offset change) with animation.
  */
 ImageView.prototype.applyViewportChange = function() {
-  if (this.screenImage_) {
+  var zooming = this.viewport_.getZoom() > 1;
+  if (this.contentCanvas_) {
+    // Show full resolution image only for zooming.
+    this.contentCanvas_.style.opacity = zooming ? '1' : '0';
     this.setTransform_(
-        this.screenImage_,
+        this.contentCanvas_,
         this.viewport_,
         new ImageView.Effect.None(),
         ImageView.Effect.DEFAULT_DURATION);
   }
+  if (this.screenImage_) {
+      this.setTransform_(
+          this.screenImage_,
+          this.viewport_,
+          new ImageView.Effect.None(),
+          ImageView.Effect.DEFAULT_DURATION);
+  }
 };
 
 /**
@@ -300,16 +315,7 @@
     canvas.height = deviceRect.height;
     needRepaint = true;
   }
-
-  // Center the image.
-  var imageBounds = this.viewport_.getImageElementBoundsOnScreen();
-  canvas.style.left = imageBounds.left + 'px';
-  canvas.style.top = imageBounds.top + 'px';
-  canvas.style.width = imageBounds.width + 'px';
-  canvas.style.height = imageBounds.height + 'px';
-
   this.setTransform_(canvas, this.viewport_);
-
   return needRepaint;
 };
 
@@ -562,6 +568,8 @@
     // Insert the full resolution canvas into DOM so that it can be printed.
     this.container_.appendChild(this.contentCanvas_);
     this.contentCanvas_.classList.add('fullres');
+    this.setTransform_(
+        this.contentCanvas_, this.viewport_, null, 0);
 
     this.contentItem_.contentImage = this.contentCanvas_;
     this.contentItem_.screenImage = this.screenImage_;
@@ -622,7 +630,6 @@
     content, opt_effect, opt_width, opt_height, opt_preview) {
   var oldScreenImage = this.screenImage_;
   var oldViewport = this.viewport_.clone();
-
   this.replaceContent_(content, opt_width, opt_height, opt_preview);
   if (!opt_effect) {
     if (oldScreenImage)
@@ -638,33 +645,47 @@
     ImageUtil.setAttribute(newScreenImage, 'fade', true);
   this.setTransform_(
       newScreenImage, this.viewport_, opt_effect, 0 /* instant */);
+  this.setTransform_(
+      content, this.viewport_, opt_effect, 0 /* instant */);
 
-  setTimeout(function() {
-    this.setTransform_(
-        newScreenImage,
-        this.viewport_,
-        null,
-        opt_effect ? opt_effect.getDuration() : undefined);
-    if (oldScreenImage) {
-      ImageUtil.setAttribute(newScreenImage, 'fade', false);
-      ImageUtil.setAttribute(oldScreenImage, 'fade', true);
-      var reverse = opt_effect.getReverse();
-      if (reverse) {
-        this.setTransform_(oldScreenImage, oldViewport, reverse);
-        setTimeout(function() {
-          if (oldScreenImage.parentNode)
-            oldScreenImage.parentNode.removeChild(oldScreenImage);
-        }, reverse.getSafeInterval());
-      } else {
-        if (oldScreenImage.parentNode)
-          oldScreenImage.parentNode.removeChild(oldScreenImage);
+  // We need to call requestAnimationFrame twice here. The first call is for
+  // commiting the styles of beggining of transition that are assigned above.
+  // The second call is for assigning and commiting the styles of end of
+  // transition, which triggers transition animation.
+  requestAnimationFrame(function() {
+    requestAnimationFrame(function() {
+      this.setTransform_(
+          newScreenImage,
+          this.viewport_,
+          null,
+          opt_effect ? opt_effect.getDuration() : undefined);
+      this.setTransform_(
+          content,
+          this.viewport_,
+          null,
+          opt_effect ? opt_effect.getDuration() : undefined);
+      if (oldScreenImage) {
+        ImageUtil.setAttribute(newScreenImage, 'fade', false);
+        ImageUtil.setAttribute(oldScreenImage, 'fade', true);
+        var reverse = opt_effect.getReverse();
+        if (reverse) {
+          this.setTransform_(oldScreenImage, oldViewport, reverse);
+          setTimeout(function() {
+            if (oldScreenImage.parentNode)
+              oldScreenImage.parentNode.removeChild(oldScreenImage);
+          }, reverse.getSafeInterval());
+        } else {
+            if (oldScreenImage.parentNode)
+              oldScreenImage.parentNode.removeChild(oldScreenImage);
+        }
       }
-    }
-  }.bind(this), 0);
+    }.bind(this));
+  }.bind(this));
 };
 
 /**
- * @param {!HTMLCanvasElement} element The element to transform.
+ * @param {!HTMLCanvasElement|!HTMLImageElement} element The element to
+ *     transform.
  * @param {!Viewport} viewport Viewport to be used for calculating
  *     transformation.
  * @param {ImageView.Effect=} opt_effect The effect to apply.
@@ -677,9 +698,14 @@
     opt_effect = new ImageView.Effect.None();
   if (typeof opt_duration !== 'number')
     opt_duration = opt_effect.getDuration();
-  element.style.webkitTransitionDuration = opt_duration + 'ms';
-  element.style.webkitTransitionTimingFunction = opt_effect.getTiming();
-  element.style.webkitTransform = opt_effect.transform(element, viewport);
+  element.style.transitionDuration = opt_duration + 'ms';
+  element.style.transitionTimingFunction = opt_effect.getTiming();
+  element.style.transform = opt_effect.transform(element, viewport);
+  var imageBounds = viewport.getImageElementBoundsOnScreen();
+  element.style.left = imageBounds.left + 'px';
+  element.style.top = imageBounds.top + 'px';
+  element.style.width = imageBounds.width + 'px';
+  element.style.height = imageBounds.height + 'px';
 };
 
 /**
@@ -823,8 +849,8 @@
 
 /**
  * Obtains the CSS transformation string of the effect.
- * @param {!HTMLCanvasElement} element Canvas element to be applied the
- *     transformation.
+ * @param {!HTMLCanvasElement|!HTMLImageElement} element Canvas element to be
+ *     applied the transformation.
  * @param {!Viewport} viewport Current viewport.
  * @return {string} CSS transformation description.
  */
@@ -849,9 +875,7 @@
 ImageView.Effect.None.prototype = { __proto__: ImageView.Effect.prototype };
 
 /**
- * @param {!HTMLCanvasElement} element Element.
- * @param {!Viewport} viewport Current viewport.
- * @return {string} Transform string.
+ * @override
  */
 ImageView.Effect.None.prototype.transform = function(element, viewport) {
   return viewport.getTransformation();
diff --git a/ui/file_manager/gallery/js/mosaic_mode.js b/ui/file_manager/gallery/js/mosaic_mode.js
index ea5e355f1..1138a674 100644
--- a/ui/file_manager/gallery/js/mosaic_mode.js
+++ b/ui/file_manager/gallery/js/mosaic_mode.js
@@ -711,9 +711,9 @@
  */
 Mosaic.prototype.transform = function(tileRect, imageRect, opt_instant) {
   if (opt_instant) {
-    this.style.webkitTransitionDuration = '0';
+    this.style.transitionDuration = '0';
   } else {
-    this.style.webkitTransitionDuration =
+    this.style.transitionDuration =
         ImageView.MODE_TRANSITION_DURATION + 'ms';
   }
 
@@ -724,11 +724,11 @@
         (tileRect.left + tileRect.width / 2);
     var shiftY = (imageRect.top + imageRect.height / 2) -
         (tileRect.top + tileRect.height / 2);
-    this.style.webkitTransform =
+    this.style.transform =
         'translate(' + shiftX * scaleX + 'px, ' + shiftY * scaleY + 'px)' +
         'scaleX(' + scaleX + ') scaleY(' + scaleY + ')';
   } else {
-    this.style.webkitTransform = '';
+    this.style.transform = '';
   }
 };
 
diff --git a/ui/gfx/display.cc b/ui/gfx/display.cc
index 63353713..6ae51b6 100644
--- a/ui/gfx/display.cc
+++ b/ui/gfx/display.cc
@@ -198,12 +198,19 @@
   return is_valid() && (id_ == internal_display_id_);
 }
 
+// static
 int64 Display::InternalDisplayId() {
   return internal_display_id_;
 }
 
+// static
 void Display::SetInternalDisplayId(int64 internal_display_id) {
   internal_display_id_ = internal_display_id;
 }
 
+// static
+bool Display::HasInternalDisplay() {
+  return internal_display_id_ != kInvalidDisplayID;
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/display.h b/ui/gfx/display.h
index fe2a40c..6f29d42 100644
--- a/ui/gfx/display.h
+++ b/ui/gfx/display.h
@@ -122,6 +122,9 @@
   static int64 InternalDisplayId();
   static void SetInternalDisplayId(int64 internal_display_id);
 
+  // True if there is an internal display.
+  static bool HasInternalDisplay();
+
   static const int64 kInvalidDisplayID;
 
  private:
diff --git a/ui/gfx/ios/OWNERS b/ui/gfx/ios/OWNERS
index f2fff55..ae82009 100644
--- a/ui/gfx/ios/OWNERS
+++ b/ui/gfx/ios/OWNERS
@@ -1,3 +1,2 @@
-lliabraa@chromium.org
 rohitrao@chromium.org
 sdefresne@chromium.org
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index fe4899ea..1ceec517 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -587,13 +587,20 @@
     { L"01" L"\x5d0\x5d1\x5d2", L"01\x5d0\x5d1\x2026", true },
     // RLM marker added as "ab" have strong LTR directionality.
     { L"ab" L"\x5d0\x5d1\x5d2", L"ab\x5d0\x5d1\x2026\x200f", true },
-    // Complex script is not handled. In this example, the "\x0915\x093f" is a
-    // compound glyph, but only half of it is elided.
-    { L"0123\x0915\x093f", L"0123\x0915\x2026", true },
-    // Surrogate pairs should be elided reasonably enough.
+    // Test surrogate pairs. \xd834\xdd1e forms a single code point U+1D11E;
+    // \xd834\xdd22 forms a second code point U+1D122. The first should be kept;
+    // the second removed (no surrogate pair should be partially elided).
+    { L"0123\xd834\xdd1e\xd834\xdd22", L"0123\xd834\xdd1e\x2026", true },
+    // Test combining character sequences. U+0915 U+093F forms a compound glyph;
+    // U+0915 U+0942 forms a second compound glyph. The first should be kept;
+    // the second removed (no combining sequence should be partially elided).
+    { L"0123\x0915\x093f\x0915\x0942", L"0123\x0915\x093f\x2026", true },
+    // U+05E9 U+05BC U+05C1 U+05B8 forms a four-character compound glyph. Again,
+    // it should be either fully elided, or not elided at all. If completely
+    // elided, an LTR Mark (U+200E) should be added.
     { L"0\x05e9\x05bc\x05c1\x05b8",   L"0\x05e9\x05bc\x05c1\x05b8", false },
-    { L"0\x05e9\x05bc\x05c1\x05b8",   L"0\x05e9\x05bc\x2026"      , true  },
-    { L"01\x05e9\x05bc\x05c1\x05b8",  L"01\x05e9\x2026"           , true  },
+    { L"0\x05e9\x05bc\x05c1\x05b8",   L"0\x2026\x200E"            , true  },
+    { L"01\x05e9\x05bc\x05c1\x05b8",  L"01\x2026\x200E"           , true  },
     { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x2026\x200E"          , true  },
     { L"012\xF0\x9D\x84\x9E",         L"012\xF0\x2026"            , true  },
   };
diff --git a/ui/gfx/text_elider.cc b/ui/gfx/text_elider.cc
index afcdb1d..fcfc71f6 100644
--- a/ui/gfx/text_elider.cc
+++ b/ui/gfx/text_elider.cc
@@ -9,6 +9,8 @@
 
 #include "ui/gfx/text_elider.h"
 
+#include <stdint.h>
+
 #include <string>
 #include <vector>
 
@@ -23,7 +25,10 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "third_party/icu/source/common/unicode/rbbi.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
 #include "third_party/icu/source/common/unicode/uloc.h"
+#include "third_party/icu/source/common/unicode/umachine.h"
+#include "third_party/icu/source/common/unicode/utf16.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/render_text.h"
@@ -99,6 +104,22 @@
 }
 #endif
 
+// Returns true if the code point |c| is a combining mark character in Unicode.
+bool CharIsMark(UChar32 c) {
+  int8_t char_type = u_charType(c);
+  return char_type == U_NON_SPACING_MARK || char_type == U_ENCLOSING_MARK ||
+         char_type == U_COMBINING_SPACING_MARK;
+}
+
+// Gets the code point of |str| at the given code unit position |index|. If
+// |index| is a surrogate code unit, returns the whole code point (unless the
+// code unit is unpaired, in which case it just returns the surrogate value).
+UChar32 GetCodePointAt(const base::string16& str, size_t index) {
+  UChar32 c;
+  U16_GET(str.data(), 0, index, str.size(), c);
+  return c;
+}
+
 }  // namespace
 
 // U+2026 in utf8
@@ -116,7 +137,8 @@
       elide_at_beginning_(elide_at_beginning) {
 }
 
-base::string16 StringSlicer::CutString(size_t length, bool insert_ellipsis) {
+base::string16 StringSlicer::CutString(size_t length,
+                                       bool insert_ellipsis) const {
   const base::string16 ellipsis_text = insert_ellipsis ? ellipsis_
                                                        : base::string16();
 
@@ -130,18 +152,25 @@
   // We put the extra character, if any, before the cut.
   const size_t half_length = length / 2;
   const size_t prefix_length = FindValidBoundaryBefore(length - half_length);
-  const size_t suffix_start_guess = text_.length() - half_length;
-  const size_t suffix_start = FindValidBoundaryAfter(suffix_start_guess);
-  const size_t suffix_length =
-      half_length - (suffix_start_guess - suffix_start);
+  const size_t suffix_start =
+      FindValidBoundaryAfter(text_.length() - half_length);
   return text_.substr(0, prefix_length) + ellipsis_text +
-         text_.substr(suffix_start, suffix_length);
+         text_.substr(suffix_start);
 }
 
 size_t StringSlicer::FindValidBoundaryBefore(size_t index) const {
-  DCHECK_LE(index, text_.length());
-  if (index != text_.length())
-    U16_SET_CP_START(text_.data(), 0, index);
+  size_t length = text_.length();
+  DCHECK_LE(index, length);
+  if (index == length)
+    return index;
+
+  // If |index| straddles a combining character sequence, go back until we find
+  // a base character.
+  while (index > 0 && CharIsMark(GetCodePointAt(text_, index)))
+    --index;
+
+  // If |index| straddles a UTF-16 surrogate pair, go back.
+  U16_SET_CP_START(text_.data(), 0, index);
   return index;
 }
 
@@ -152,6 +181,15 @@
 
   int32_t text_index = base::checked_cast<int32_t>(index);
   int32_t text_length = base::checked_cast<int32_t>(text_.length());
+
+  // If |index| straddles a combining character sequence, go forward until we
+  // find a base character.
+  while (text_index < text_length &&
+         CharIsMark(GetCodePointAt(text_, text_index))) {
+    ++text_index;
+  }
+
+  // If |index| straddles a UTF-16 surrogate pair, go forward.
   U16_SET_CP_LIMIT(text_.data(), 0, text_index, text_length);
   return static_cast<size_t>(text_index);
 }
@@ -245,12 +283,13 @@
   size_t lo = 0;
   size_t hi = text.length() - 1;
   size_t guess;
+  base::string16 cut;
   for (guess = (lo + hi) / 2; lo <= hi; guess = (lo + hi) / 2) {
     // We check the width of the whole desired string at once to ensure we
     // handle kerning/ligatures/etc. correctly.
     // TODO(skanuj) : Handle directionality of ellipsis based on adjacent
     // characters.  See crbug.com/327963.
-    const base::string16 cut = slicer.CutString(guess, insert_ellipsis);
+    cut = slicer.CutString(guess, insert_ellipsis);
     const float guess_width = GetStringWidthF(cut, font_list);
     if (guess_width == available_pixel_width)
       break;
@@ -264,7 +303,7 @@
     }
   }
 
-  return slicer.CutString(guess, insert_ellipsis);
+  return cut;
 #endif
 }
 
diff --git a/ui/gfx/text_elider.h b/ui/gfx/text_elider.h
index 6b24ea6..1269caf 100644
--- a/ui/gfx/text_elider.h
+++ b/ui/gfx/text_elider.h
@@ -28,20 +28,27 @@
 GFX_EXPORT extern const base::char16 kEllipsisUTF16[];
 GFX_EXPORT extern const base::char16 kForwardSlash;
 
-// Helper class to split + elide text, while respecting UTF16 surrogate pairs.
-class StringSlicer {
+// Helper class to split + elide text, while respecting UTF-16 surrogate pairs
+// and combining character sequences.
+class GFX_EXPORT StringSlicer {
  public:
+  // Warning: Retains a reference to |text| and |ellipsis|. They must have a
+  // longer lifetime than the StringSlicer.
   StringSlicer(const base::string16& text,
                const base::string16& ellipsis,
                bool elide_in_middle,
                bool elide_at_beginning);
 
-  // Cuts |text_| to be |length| characters long. If |elide_in_middle_| is true,
-  // the middle of the string is removed to leave equal-length pieces from the
-  // beginning and end of the string; otherwise, the end of the string is
-  // removed and only the beginning remains. If |insert_ellipsis| is true,
-  // then an ellipsis character will be inserted at the cut point.
-  base::string16 CutString(size_t length, bool insert_ellipsis);
+  // Cuts |text_| to be at most |length| UTF-16 code units long. If
+  // |elide_in_middle_| is true, the middle of the string is removed to leave
+  // equal-length pieces from the beginning and end of the string; otherwise,
+  // the end of the string is removed and only the beginning remains. If
+  // |insert_ellipsis| is true, then an ellipsis character will be inserted at
+  // the cut point (note that the ellipsis will does not count towards the
+  // |length| limit).
+  // Note: Characters may still be omitted even if |length| is the full string
+  // length, if surrogate pairs fall on the split boundary.
+  base::string16 CutString(size_t length, bool insert_ellipsis) const;
 
  private:
   // Returns a valid cut boundary at or before/after |index|.
diff --git a/ui/gfx/text_elider_unittest.cc b/ui/gfx/text_elider_unittest.cc
index 01269ae..641a31f 100644
--- a/ui/gfx/text_elider_unittest.cc
+++ b/ui/gfx/text_elider_unittest.cc
@@ -6,6 +6,8 @@
 
 #include "ui/gfx/text_elider.h"
 
+#include <vector>
+
 #include "base/files/file_path.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/scoped_ptr.h"
@@ -299,10 +301,11 @@
 }
 
 // Checks that all occurrences of |first_char| are followed by |second_char| and
-// all occurrences of |second_char| are preceded by |first_char| in |text|.
-static void CheckSurrogatePairs(const base::string16& text,
-                                base::char16 first_char,
-                                base::char16 second_char) {
+// all occurrences of |second_char| are preceded by |first_char| in |text|. Can
+// be used to test surrogate pairs or two-character combining sequences.
+static void CheckCodeUnitPairs(const base::string16& text,
+                               base::char16 first_char,
+                               base::char16 second_char) {
   for (size_t index = 0; index < text.length(); ++index) {
     EXPECT_NE(second_char, text[index]);
     if (text[index] == first_char) {
@@ -312,37 +315,49 @@
   }
 }
 
+// Test that both both UTF-16 surrogate pairs and combining character sequences
+// do not get split by ElideText.
 // TODO(338784): Enable this on android.
 #if defined(OS_ANDROID)
-#define MAYBE_ElideTextSurrogatePairs DISABLED_ElideTextSurrogatePairs
+#define MAYBE_ElideTextAtomicSequences DISABLED_ElideTextAtomicSequences
 #else
-#define MAYBE_ElideTextSurrogatePairs ElideTextSurrogatePairs
+#define MAYBE_ElideTextAtomicSequences ElideTextAtomicSequences
 #endif
-TEST(TextEliderTest, MAYBE_ElideTextSurrogatePairs) {
+TEST(TextEliderTest, MAYBE_ElideTextAtomicSequences) {
   const FontList font_list;
-  // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as
-  // two characters forming a surrogate pair 0x0001D11E.
-  const std::string kSurrogate = "\xF0\x9D\x84\x9E";
-  const base::string16 kTestString = UTF8ToUTF16(kSurrogate + "x" + kSurrogate);
-  const float kTestStringWidth = GetStringWidthF(kTestString, font_list);
-  const base::char16 kSurrogateFirstChar = kTestString[0];
-  const base::char16 kSurrogateSecondChar = kTestString[1];
-  base::string16 result;
+  // The below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in
+  // UTF-16 as two code units forming a surrogate pair: 0xD834 0xDD1E.
+  const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
+  // The below is a Devanagari two-character combining sequence U+0921 U+093F.
+  // The sequence forms a single display character and should not be separated.
+  const base::char16 kCombiningSequence[] = {0x921, 0x93F, 0};
+  std::vector<base::string16> pairs;
+  pairs.push_back(kSurrogate);
+  pairs.push_back(kCombiningSequence);
 
-  // Elide |kTextString| to all possible widths and check that no instance of
-  // |kSurrogate| was split in two.
-  for (float width = 0; width <= kTestStringWidth; width++) {
-    result = ElideText(kTestString, font_list, width, TRUNCATE);
-    CheckSurrogatePairs(result, kSurrogateFirstChar, kSurrogateSecondChar);
+  for (const base::string16& pair : pairs) {
+    base::char16 first_char = pair[0];
+    base::char16 second_char = pair[1];
+    base::string16 test_string = pair + UTF8ToUTF16("x") + pair;
+    SCOPED_TRACE(test_string);
+    const float test_string_width = GetStringWidthF(test_string, font_list);
+    base::string16 result;
 
-    result = ElideText(kTestString, font_list, width, ELIDE_TAIL);
-    CheckSurrogatePairs(result, kSurrogateFirstChar, kSurrogateSecondChar);
+    // Elide |text_string| to all possible widths and check that no instance of
+    // |pair| was split in two.
+    for (float width = 0; width <= test_string_width; width++) {
+      result = ElideText(test_string, font_list, width, TRUNCATE);
+      CheckCodeUnitPairs(result, first_char, second_char);
 
-    result = ElideText(kTestString, font_list, width, ELIDE_MIDDLE);
-    CheckSurrogatePairs(result, kSurrogateFirstChar, kSurrogateSecondChar);
+      result = ElideText(test_string, font_list, width, ELIDE_TAIL);
+      CheckCodeUnitPairs(result, first_char, second_char);
 
-    result = ElideText(kTestString, font_list, width, ELIDE_HEAD);
-    CheckSurrogatePairs(result, kSurrogateFirstChar, kSurrogateSecondChar);
+      result = ElideText(test_string, font_list, width, ELIDE_MIDDLE);
+      CheckCodeUnitPairs(result, first_char, second_char);
+
+      result = ElideText(test_string, font_list, width, ELIDE_HEAD);
+      CheckCodeUnitPairs(result, first_char, second_char);
+    }
   }
 }
 
@@ -440,6 +455,136 @@
   }
 }
 
+// Detailed tests for StringSlicer. These are faster and test more of the edge
+// cases than the above tests which are more end-to-end.
+
+TEST(TextEliderTest, StringSlicerBasicTest) {
+  // Must store strings in variables (StringSlicer retains a reference to them).
+  base::string16 text(UTF8ToUTF16("Hello, world!"));
+  base::string16 ellipsis(kEllipsisUTF16);
+  StringSlicer slicer(text, ellipsis, false, false);
+
+  EXPECT_EQ(UTF8ToUTF16(""), slicer.CutString(0, false));
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
+
+  EXPECT_EQ(UTF8ToUTF16("Hell"), slicer.CutString(4, false));
+  EXPECT_EQ(UTF8ToUTF16("Hell") + kEllipsisUTF16, slicer.CutString(4, true));
+
+  EXPECT_EQ(text, slicer.CutString(text.length(), false));
+  EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(text.length(), true));
+
+  StringSlicer slicer_begin(text, ellipsis, false, true);
+  EXPECT_EQ(UTF8ToUTF16("rld!"), slicer_begin.CutString(4, false));
+  EXPECT_EQ(kEllipsisUTF16 + UTF8ToUTF16("rld!"),
+            slicer_begin.CutString(4, true));
+
+  StringSlicer slicer_mid(text, ellipsis, true, false);
+  EXPECT_EQ(UTF8ToUTF16("Held!"), slicer_mid.CutString(5, false));
+  EXPECT_EQ(UTF8ToUTF16("Hel") + kEllipsisUTF16 + UTF8ToUTF16("d!"),
+            slicer_mid.CutString(5, true));
+}
+
+TEST(TextEliderTest, StringSlicerSurrogate) {
+  // The below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in
+  // UTF-16 as two code units forming a surrogate pair: 0xD834 0xDD1E.
+  const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
+  base::string16 text(UTF8ToUTF16("abc") + kSurrogate + UTF8ToUTF16("xyz"));
+  base::string16 ellipsis(kEllipsisUTF16);
+  StringSlicer slicer(text, ellipsis, false, false);
+
+  // Cut surrogate on the right. Should round left and exclude the surrogate.
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
+  EXPECT_EQ(UTF8ToUTF16("abc") + kEllipsisUTF16, slicer.CutString(4, true));
+  EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(text.length(), true));
+
+  // Cut surrogate on the left. Should round left and include the surrogate.
+  StringSlicer slicer_begin(text, ellipsis, false, true);
+  EXPECT_EQ(base::string16(kEllipsisUTF16) + kSurrogate + UTF8ToUTF16("xyz"),
+            slicer_begin.CutString(4, true));
+
+  // Cut surrogate in the middle. Should round right and exclude the surrogate.
+  base::string16 short_text(UTF8ToUTF16("abc") + kSurrogate);
+  StringSlicer slicer_mid(short_text, ellipsis, true, false);
+  EXPECT_EQ(UTF8ToUTF16("a") + kEllipsisUTF16, slicer_mid.CutString(2, true));
+
+  // String that starts with a dangling trailing surrogate.
+  base::char16 dangling_trailing_chars[] = {kSurrogate[1], 0};
+  base::string16 dangling_trailing_text(dangling_trailing_chars);
+  StringSlicer slicer_dangling_trailing(dangling_trailing_text, ellipsis, false,
+                                        false);
+  EXPECT_EQ(base::string16(kEllipsisUTF16),
+            slicer_dangling_trailing.CutString(0, true));
+  EXPECT_EQ(dangling_trailing_text + kEllipsisUTF16,
+            slicer_dangling_trailing.CutString(1, true));
+}
+
+TEST(TextEliderTest, StringSlicerCombining) {
+  // The following string contains three combining character sequences (one for
+  // each category of combining mark):
+  // LATIN SMALL LETTER E + COMBINING ACUTE ACCENT + COMBINING CEDILLA
+  // LATIN SMALL LETTER X + COMBINING ENCLOSING KEYCAP
+  // DEVANAGARI LETTER DDA + DEVANAGARI VOWEL SIGN I
+  const base::char16 kText[] = {
+      'e', 0x301, 0x327, ' ', 'x', 0x20E3, ' ', 0x921, 0x93F, 0};
+  base::string16 text(kText);
+  base::string16 ellipsis(kEllipsisUTF16);
+  StringSlicer slicer(text, ellipsis, false, false);
+
+  // Attempt to cut the string for all lengths. When a combining sequence is
+  // cut, it should always round left and exclude the combining sequence.
+  // First sequence:
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(1, true));
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(2, true));
+  EXPECT_EQ(text.substr(0, 3) + kEllipsisUTF16, slicer.CutString(3, true));
+  // Second sequence:
+  EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16, slicer.CutString(4, true));
+  EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16, slicer.CutString(5, true));
+  EXPECT_EQ(text.substr(0, 6) + kEllipsisUTF16, slicer.CutString(6, true));
+  // Third sequence:
+  EXPECT_EQ(text.substr(0, 7) + kEllipsisUTF16, slicer.CutString(7, true));
+  EXPECT_EQ(text.substr(0, 7) + kEllipsisUTF16, slicer.CutString(8, true));
+  EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(9, true));
+
+  // Cut string in the middle, splitting the second sequence in half. Should
+  // round both left and right, excluding the second sequence.
+  StringSlicer slicer_mid(text, ellipsis, true, false);
+  EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16 + text.substr(6),
+            slicer_mid.CutString(9, true));
+
+  // String that starts with a dangling combining mark.
+  base::char16 dangling_mark_chars[] = {text[1], 0};
+  base::string16 dangling_mark_text(dangling_mark_chars);
+  StringSlicer slicer_dangling_mark(dangling_mark_text, ellipsis, false, false);
+  EXPECT_EQ(base::string16(kEllipsisUTF16),
+            slicer_dangling_mark.CutString(0, true));
+  EXPECT_EQ(dangling_mark_text + kEllipsisUTF16,
+            slicer_dangling_mark.CutString(1, true));
+}
+
+TEST(TextEliderTest, StringSlicerCombiningSurrogate) {
+  // The ultimate test: combining sequences comprised of surrogate pairs.
+  // The following string contains a single combining character sequence:
+  // MUSICAL SYMBOL G CLEF (U+1D11E) + MUSICAL SYMBOL COMBINING FLAG-1 (U+1D16E)
+  // Represented as four UTF-16 code units.
+  const base::char16 kText[] = {0xD834, 0xDD1E, 0xD834, 0xDD6E, 0};
+  base::string16 text(kText);
+  base::string16 ellipsis(kEllipsisUTF16);
+  StringSlicer slicer(text, ellipsis, false, false);
+
+  // Attempt to cut the string for all lengths. Should always round left and
+  // exclude the combining sequence.
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(1, true));
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(2, true));
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(3, true));
+  EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(4, true));
+
+  // Cut string in the middle. Should exclude the sequence.
+  StringSlicer slicer_mid(text, ellipsis, true, false);
+  EXPECT_EQ(base::string16(kEllipsisUTF16), slicer_mid.CutString(4, true));
+}
+
 TEST(TextEliderTest, ElideString) {
   struct TestData {
     const char* input;
diff --git a/ui/gfx/win/window_impl.cc b/ui/gfx/win/window_impl.cc
index 94e315c..f01f182 100644
--- a/ui/gfx/win/window_impl.cc
+++ b/ui/gfx/win/window_impl.cc
@@ -41,7 +41,8 @@
 
   // Compares two ClassInfos. Returns true if all members match.
   bool Equals(const ClassInfo& other) const {
-    return (other.style == style && other.icon == icon);
+    return (other.style == style && other.icon == icon &&
+            other.small_icon == small_icon);
   }
 };
 
diff --git a/ui/gl/angle_platform_impl.cc b/ui/gl/angle_platform_impl.cc
index 47f6cef..732f088 100644
--- a/ui/gl/angle_platform_impl.cc
+++ b/ui/gl/angle_platform_impl.cc
@@ -16,6 +16,10 @@
 ANGLEPlatformImpl::~ANGLEPlatformImpl() {
 }
 
+double ANGLEPlatformImpl::currentTime() {
+  return base::Time::Now().ToDoubleT();
+}
+
 double ANGLEPlatformImpl::monotonicallyIncreasingTime() {
   return base::TimeTicks::Now().ToInternalValue() /
          static_cast<double>(base::Time::kMicrosecondsPerSecond);
diff --git a/ui/gl/angle_platform_impl.h b/ui/gl/angle_platform_impl.h
index 92d1397f..4f1aac4b7 100644
--- a/ui/gl/angle_platform_impl.h
+++ b/ui/gl/angle_platform_impl.h
@@ -20,6 +20,7 @@
   ~ANGLEPlatformImpl() override;
 
   // angle::Platform:
+  double currentTime() override;
   double monotonicallyIncreasingTime() override;
   const unsigned char* getTraceCategoryEnabledFlag(
       const char* category_group) override;
diff --git a/ui/gl/gl_context_wgl.h b/ui/gl/gl_context_wgl.h
index d97e568..7a0a437 100644
--- a/ui/gl/gl_context_wgl.h
+++ b/ui/gl/gl_context_wgl.h
@@ -18,18 +18,18 @@
 class GLContextWGL : public GLContextReal {
  public:
   explicit GLContextWGL(GLShareGroup* share_group);
-  virtual ~GLContextWGL();
+  ~GLContextWGL() override;
 
   // Implement GLContext.
-  virtual bool Initialize(
-      GLSurface* compatible_surface, GpuPreference gpu_preference);
-  virtual void Destroy();
-  virtual bool MakeCurrent(GLSurface* surface);
-  virtual void ReleaseCurrent(GLSurface* surface);
-  virtual bool IsCurrent(GLSurface* surface);
-  virtual void* GetHandle();
-  virtual void OnSetSwapInterval(int interval);
-  virtual std::string GetExtensions();
+  bool Initialize(GLSurface* compatible_surface,
+                  GpuPreference gpu_preference) override;
+  void Destroy() override;
+  bool MakeCurrent(GLSurface* surface) override;
+  void ReleaseCurrent(GLSurface* surface) override;
+  bool IsCurrent(GLSurface* surface) override;
+  void* GetHandle() override;
+  void OnSetSwapInterval(int interval) override;
+  std::string GetExtensions() override;
 
  private:
   HGLRC context_;
diff --git a/ui/gl/gl_surface_wgl.h b/ui/gl/gl_surface_wgl.h
index aa32047..b65fad2 100644
--- a/ui/gl/gl_surface_wgl.h
+++ b/ui/gl/gl_surface_wgl.h
@@ -14,10 +14,10 @@
 class GLSurfaceWGL : public GLSurface {
  public:
   GLSurfaceWGL();
-  virtual ~GLSurfaceWGL();
+  ~GLSurfaceWGL() override;
 
   // Implement GLSurface.
-  virtual void* GetDisplay();
+  void* GetDisplay() override;
 
   static bool InitializeOneOff();
   static HDC GetDisplayDC();
@@ -30,15 +30,15 @@
 class NativeViewGLSurfaceWGL : public GLSurfaceWGL {
  public:
   explicit NativeViewGLSurfaceWGL(gfx::AcceleratedWidget window);
-  virtual ~NativeViewGLSurfaceWGL();
+  ~NativeViewGLSurfaceWGL() override;
 
   // Implement GLSurface.
-  virtual bool Initialize();
-  virtual void Destroy();
-  virtual bool IsOffscreen();
-  virtual bool SwapBuffers();
-  virtual gfx::Size GetSize();
-  virtual void* GetHandle();
+  bool Initialize() override;
+  void Destroy() override;
+  bool IsOffscreen() override;
+  bool SwapBuffers() override;
+  gfx::Size GetSize() override;
+  void* GetHandle() override;
 
  private:
   gfx::AcceleratedWidget window_;
@@ -53,15 +53,15 @@
 class PbufferGLSurfaceWGL : public GLSurfaceWGL {
  public:
   explicit PbufferGLSurfaceWGL(const gfx::Size& size);
-  virtual ~PbufferGLSurfaceWGL();
+  ~PbufferGLSurfaceWGL() override;
 
   // Implement GLSurface.
-  virtual bool Initialize();
-  virtual void Destroy();
-  virtual bool IsOffscreen();
-  virtual bool SwapBuffers();
-  virtual gfx::Size GetSize();
-  virtual void* GetHandle();
+  bool Initialize() override;
+  void Destroy() override;
+  bool IsOffscreen() override;
+  bool SwapBuffers() override;
+  gfx::Size GetSize() override;
+  void* GetHandle() override;
 
  private:
   gfx::Size size_;
diff --git a/ui/gl/gl_surface_win.cc b/ui/gl/gl_surface_win.cc
index ed2958e8..8d55009 100644
--- a/ui/gl/gl_surface_win.cc
+++ b/ui/gl/gl_surface_win.cc
@@ -33,15 +33,15 @@
 class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
  public:
   explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window);
-  virtual ~NativeViewGLSurfaceOSMesa();
+  ~NativeViewGLSurfaceOSMesa() override;
 
   // Implement subset of GLSurface.
-  virtual bool Initialize() override;
-  virtual void Destroy() override;
-  virtual bool IsOffscreen() override;
-  virtual bool SwapBuffers() override;
-  virtual bool SupportsPostSubBuffer() override;
-  virtual bool PostSubBuffer(int x, int y, int width, int height) override;
+  bool Initialize() override;
+  void Destroy() override;
+  bool IsOffscreen() override;
+  bool SwapBuffers() override;
+  bool SupportsPostSubBuffer() override;
+  bool PostSubBuffer(int x, int y, int width, int height) override;
 
  private:
   gfx::AcceleratedWidget window_;
@@ -58,9 +58,9 @@
     use_dwm_ = (base::win::GetVersion() >= base::win::VERSION_WIN7);
   }
 
-  virtual ~WinVSyncProvider() {}
+  ~WinVSyncProvider() override {}
 
-  virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) {
+  void GetVSyncParameters(const UpdateVSyncCallback& callback) override {
     TRACE_EVENT0("gpu", "WinVSyncProvider::GetVSyncParameters");
 
     base::TimeTicks timebase;
diff --git a/ui/gl/gl_wgl_api_implementation.h b/ui/gl/gl_wgl_api_implementation.h
index dbef51a..b4da117 100644
--- a/ui/gl/gl_wgl_api_implementation.h
+++ b/ui/gl/gl_wgl_api_implementation.h
@@ -28,7 +28,7 @@
 
  protected:
   WGLApiBase();
-  virtual ~WGLApiBase();
+  ~WGLApiBase() override;
   void InitializeBase(DriverWGL* driver);
 
   DriverWGL* driver_;
@@ -37,7 +37,7 @@
 class GL_EXPORT RealWGLApi : public WGLApiBase {
  public:
   RealWGLApi();
-  virtual ~RealWGLApi();
+  ~RealWGLApi() override;
   void Initialize(DriverWGL* driver);
 };
 
@@ -45,7 +45,7 @@
 class GL_EXPORT TraceWGLApi : public WGLApi {
  public:
   TraceWGLApi(WGLApi* wgl_api) : wgl_api_(wgl_api) { }
-  virtual ~TraceWGLApi();
+  ~TraceWGLApi() 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/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn
index 28f34f1..8f7c8a3a 100644
--- a/ui/keyboard/BUILD.gn
+++ b/ui/keyboard/BUILD.gn
@@ -43,6 +43,7 @@
     "//ui/compositor",
     "//ui/events",
     "//ui/events:dom4_keycode_converter",
+    "//ui/events:events_base",
     "//ui/gfx",
     "//ui/gfx/geometry",
     "//ui/wm",
diff --git a/ui/keyboard/keyboard.gyp b/ui/keyboard/keyboard.gyp
index 65709084..18069fa7 100644
--- a/ui/keyboard/keyboard.gyp
+++ b/ui/keyboard/keyboard.gyp
@@ -59,6 +59,7 @@
         '../compositor/compositor.gyp:compositor',
         '../events/events.gyp:dom4_keycode_converter',
         '../events/events.gyp:events',
+        '../events/events.gyp:events_base',
         '../gfx/gfx.gyp:gfx',
         '../gfx/gfx.gyp:gfx_geometry',
         '../wm/wm.gyp:wm',
diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc
index c234127..7b77b438f 100644
--- a/ui/keyboard/keyboard_util.cc
+++ b/ui/keyboard/keyboard_util.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/basictypes.h"
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
@@ -18,7 +19,11 @@
 #include "ui/base/ime/input_method.h"
 #include "ui/base/ime/text_input_client.h"
 #include "ui/events/event_processor.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/keycodes/dom3/dom_code.h"
+#include "ui/events/keycodes/dom3/dom_key.h"
 #include "ui/events/keycodes/dom4/keycode_converter.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
 #include "ui/keyboard/keyboard_controller.h"
 #include "ui/keyboard/keyboard_controller_proxy.h"
 #include "ui/keyboard/keyboard_switches.h"
@@ -31,7 +36,8 @@
 
 void SendProcessKeyEvent(ui::EventType type,
                          aura::WindowTreeHost* host) {
-  ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::EF_NONE);
+  ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::DomCode::NONE, ui::EF_NONE,
+                     ui::DomKey::PROCESS, 0, ui::EventTimeForNow());
   event.SetTranslated(true);
   ui::EventDispatchDetails details =
       host->event_processor()->OnEventFromSource(&event);
@@ -191,36 +197,54 @@
                 aura::WindowTreeHost* host) {
   if (!host)
     return false;
-  ui::KeyboardCode codex = ui::VKEY_UNKNOWN;
-  ui::KeyboardCode codey = ui::VKEY_UNKNOWN;
+  ui::DomCode domcodex = ui::DomCode::NONE;
+  ui::DomCode domcodey = ui::DomCode::NONE;
   if (swipe_direction & kCursorMoveRight)
-    codex = ui::VKEY_RIGHT;
+    domcodex = ui::DomCode::ARROW_RIGHT;
   else if (swipe_direction & kCursorMoveLeft)
-    codex = ui::VKEY_LEFT;
+    domcodex = ui::DomCode::ARROW_LEFT;
 
   if (swipe_direction & kCursorMoveUp)
-    codey = ui::VKEY_UP;
+    domcodey = ui::DomCode::ARROW_UP;
   else if (swipe_direction & kCursorMoveDown)
-    codey = ui::VKEY_DOWN;
+    domcodey = ui::DomCode::ARROW_DOWN;
 
   // First deal with the x movement.
-  if (codex != ui::VKEY_UNKNOWN) {
-    ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags);
+  if (domcodex != ui::DomCode::NONE) {
+    ui::KeyboardCode codex = ui::VKEY_UNKNOWN;
+    ui::DomKey domkeyx = ui::DomKey::NONE;
+    base::char16 cx;
+    ignore_result(DomCodeToUsLayoutMeaning(domcodex, ui::EF_NONE, &domkeyx,
+                                           &cx, &codex));
+    ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, domcodex,
+                             modifier_flags, domkeyx, cx,
+                             ui::EventTimeForNow());
     ui::EventDispatchDetails details =
         host->event_processor()->OnEventFromSource(&press_event);
     CHECK(!details.dispatcher_destroyed);
-    ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags);
+    ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, domcodex,
+                               modifier_flags, domkeyx, cx,
+                               ui::EventTimeForNow());
     details = host->event_processor()->OnEventFromSource(&release_event);
     CHECK(!details.dispatcher_destroyed);
   }
 
   // Then deal with the y movement.
-  if (codey != ui::VKEY_UNKNOWN) {
-    ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags);
+  if (domcodey != ui::DomCode::NONE) {
+    ui::KeyboardCode codey = ui::VKEY_UNKNOWN;
+    ui::DomKey domkeyy = ui::DomKey::NONE;
+    base::char16 cy;
+    ignore_result(DomCodeToUsLayoutMeaning(domcodey, ui::EF_NONE, &domkeyy,
+                                           &cy, &codey));
+    ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, domcodey,
+                             modifier_flags, domkeyy, cy,
+                             ui::EventTimeForNow());
     ui::EventDispatchDetails details =
         host->event_processor()->OnEventFromSource(&press_event);
     CHECK(!details.dispatcher_destroyed);
-    ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags);
+    ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, domcodey,
+                               modifier_flags, domkeyy, cy,
+                               ui::EventTimeForNow());
     details = host->event_processor()->OnEventFromSource(&release_event);
     CHECK(!details.dispatcher_destroyed);
   }
@@ -274,10 +298,16 @@
       }
     }
 
+    ui::DomCode dom_code = ui::DomCode::NONE;
+    if (!key_name.empty())
+      dom_code = ui::KeycodeConverter::CodeStringToDomCode(key_name.c_str());
+    if (dom_code == ui::DomCode::NONE)
+      dom_code = ui::UsLayoutKeyboardCodeToDomCode(code);
+    CHECK(dom_code != ui::DomCode::NONE);
     ui::KeyEvent event(
         event_type,
         code,
-        ui::KeycodeConverter::CodeStringToDomCode(key_name.c_str()),
+        dom_code,
         modifiers);
     ui::EventDispatchDetails details =
         host->event_processor()->OnEventFromSource(&event);
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js
index 62beda45..958d72fc 100644
--- a/ui/login/display_manager.js
+++ b/ui/login/display_manager.js
@@ -52,6 +52,7 @@
     'app_launch_network_config';
 /** @const */ var ACCELERATOR_NEW_OOBE = 'new_oobe';
 /** @const */ var ACCELERATOR_TOGGLE_WEBVIEW_SIGNIN = 'toggle_webview_signin';
+/** @const */ var ACCELERATOR_TOGGLE_NEW_LOGIN_UI = 'toggle_new_login_ui';
 
 /* Signin UI state constants. Used to control header bar UI. */
 /** @const */ var SIGNIN_UI_STATE = {
@@ -408,6 +409,9 @@
         if (currentStepId == SCREEN_GAIA_SIGNIN ||
             currentStepId == SCREEN_OOBE_ENROLLMENT)
           chrome.send('toggleWebviewSignin');
+      } else if (name == ACCELERATOR_TOGGLE_NEW_LOGIN_UI) {
+        if (currentStepId == SCREEN_OOBE_NETWORK)
+          chrome.send('toggleNewLoginUI');
       } else if (name == ACCELERATOR_TOGGLE_EASY_BOOTSTRAP) {
         if (currentStepId == SCREEN_GAIA_SIGNIN)
           chrome.send('toggleEasyBootstrap');
diff --git a/ui/native_theme/native_theme_aurawin.h b/ui/native_theme/native_theme_aurawin.h
index 7c7e57d..11bb87d2 100644
--- a/ui/native_theme/native_theme_aurawin.h
+++ b/ui/native_theme/native_theme_aurawin.h
@@ -18,17 +18,17 @@
 
  private:
   NativeThemeAuraWin();
-  virtual ~NativeThemeAuraWin();
+  ~NativeThemeAuraWin() override;
 
   // Overridden from NativeThemeBase:
-  virtual gfx::Size GetPartSize(Part part,
-                                State state,
-                                const ExtraParams& extra) const override;
-  virtual void Paint(SkCanvas* canvas,
-                     Part part,
-                     State state,
-                     const gfx::Rect& rect,
-                     const ExtraParams& extra) const override;
+  gfx::Size GetPartSize(Part part,
+                        State state,
+                        const ExtraParams& extra) const override;
+  void Paint(SkCanvas* canvas,
+             Part part,
+             State state,
+             const gfx::Rect& rect,
+             const ExtraParams& extra) const override;
   DISALLOW_COPY_AND_ASSIGN(NativeThemeAuraWin);
 };
 
diff --git a/ui/native_theme/native_theme_win.h b/ui/native_theme/native_theme_win.h
index 24b718f..46b62ae 100644
--- a/ui/native_theme/native_theme_win.h
+++ b/ui/native_theme/native_theme_win.h
@@ -104,22 +104,22 @@
                          bool draw_edges) const;
 
   // NativeTheme implementation:
-  virtual gfx::Size GetPartSize(Part part,
-                                State state,
-                                const ExtraParams& extra) const override;
-  virtual void Paint(SkCanvas* canvas,
-                     Part part,
-                     State state,
-                     const gfx::Rect& rect,
-                     const ExtraParams& extra) const override;
-  virtual SkColor GetSystemColor(ColorId color_id) const override;
+  gfx::Size GetPartSize(Part part,
+                        State state,
+                        const ExtraParams& extra) const override;
+  void Paint(SkCanvas* canvas,
+             Part part,
+             State state,
+             const gfx::Rect& rect,
+             const ExtraParams& extra) const override;
+  SkColor GetSystemColor(ColorId color_id) const override;
 
  private:
   NativeThemeWin();
-  ~NativeThemeWin();
+  ~NativeThemeWin() override;
 
   // gfx::SysColorChangeListener implementation:
-  virtual void OnSysColorChange() override;
+  void OnSysColorChange() override;
 
   // Update the locally cached set of system colors.
   void UpdateSystemColors();
diff --git a/ui/ozone/common/native_display_delegate_ozone.cc b/ui/ozone/common/native_display_delegate_ozone.cc
index 7f7e15d..0aa8e33 100644
--- a/ui/ozone/common/native_display_delegate_ozone.cc
+++ b/ui/ozone/common/native_display_delegate_ozone.cc
@@ -76,18 +76,33 @@
   NOTIMPLEMENTED();
 }
 
-bool NativeDisplayDelegateOzone::GetHDCPState(const ui::DisplaySnapshot& output,
-                                              ui::HDCPState* state) {
+bool NativeDisplayDelegateOzone::GetHDCPState(const DisplaySnapshot& output,
+                                              HDCPState* state) {
   NOTIMPLEMENTED();
   return false;
 }
 
-bool NativeDisplayDelegateOzone::SetHDCPState(const ui::DisplaySnapshot& output,
-                                              ui::HDCPState state) {
+bool NativeDisplayDelegateOzone::SetHDCPState(const DisplaySnapshot& output,
+                                              HDCPState state) {
   NOTIMPLEMENTED();
   return false;
 }
 
+void NativeDisplayDelegateOzone::GetHDCPState(
+    const ui::DisplaySnapshot& output,
+    const GetHDCPStateCallback& callback) {
+  NOTIMPLEMENTED();
+  callback.Run(false, HDCP_STATE_UNDESIRED);
+}
+
+void NativeDisplayDelegateOzone::SetHDCPState(
+    const ui::DisplaySnapshot& output,
+    ui::HDCPState state,
+    const SetHDCPStateCallback& callback) {
+  NOTIMPLEMENTED();
+  callback.Run(false);
+}
+
 std::vector<ui::ColorCalibrationProfile>
 NativeDisplayDelegateOzone::GetAvailableColorCalibrationProfiles(
     const ui::DisplaySnapshot& output) {
diff --git a/ui/ozone/common/native_display_delegate_ozone.h b/ui/ozone/common/native_display_delegate_ozone.h
index 3801834..a9e17dd 100644
--- a/ui/ozone/common/native_display_delegate_ozone.h
+++ b/ui/ozone/common/native_display_delegate_ozone.h
@@ -33,10 +33,13 @@
                  const gfx::Point& origin,
                  const ConfigureCallback& callback) override;
   void CreateFrameBuffer(const gfx::Size& size) override;
-  bool GetHDCPState(const ui::DisplaySnapshot& output,
-                    ui::HDCPState* state) override;
-  bool SetHDCPState(const ui::DisplaySnapshot& output,
-                    ui::HDCPState state) override;
+  bool GetHDCPState(const DisplaySnapshot& output, HDCPState* state) override;
+  bool SetHDCPState(const DisplaySnapshot& output, HDCPState state) override;
+  void GetHDCPState(const ui::DisplaySnapshot& output,
+                    const GetHDCPStateCallback& callback) override;
+  void SetHDCPState(const ui::DisplaySnapshot& output,
+                    ui::HDCPState state,
+                    const SetHDCPStateCallback& callback) override;
   std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
       const ui::DisplaySnapshot& output) override;
   bool SetColorCalibrationProfile(
diff --git a/ui/ozone/platform/drm/gpu/drm_buffer.cc b/ui/ozone/platform/drm/gpu/drm_buffer.cc
index bdf5727..e9ef7c4 100644
--- a/ui/ozone/platform/drm/gpu/drm_buffer.cc
+++ b/ui/ozone/platform/drm/gpu/drm_buffer.cc
@@ -35,29 +35,38 @@
 }  // namespace
 
 DrmBuffer::DrmBuffer(const scoped_refptr<DrmDevice>& drm)
-    : drm_(drm), handle_(0), framebuffer_(0) {
+    : drm_(drm),
+      stride_(0),
+      handle_(0),
+      mmap_base_(0),
+      mmap_size_(0),
+      framebuffer_(0) {
 }
 
 DrmBuffer::~DrmBuffer() {
-  if (!surface_)
-    return;
+  surface_.clear();
 
-  if (framebuffer_)
-    drm_->RemoveFramebuffer(framebuffer_);
+  if (framebuffer_ && !drm_->RemoveFramebuffer(framebuffer_))
+    PLOG(ERROR) << "DrmBuffer: RemoveFramebuffer: fb " << framebuffer_;
 
-  SkImageInfo info;
-  void* pixels = const_cast<void*>(surface_->peekPixels(&info, NULL));
-  if (!pixels)
-    return;
+  if (mmap_base_ && !drm_->UnmapDumbBuffer(mmap_base_, mmap_size_))
+    PLOG(ERROR) << "DrmBuffer: UnmapDumbBuffer: handle " << handle_;
 
-  drm_->DestroyDumbBuffer(info, handle_, stride_, pixels);
+  if (handle_ && !drm_->DestroyDumbBuffer(handle_))
+    PLOG(ERROR) << "DrmBuffer: DestroyDumbBuffer: handle " << handle_;
 }
 
 bool DrmBuffer::Initialize(const SkImageInfo& info,
                            bool should_register_framebuffer) {
-  void* pixels = NULL;
-  if (!drm_->CreateDumbBuffer(info, &handle_, &stride_, &pixels)) {
-    VLOG(2) << "Cannot create drm dumb buffer";
+  if (!drm_->CreateDumbBuffer(info, &handle_, &stride_)) {
+    PLOG(ERROR) << "DrmBuffer: CreateDumbBuffer: width " << info.width()
+                << " height " << info.height();
+    return false;
+  }
+
+  mmap_size_ = info.getSafeSize(stride_);
+  if (!drm_->MapDumbBuffer(handle_, mmap_size_, &mmap_base_)) {
+    PLOG(ERROR) << "DrmBuffer: MapDumbBuffer: handle " << handle_;
     return false;
   }
 
@@ -65,13 +74,14 @@
       !drm_->AddFramebuffer(
           info.width(), info.height(), GetColorDepth(info.colorType()),
           info.bytesPerPixel() << 3, stride_, handle_, &framebuffer_)) {
-    VPLOG(2) << "Failed to register framebuffer";
+    PLOG(ERROR) << "DrmBuffer: AddFramebuffer: handle " << handle_;
     return false;
   }
 
-  surface_ = skia::AdoptRef(SkSurface::NewRasterDirect(info, pixels, stride_));
+  surface_ =
+      skia::AdoptRef(SkSurface::NewRasterDirect(info, mmap_base_, stride_));
   if (!surface_) {
-    VLOG(2) << "Cannot install Skia pixels for drm buffer";
+    LOG(ERROR) << "DrmBuffer: Failed to create SkSurface: handle " << handle_;
     return false;
   }
 
diff --git a/ui/ozone/platform/drm/gpu/drm_buffer.h b/ui/ozone/platform/drm/gpu/drm_buffer.h
index 18ad9af..6dcd02b 100644
--- a/ui/ozone/platform/drm/gpu/drm_buffer.h
+++ b/ui/ozone/platform/drm/gpu/drm_buffer.h
@@ -40,19 +40,25 @@
 
   scoped_refptr<DrmDevice> drm_;
 
-  // Wrapper around the native pixel memory.
-  skia::RefPtr<SkSurface> surface_;
-
   // Length of a row of pixels.
   uint32_t stride_;
 
   // Buffer handle used by the DRM allocator.
   uint32_t handle_;
 
+  // Base address for memory mapping.
+  void* mmap_base_;
+
+  // Size for memory mapping.
+  size_t mmap_size_;
+
   // Buffer ID used by the DRM modesettings API. This is set when the buffer is
   // registered with the CRTC.
   uint32_t framebuffer_;
 
+  // Wrapper around the native pixel memory.
+  skia::RefPtr<SkSurface> surface_;
+
   DISALLOW_COPY_AND_ASSIGN(DrmBuffer);
 };
 
diff --git a/ui/ozone/platform/drm/gpu/drm_console_buffer.cc b/ui/ozone/platform/drm/gpu/drm_console_buffer.cc
index 2244fc2..871c2fa0 100644
--- a/ui/ozone/platform/drm/gpu/drm_console_buffer.cc
+++ b/ui/ozone/platform/drm/gpu/drm_console_buffer.cc
@@ -9,7 +9,6 @@
 
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "ui/ozone/platform/drm/gpu/drm_device.h"
-#include "ui/ozone/platform/drm/gpu/drm_util.h"
 #include "ui/ozone/platform/drm/gpu/scoped_drm_types.h"
 
 namespace ui {
@@ -44,7 +43,7 @@
 
   mmap_size_ = info.getSafeSize(stride_);
 
-  if (!MapDumbBuffer(drm_->get_fd(), fb->handle, mmap_size_, &mmap_base_)) {
+  if (!drm_->MapDumbBuffer(fb->handle, mmap_size_, &mmap_base_)) {
     mmap_base_ = NULL;
     return false;
   }
diff --git a/ui/ozone/platform/drm/gpu/drm_device.cc b/ui/ozone/platform/drm/gpu/drm_device.cc
index b547b08..7b03b43 100644
--- a/ui/ozone/platform/drm/gpu/drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/drm_device.cc
@@ -66,11 +66,11 @@
   return true;
 }
 
-void DrmDestroyDumbBuffer(int fd, uint32_t handle) {
+bool DrmDestroyDumbBuffer(int fd, uint32_t handle) {
   struct drm_mode_destroy_dumb destroy_request;
   memset(&destroy_request, 0, sizeof(destroy_request));
   destroy_request.handle = handle;
-  drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
+  return !drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
 }
 
 void HandlePageFlipEventOnIO(int fd,
@@ -451,31 +451,41 @@
 
 bool DrmDevice::CreateDumbBuffer(const SkImageInfo& info,
                                  uint32_t* handle,
-                                 uint32_t* stride,
-                                 void** pixels) {
+                                 uint32_t* stride) {
   DCHECK(file_.IsValid());
 
   TRACE_EVENT0("drm", "DrmDevice::CreateDumbBuffer");
-  if (!DrmCreateDumbBuffer(file_.GetPlatformFile(), info, handle, stride))
-    return false;
+  return DrmCreateDumbBuffer(file_.GetPlatformFile(), info, handle, stride);
+}
 
-  if (!MapDumbBuffer(file_.GetPlatformFile(), *handle,
-                     info.getSafeSize(*stride), pixels)) {
-    DrmDestroyDumbBuffer(file_.GetPlatformFile(), *handle);
+bool DrmDevice::DestroyDumbBuffer(uint32_t handle) {
+  DCHECK(file_.IsValid());
+  TRACE_EVENT1("drm", "DrmDevice::DestroyDumbBuffer", "handle", handle);
+  return DrmDestroyDumbBuffer(file_.GetPlatformFile(), handle);
+}
+
+bool DrmDevice::MapDumbBuffer(uint32_t handle, size_t size, void** pixels) {
+  struct drm_mode_map_dumb map_request;
+  memset(&map_request, 0, sizeof(map_request));
+  map_request.handle = handle;
+  if (drmIoctl(file_.GetPlatformFile(), DRM_IOCTL_MODE_MAP_DUMB,
+               &map_request)) {
+    PLOG(ERROR) << "Cannot prepare dumb buffer for mapping";
+    return false;
+  }
+
+  *pixels = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+                 file_.GetPlatformFile(), map_request.offset);
+  if (*pixels == MAP_FAILED) {
+    PLOG(ERROR) << "Cannot mmap dumb buffer";
     return false;
   }
 
   return true;
 }
 
-void DrmDevice::DestroyDumbBuffer(const SkImageInfo& info,
-                                  uint32_t handle,
-                                  uint32_t stride,
-                                  void* pixels) {
-  DCHECK(file_.IsValid());
-  TRACE_EVENT1("drm", "DrmDevice::DestroyDumbBuffer", "handle", handle);
-  munmap(pixels, info.getSafeSize(stride));
-  DrmDestroyDumbBuffer(file_.GetPlatformFile(), handle);
+bool DrmDevice::UnmapDumbBuffer(void* pixels, size_t size) {
+  return !munmap(pixels, size);
 }
 
 bool DrmDevice::CloseBufferHandle(uint32_t handle) {
diff --git a/ui/ozone/platform/drm/gpu/drm_device.h b/ui/ozone/platform/drm/gpu/drm_device.h
index 67ffcffa..6fc2e49 100644
--- a/ui/ozone/platform/drm/gpu/drm_device.h
+++ b/ui/ozone/platform/drm/gpu/drm_device.h
@@ -146,13 +146,13 @@
 
   virtual bool CreateDumbBuffer(const SkImageInfo& info,
                                 uint32_t* handle,
-                                uint32_t* stride,
-                                void** pixels);
+                                uint32_t* stride);
 
-  virtual void DestroyDumbBuffer(const SkImageInfo& info,
-                                 uint32_t handle,
-                                 uint32_t stride,
-                                 void* pixels);
+  virtual bool DestroyDumbBuffer(uint32_t handle);
+
+  virtual bool MapDumbBuffer(uint32_t handle, size_t size, void** pixels);
+
+  virtual bool UnmapDumbBuffer(void* pixels, size_t size);
 
   virtual bool CloseBufferHandle(uint32_t handle);
 
diff --git a/ui/ozone/platform/drm/gpu/drm_util.cc b/ui/ozone/platform/drm/gpu/drm_util.cc
index 517a58c..67f3c94 100644
--- a/ui/ozone/platform/drm/gpu/drm_util.cc
+++ b/ui/ozone/platform/drm/gpu/drm_util.cc
@@ -108,25 +108,6 @@
          lhs.flags == rhs.flags && strcmp(lhs.name, rhs.name) == 0;
 }
 
-bool MapDumbBuffer(int fd, uint32_t handle, uint32_t size, void** pixels) {
-  struct drm_mode_map_dumb map_request;
-  memset(&map_request, 0, sizeof(map_request));
-  map_request.handle = handle;
-  if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_request)) {
-    VPLOG(2) << "Cannot prepare dumb buffer for mapping";
-    return false;
-  }
-
-  *pixels =
-      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_request.offset);
-  if (*pixels == MAP_FAILED) {
-    VPLOG(2) << "Cannot mmap dumb buffer";
-    return false;
-  }
-
-  return true;
-}
-
 void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DrmDevice>& drm,
                                          ScreenManager* screen_manager) {
   VLOG(2) << "Forcing initialization of primary display.";
diff --git a/ui/ozone/platform/drm/gpu/drm_util.h b/ui/ozone/platform/drm/gpu/drm_util.h
index a15a60f7..baf8893 100644
--- a/ui/ozone/platform/drm/gpu/drm_util.h
+++ b/ui/ozone/platform/drm/gpu/drm_util.h
@@ -43,9 +43,6 @@
 
 bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs);
 
-// Memory maps a DRM buffer.
-bool MapDumbBuffer(int fd, uint32_t handle, uint32_t size, void** pixels);
-
 void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DrmDevice>& drm,
                                          ScreenManager* screen_manager);
 
diff --git a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
index ec84b0a..0a2a4c2 100644
--- a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
+++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
@@ -196,6 +196,21 @@
   return false;
 }
 
+void DrmNativeDisplayDelegate::GetHDCPState(
+    const ui::DisplaySnapshot& output,
+    const GetHDCPStateCallback& callback) {
+  NOTIMPLEMENTED();
+  callback.Run(false, HDCP_STATE_UNDESIRED);
+}
+
+void DrmNativeDisplayDelegate::SetHDCPState(
+    const ui::DisplaySnapshot& output,
+    ui::HDCPState state,
+    const SetHDCPStateCallback& callback) {
+  NOTIMPLEMENTED();
+  callback.Run(false);
+}
+
 std::vector<ColorCalibrationProfile>
 DrmNativeDisplayDelegate::GetAvailableColorCalibrationProfiles(
     const DisplaySnapshot& output) {
diff --git a/ui/ozone/platform/drm/host/drm_native_display_delegate.h b/ui/ozone/platform/drm/host/drm_native_display_delegate.h
index 42802a8..986f28a 100644
--- a/ui/ozone/platform/drm/host/drm_native_display_delegate.h
+++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.h
@@ -52,6 +52,11 @@
   void CreateFrameBuffer(const gfx::Size& size) override;
   bool GetHDCPState(const DisplaySnapshot& output, HDCPState* state) override;
   bool SetHDCPState(const DisplaySnapshot& output, HDCPState state) override;
+  void GetHDCPState(const DisplaySnapshot& output,
+                    const GetHDCPStateCallback& callback) override;
+  void SetHDCPState(const DisplaySnapshot& output,
+                    HDCPState state,
+                    const SetHDCPStateCallback& callback) override;
   std::vector<ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
       const DisplaySnapshot& output) override;
   bool SetColorCalibrationProfile(const DisplaySnapshot& output,
diff --git a/ui/ozone/platform/drm/test/mock_drm_device.cc b/ui/ozone/platform/drm/test/mock_drm_device.cc
index eb11623..3a822dc 100644
--- a/ui/ozone/platform/drm/test/mock_drm_device.cc
+++ b/ui/ozone/platform/drm/test/mock_drm_device.cc
@@ -196,27 +196,38 @@
 
 bool MockDrmDevice::CreateDumbBuffer(const SkImageInfo& info,
                                      uint32_t* handle,
-                                     uint32_t* stride,
-                                     void** pixels) {
-  allocate_buffer_count_++;
+                                     uint32_t* stride) {
   if (!create_dumb_buffer_expectation_)
     return false;
 
-  *handle = allocate_buffer_count_;
+  *handle = allocate_buffer_count_++;
   *stride = info.minRowBytes();
-  *pixels = new char[info.getSafeSize(*stride)];
+  void* pixels = new char[info.getSafeSize(*stride)];
   buffers_.push_back(
-      skia::AdoptRef(SkSurface::NewRasterDirect(info, *pixels, *stride)));
-  buffers_.back()->getCanvas()->clear(SK_ColorBLACK);
+      skia::AdoptRef(SkSurface::NewRasterDirect(info, pixels, *stride)));
+  buffers_[*handle]->getCanvas()->clear(SK_ColorBLACK);
 
   return true;
 }
 
-void MockDrmDevice::DestroyDumbBuffer(const SkImageInfo& info,
-                                      uint32_t handle,
-                                      uint32_t stride,
-                                      void* pixels) {
-  delete[] static_cast<char*>(pixels);
+bool MockDrmDevice::DestroyDumbBuffer(uint32_t handle) {
+  if (handle >= buffers_.size() || !buffers_[handle])
+    return false;
+
+  buffers_[handle].clear();
+  return true;
+}
+
+bool MockDrmDevice::MapDumbBuffer(uint32_t handle, size_t size, void** pixels) {
+  if (handle >= buffers_.size() || !buffers_[handle])
+    return false;
+
+  *pixels = const_cast<void*>(buffers_[handle]->peekPixels(nullptr, nullptr));
+  return true;
+}
+
+bool MockDrmDevice::UnmapDumbBuffer(void* pixels, size_t size) {
+  return true;
 }
 
 bool MockDrmDevice::CloseBufferHandle(uint32_t handle) {
diff --git a/ui/ozone/platform/drm/test/mock_drm_device.h b/ui/ozone/platform/drm/test/mock_drm_device.h
index 41d5ba3..5632b6e2 100644
--- a/ui/ozone/platform/drm/test/mock_drm_device.h
+++ b/ui/ozone/platform/drm/test/mock_drm_device.h
@@ -100,13 +100,10 @@
   bool MoveCursor(uint32_t crtc_id, const gfx::Point& point) override;
   bool CreateDumbBuffer(const SkImageInfo& info,
                         uint32_t* handle,
-                        uint32_t* stride,
-                        void** pixels) override;
-  void DestroyDumbBuffer(const SkImageInfo& info,
-                         uint32_t handle,
-                         uint32_t stride,
-                         void* pixels) override;
-
+                        uint32_t* stride) override;
+  bool DestroyDumbBuffer(uint32_t handle) override;
+  bool MapDumbBuffer(uint32_t handle, size_t size, void** pixels) override;
+  bool UnmapDumbBuffer(void* pixels, size_t size) override;
   bool CloseBufferHandle(uint32_t handle) override;
   bool CommitProperties(drmModePropertySet* properties,
                         uint32_t flags,
diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h
index 12aa7ad..8fb8adc 100644
--- a/ui/platform_window/win/win_window.h
+++ b/ui/platform_window/win/win_window.h
@@ -16,26 +16,26 @@
                                     public gfx::WindowImpl {
  public:
   WinWindow(PlatformWindowDelegate* delegate, const gfx::Rect& bounds);
-  virtual ~WinWindow();
+  ~WinWindow() override;
 
  private:
   void Destroy();
 
   // PlatformWindow:
-  virtual void Show() override;
-  virtual void Hide() override;
-  virtual void Close() override;
-  virtual void SetBounds(const gfx::Rect& bounds) override;
-  virtual gfx::Rect GetBounds() override;
-  virtual void SetCapture() override;
-  virtual void ReleaseCapture() override;
-  virtual void ToggleFullscreen() override;
-  virtual void Maximize() override;
-  virtual void Minimize() override;
-  virtual void Restore() override;
-  virtual void SetCursor(PlatformCursor cursor) override;
-  virtual void MoveCursorTo(const gfx::Point& location) override;
-  virtual void ConfineCursorToBounds(const gfx::Rect& bounds) override;
+  void Show() override;
+  void Hide() override;
+  void Close() override;
+  void SetBounds(const gfx::Rect& bounds) override;
+  gfx::Rect GetBounds() override;
+  void SetCapture() override;
+  void ReleaseCapture() override;
+  void ToggleFullscreen() override;
+  void Maximize() override;
+  void Minimize() override;
+  void Restore() override;
+  void SetCursor(PlatformCursor cursor) override;
+  void MoveCursorTo(const gfx::Point& location) override;
+  void ConfineCursorToBounds(const gfx::Rect& bounds) override;
 
   CR_BEGIN_MSG_MAP_EX(WinWindow)
     CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
diff --git a/ui/views/accessibility/native_view_accessibility_win.h b/ui/views/accessibility/native_view_accessibility_win.h
index 087d50e7..dadbcba7 100644
--- a/ui/views/accessibility/native_view_accessibility_win.h
+++ b/ui/views/accessibility/native_view_accessibility_win.h
@@ -13,7 +13,7 @@
 class NativeViewAccessibilityWin : public NativeViewAccessibility {
  public:
   NativeViewAccessibilityWin(View* view);
-  virtual ~NativeViewAccessibilityWin();
+  ~NativeViewAccessibilityWin() override;
 
   // NativeViewAccessibility.
   gfx::NativeViewAccessible GetParent() override;
diff --git a/ui/views/accessibility/native_view_accessibility_win_unittest.cc b/ui/views/accessibility/native_view_accessibility_win_unittest.cc
index 2eba9cb..3b955b2 100644
--- a/ui/views/accessibility/native_view_accessibility_win_unittest.cc
+++ b/ui/views/accessibility/native_view_accessibility_win_unittest.cc
@@ -22,7 +22,7 @@
 class NativeViewAcccessibilityWinTest : public ViewsTestBase {
  public:
   NativeViewAcccessibilityWinTest() {}
-  virtual ~NativeViewAcccessibilityWinTest() {}
+  ~NativeViewAcccessibilityWinTest() override {}
 
  protected:
   void GetIAccessible2InterfaceForView(View* view, IAccessible2_2** result) {
diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher_win.h b/ui/views/controls/menu/menu_message_pump_dispatcher_win.h
index 9f84171b..afc54fe 100644
--- a/ui/views/controls/menu/menu_message_pump_dispatcher_win.h
+++ b/ui/views/controls/menu/menu_message_pump_dispatcher_win.h
@@ -19,11 +19,11 @@
 class MenuMessagePumpDispatcher : public base::MessagePumpDispatcher {
  public:
   explicit MenuMessagePumpDispatcher(MenuController* menu_controller);
-  virtual ~MenuMessagePumpDispatcher();
+  ~MenuMessagePumpDispatcher() override;
 
  private:
   // base::MessagePumpDispatcher:
-  virtual uint32_t Dispatch(const base::NativeEvent& event) override;
+  uint32_t Dispatch(const base::NativeEvent& event) override;
 
   MenuController* menu_controller_;
 
diff --git a/ui/views/controls/menu/native_menu_win.h b/ui/views/controls/menu/native_menu_win.h
index 39dc37e20..7d4dea9a 100644
--- a/ui/views/controls/menu/native_menu_win.h
+++ b/ui/views/controls/menu/native_menu_win.h
@@ -30,18 +30,18 @@
   // is non-NULL, the NativeMenuWin wraps the system menu for that window.
   // The caller owns the model and the delegate.
   NativeMenuWin(ui::MenuModel* model, HWND system_menu_for);
-  virtual ~NativeMenuWin();
+  ~NativeMenuWin() override;
 
   // Overridden from MenuWrapper:
-  virtual void RunMenuAt(const gfx::Point& point, int alignment) override;
-  virtual void CancelMenu() override;
-  virtual void Rebuild(MenuInsertionDelegateWin* delegate) override;
-  virtual void UpdateStates() override;
-  virtual HMENU GetNativeMenu() const override;
-  virtual MenuAction GetMenuAction() const override;
-  virtual void AddMenuListener(MenuListener* listener) override;
-  virtual void RemoveMenuListener(MenuListener* listener) override;
-  virtual void SetMinimumWidth(int width) override;
+  void RunMenuAt(const gfx::Point& point, int alignment) override;
+  void CancelMenu() override;
+  void Rebuild(MenuInsertionDelegateWin* delegate) override;
+  void UpdateStates() override;
+  HMENU GetNativeMenu() const override;
+  MenuAction GetMenuAction() const override;
+  void AddMenuListener(MenuListener* listener) override;
+  void RemoveMenuListener(MenuListener* listener) override;
+  void SetMinimumWidth(int width) override;
 
  private:
   // IMPORTANT: Note about indices.
diff --git a/ui/views/controls/throbber.cc b/ui/views/controls/throbber.cc
index d1d5c1d..30cfb3b3 100644
--- a/ui/views/controls/throbber.cc
+++ b/ui/views/controls/throbber.cc
@@ -111,7 +111,7 @@
 void SmoothedThrobber::Start() {
   stop_timer_.Stop();
 
-  if (!running_ && !start_timer_.IsRunning()) {
+  if (!running() && !start_timer_.IsRunning()) {
     start_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(start_delay_ms_),
                        this, &SmoothedThrobber::StartDelayOver);
   }
@@ -122,7 +122,7 @@
 }
 
 void SmoothedThrobber::Stop() {
-  if (!running_)
+  if (!running())
     start_timer_.Stop();
 
   stop_timer_.Stop();
@@ -134,35 +134,87 @@
   Throbber::Stop();
 }
 
-// Checkmark throbber ---------------------------------------------------------
+// Material throbber -----------------------------------------------------------
 
-CheckmarkThrobber::CheckmarkThrobber()
-    : Throbber(kFrameTimeMs, false),
-      checked_(false),
-      checkmark_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-          IDR_CHECKMARK).ToImageSkia()) {
+// The length of a frame in milliseconds.
+// TODO(estade): remove the +10 when the -10 is removed from Throbber::Start().
+static const int kMaterialThrobberFrameTimeMs = 30 + 10;
+
+MaterialThrobber::MaterialThrobber() :
+    Throbber(kMaterialThrobberFrameTimeMs, false),
+    preferred_diameter_(0),
+    checked_(false),
+    checkmark_(nullptr) {
 }
 
-void CheckmarkThrobber::SetChecked(bool checked) {
-  bool changed = checked != checked_;
-  if (changed) {
-    checked_ = checked;
-    SchedulePaint();
-  }
+MaterialThrobber::~MaterialThrobber() {
 }
 
-void CheckmarkThrobber::OnPaint(gfx::Canvas* canvas) {
-  if (running_) {
-    // Let the throbber throb...
-    Throbber::OnPaint(canvas);
+void MaterialThrobber::SetChecked(bool checked) {
+  if (checked == checked_)
+    return;
+
+  checked_ = checked;
+  SchedulePaint();
+}
+
+gfx::Size MaterialThrobber::GetPreferredSize() const {
+  if (preferred_diameter_ == 0)
+    return Throbber::GetPreferredSize();
+
+  return gfx::Size(preferred_diameter_, preferred_diameter_);
+}
+
+int MaterialThrobber::GetHeightForWidth(int w) const {
+  return w;
+}
+
+void MaterialThrobber::OnPaint(gfx::Canvas* canvas) {
+  if (!running()) {
+    if (checked_) {
+      if (!checkmark_) {
+        checkmark_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+            IDR_CHECKMARK).ToImageSkia();
+      }
+
+      int checkmark_x = (width() - checkmark_->width()) / 2;
+      int checkmark_y = (height() - checkmark_->height()) / 2;
+      canvas->DrawImageInt(*checkmark_, checkmark_x, checkmark_y);
+    }
     return;
   }
-  // Otherwise we paint our tick mark or nothing depending on our state.
-  if (checked_) {
-    int checkmark_x = (width() - checkmark_->width()) / 2;
-    int checkmark_y = (height() - checkmark_->height()) / 2;
-    canvas->DrawImageInt(*checkmark_, checkmark_x, checkmark_y);
-  }
+
+  gfx::Rect bounds = GetContentsBounds();
+  // Inset by half the stroke width to make sure the whole arc is inside
+  // the visible rect.
+  SkScalar stroke_width = SkIntToScalar(bounds.width()) / 10.0;
+  gfx::Rect oval = bounds;
+  int inset = SkScalarCeilToInt(stroke_width / 2.0);
+  oval.Inset(inset, inset);
+
+  // Calculate start and end points. The angles are counter-clockwise because
+  // the throbber spins counter-clockwise. The finish angle starts at 12 o'clock
+  // (90 degrees) and rotates steadily. The start angle trails 180 degrees
+  // behind, except for the first half revolution, when it stays at 12 o'clock.
+  base::TimeDelta revolution_time = base::TimeDelta::FromMilliseconds(1320);
+  base::TimeDelta elapsed_time = base::Time::Now() - start_time();
+  int64_t twelve_oclock = 90;
+  int64_t finish_angle = twelve_oclock + 360 * elapsed_time / revolution_time;
+  int64_t start_angle = std::max(finish_angle - 180, twelve_oclock);
+
+  SkPath path;
+  // Negate the angles to convert to the clockwise numbers Skia expects.
+  path.arcTo(gfx::RectToSkRect(oval), -start_angle,
+             -(finish_angle - start_angle), true);
+
+  SkPaint paint;
+  // TODO(estade): find a place for this color.
+  paint.setColor(SkColorSetRGB(0x42, 0x85, 0xF4));
+  paint.setStrokeCap(SkPaint::kRound_Cap);
+  paint.setStrokeWidth(stroke_width);
+  paint.setStyle(SkPaint::kStroke_Style);
+  paint.setAntiAlias(true);
+  canvas->DrawPath(path, paint);
 }
 
 }  // namespace views
diff --git a/ui/views/controls/throbber.h b/ui/views/controls/throbber.h
index 0ee428d..73eedb9 100644
--- a/ui/views/controls/throbber.h
+++ b/ui/views/controls/throbber.h
@@ -41,12 +41,15 @@
   void OnPaint(gfx::Canvas* canvas) override;
 
  protected:
+  bool running() const { return running_; }
+  base::Time start_time() const { return start_time_; }
+
   // Specifies whether the throbber is currently animating or not
-  bool running_;
 
  private:
   void Run();
 
+  bool running_;
   bool paint_while_stopped_;
   int frame_count_;  // How many frames we have.
   base::Time start_time_;  // Time when Start was called.
@@ -94,32 +97,37 @@
   DISALLOW_COPY_AND_ASSIGN(SmoothedThrobber);
 };
 
-// A CheckmarkThrobber is a special variant of throbber that has three states:
-//   1. not yet completed (which paints nothing)
-//   2. working (which paints the throbber animation)
-//   3. completed (which paints a checkmark)
-//
-class VIEWS_EXPORT CheckmarkThrobber : public Throbber {
+// A throbber that follows material design guidelines. This is a specialization
+// of Throbber for now, but should probably be folded into/replace Throbber
+// eventually.
+class VIEWS_EXPORT MaterialThrobber : public Throbber {
  public:
-  CheckmarkThrobber();
+  MaterialThrobber();
+  ~MaterialThrobber() override;
 
-  // If checked is true, the throbber stops spinning and displays a checkmark.
-  // If checked is false, the throbber stops spinning and displays nothing.
+  // Stop spinning and, if checked is true, display a checkmark.
   void SetChecked(bool checked);
 
-  // Overridden from Throbber:
+  void set_preferred_diameter(int diameter) { preferred_diameter_ = diameter; }
+
+  // View implementation.
+  gfx::Size GetPreferredSize() const override;
+  int GetHeightForWidth(int w) const override;
   void OnPaint(gfx::Canvas* canvas) override;
 
  private:
-  static const int kFrameTimeMs = 30;
+  // The preferred width and height for this view. Zero indicates the size is
+  // set by the parent class (i.e. matches the size of the pre-material
+  // sprites).
+  int preferred_diameter_;
 
   // Whether or not we should display a checkmark.
   bool checked_;
 
-  // The checkmark image.
+  // The checkmark image. Will be null until it's used (if ever).
   const gfx::ImageSkia* checkmark_;
 
-  DISALLOW_COPY_AND_ASSIGN(CheckmarkThrobber);
+  DISALLOW_COPY_AND_ASSIGN(MaterialThrobber);
 };
 
 }  // namespace views
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc
index 8fe27bf0..4a5a114 100644
--- a/ui/views/controls/webview/web_dialog_view.cc
+++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -247,6 +247,7 @@
 
 void WebDialogView::OnCloseContents(WebContents* source,
                                     bool* out_close_dialog) {
+  DCHECK(out_close_dialog);
   if (delegate_)
     delegate_->OnCloseContents(source, out_close_dialog);
 }
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
index c46e242..4cc0e8a8 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
@@ -24,22 +24,19 @@
     : public aura::client::DragDropClient {
  public:
   DesktopDragDropClientWin(aura::Window* root_window, HWND window);
-  virtual ~DesktopDragDropClientWin();
+  ~DesktopDragDropClientWin() override;
 
   // Overridden from aura::client::DragDropClient:
-  virtual int StartDragAndDrop(
-      const ui::OSExchangeData& data,
-      aura::Window* root_window,
-      aura::Window* source_window,
-      const gfx::Point& screen_location,
-      int operation,
-      ui::DragDropTypes::DragEventSource source) override;
-  virtual void DragUpdate(aura::Window* target,
-                          const ui::LocatedEvent& event) override;
-  virtual void Drop(aura::Window* target,
-                    const ui::LocatedEvent& event) override;
-  virtual void DragCancel() override;
-  virtual bool IsDragDropInProgress() override;
+  int StartDragAndDrop(const ui::OSExchangeData& data,
+                       aura::Window* root_window,
+                       aura::Window* source_window,
+                       const gfx::Point& screen_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;
 
   void OnNativeWidgetDestroying(HWND window);
 
diff --git a/ui/views/widget/desktop_aura/desktop_drop_target_win.h b/ui/views/widget/desktop_aura/desktop_drop_target_win.h
index d376182..73dc15f 100644
--- a/ui/views/widget/desktop_aura/desktop_drop_target_win.h
+++ b/ui/views/widget/desktop_aura/desktop_drop_target_win.h
@@ -29,26 +29,26 @@
                              public aura::WindowObserver {
  public:
   DesktopDropTargetWin(aura::Window* root_window, HWND window);
-  virtual ~DesktopDropTargetWin();
+  ~DesktopDropTargetWin() override;
 
  private:
   // ui::DropTargetWin implementation:
-  virtual DWORD OnDragEnter(IDataObject* data_object,
-                            DWORD key_state,
-                            POINT position,
-                            DWORD effect) override;
-  virtual DWORD OnDragOver(IDataObject* data_object,
-                           DWORD key_state,
-                           POINT position,
-                           DWORD effect) override;
-  virtual void OnDragLeave(IDataObject* data_object) override;
-  virtual DWORD OnDrop(IDataObject* data_object,
-                       DWORD key_state,
-                       POINT position,
-                       DWORD effect) override;
+  DWORD OnDragEnter(IDataObject* data_object,
+                    DWORD key_state,
+                    POINT position,
+                    DWORD effect) override;
+  DWORD OnDragOver(IDataObject* data_object,
+                   DWORD key_state,
+                   POINT position,
+                   DWORD effect) override;
+  void OnDragLeave(IDataObject* data_object) override;
+  DWORD OnDrop(IDataObject* data_object,
+               DWORD key_state,
+               POINT position,
+               DWORD effect) override;
 
   // aura::WindowObserver implementation:
-  virtual void OnWindowDestroyed(aura::Window* window) override;
+  void OnWindowDestroyed(aura::Window* window) override;
 
   // Common functionality for the ui::DropTargetWin methods to translate from
   // COM data types to Aura ones.
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 8472b6a..c82ced73 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -15,6 +15,7 @@
 #include "ui/aura/window_property.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
+#include "ui/base/ime/input_method.h"
 #include "ui/base/ui_base_switches_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
@@ -380,6 +381,9 @@
         view_for_activation = GetWidget()->GetRootView();
       activation_client->ActivateWindow(
           view_for_activation->GetWidget()->GetNativeView());
+      // Refreshes the focus info to IMF in case that IMF cached the old info
+      // about focused text input client when it was "inactive".
+      GetHostInputMethod()->OnFocus();
     }
   } else {
     // If we're not active we need to deactivate the corresponding
@@ -387,8 +391,10 @@
     // deactivated (child widgets don't get native desktop activation changes,
     // only aura activation changes).
     aura::Window* active_window = activation_client->GetActiveWindow();
-    if (active_window)
+    if (active_window) {
       activation_client->DeactivateWindow(active_window);
+      GetHostInputMethod()->OnBlur();
+    }
   }
 }
 
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.h b/ui/views/widget/desktop_aura/desktop_screen_win.h
index 59776a6..16357a3 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_win.h
+++ b/ui/views/widget/desktop_aura/desktop_screen_win.h
@@ -13,14 +13,13 @@
 class VIEWS_EXPORT DesktopScreenWin : public gfx::ScreenWin {
 public:
   DesktopScreenWin();
-  virtual ~DesktopScreenWin();
+  ~DesktopScreenWin() override;
 
  private:
   // Overridden from gfx::ScreenWin:
-  virtual gfx::Display GetDisplayMatching(
-      const gfx::Rect& match_rect) const override;
-  virtual HWND GetHWNDFromNativeView(gfx::NativeView window) const override;
-  virtual gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override;
+  gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
+  HWND GetHWNDFromNativeView(gfx::NativeView window) const override;
+  gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override;
 
   DISALLOW_COPY_AND_ASSIGN(DesktopScreenWin);
 };
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 8e8aec2..6e32fc7 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -38,170 +38,165 @@
   DesktopWindowTreeHostWin(
       internal::NativeWidgetDelegate* native_widget_delegate,
       DesktopNativeWidgetAura* desktop_native_widget_aura);
-  virtual ~DesktopWindowTreeHostWin();
+  ~DesktopWindowTreeHostWin() override;
 
   // A way of converting an HWND into a content window.
   static aura::Window* GetContentWindowForHWND(HWND hwnd);
 
  protected:
   // Overridden from DesktopWindowTreeHost:
-  virtual void Init(aura::Window* content_window,
-                    const Widget::InitParams& params) override;
-  virtual void OnNativeWidgetCreated(const Widget::InitParams& params) override;
-  virtual scoped_ptr<corewm::Tooltip> CreateTooltip() override;
-  virtual scoped_ptr<aura::client::DragDropClient>
-      CreateDragDropClient(DesktopNativeCursorManager* cursor_manager) override;
-  virtual void Close() override;
-  virtual void CloseNow() override;
-  virtual aura::WindowTreeHost* AsWindowTreeHost() override;
-  virtual void ShowWindowWithState(ui::WindowShowState show_state) override;
-  virtual void ShowMaximizedWithBounds(
-      const gfx::Rect& restored_bounds) override;
-  virtual bool IsVisible() const override;
-  virtual void SetSize(const gfx::Size& size) override;
-  virtual void StackAtTop() override;
-  virtual void CenterWindow(const gfx::Size& size) override;
-  virtual void GetWindowPlacement(
-      gfx::Rect* bounds,
-      ui::WindowShowState* show_state) const override;
-  virtual gfx::Rect GetWindowBoundsInScreen() const override;
-  virtual gfx::Rect GetClientAreaBoundsInScreen() const override;
-  virtual gfx::Rect GetRestoredBounds() const override;
-  virtual gfx::Rect GetWorkAreaBoundsInScreen() const override;
-  virtual void SetShape(gfx::NativeRegion native_region) override;
-  virtual void Activate() override;
-  virtual void Deactivate() override;
-  virtual bool IsActive() const override;
-  virtual void Maximize() override;
-  virtual void Minimize() override;
-  virtual void Restore() override;
-  virtual bool IsMaximized() const override;
-  virtual bool IsMinimized() const override;
-  virtual bool HasCapture() const override;
-  virtual void SetAlwaysOnTop(bool always_on_top) override;
-  virtual bool IsAlwaysOnTop() const override;
-  virtual void SetVisibleOnAllWorkspaces(bool always_visible) override;
-  virtual bool SetWindowTitle(const base::string16& title) override;
-  virtual void ClearNativeFocus() override;
-  virtual Widget::MoveLoopResult RunMoveLoop(
+  void Init(aura::Window* content_window,
+            const Widget::InitParams& params) override;
+  void OnNativeWidgetCreated(const Widget::InitParams& params) override;
+  scoped_ptr<corewm::Tooltip> CreateTooltip() override;
+  scoped_ptr<aura::client::DragDropClient> CreateDragDropClient(
+      DesktopNativeCursorManager* cursor_manager) override;
+  void Close() override;
+  void CloseNow() override;
+  aura::WindowTreeHost* AsWindowTreeHost() override;
+  void ShowWindowWithState(ui::WindowShowState show_state) override;
+  void ShowMaximizedWithBounds(const gfx::Rect& restored_bounds) override;
+  bool IsVisible() const override;
+  void SetSize(const gfx::Size& size) override;
+  void StackAtTop() override;
+  void CenterWindow(const gfx::Size& size) override;
+  void GetWindowPlacement(gfx::Rect* bounds,
+                          ui::WindowShowState* show_state) const override;
+  gfx::Rect GetWindowBoundsInScreen() const override;
+  gfx::Rect GetClientAreaBoundsInScreen() const override;
+  gfx::Rect GetRestoredBounds() const override;
+  gfx::Rect GetWorkAreaBoundsInScreen() const override;
+  void SetShape(gfx::NativeRegion native_region) override;
+  void Activate() override;
+  void Deactivate() override;
+  bool IsActive() const override;
+  void Maximize() override;
+  void Minimize() override;
+  void Restore() override;
+  bool IsMaximized() const override;
+  bool IsMinimized() const override;
+  bool HasCapture() const override;
+  void SetAlwaysOnTop(bool always_on_top) override;
+  bool IsAlwaysOnTop() const override;
+  void SetVisibleOnAllWorkspaces(bool always_visible) override;
+  bool SetWindowTitle(const base::string16& title) override;
+  void ClearNativeFocus() override;
+  Widget::MoveLoopResult RunMoveLoop(
       const gfx::Vector2d& drag_offset,
       Widget::MoveLoopSource source,
       Widget::MoveLoopEscapeBehavior escape_behavior) override;
-  virtual void EndMoveLoop() override;
-  virtual void SetVisibilityChangedAnimationsEnabled(bool value) override;
-  virtual bool ShouldUseNativeFrame() const override;
-  virtual bool ShouldWindowContentsBeTransparent() const override;
-  virtual void FrameTypeChanged() override;
-  virtual void SetFullscreen(bool fullscreen) override;
-  virtual bool IsFullscreen() const override;
-  virtual void SetOpacity(unsigned char opacity) override;
-  virtual void SetWindowIcons(const gfx::ImageSkia& window_icon,
-                              const gfx::ImageSkia& app_icon) override;
-  virtual void InitModalType(ui::ModalType modal_type) override;
-  virtual void FlashFrame(bool flash_frame) override;
-  virtual void OnRootViewLayout() override;
-  virtual void OnNativeWidgetFocus() override;
-  virtual void OnNativeWidgetBlur() override;
-  virtual bool IsAnimatingClosed() const override;
-  virtual bool IsTranslucentWindowOpacitySupported() const override;
-  virtual void SizeConstraintsChanged() override;
+  void EndMoveLoop() override;
+  void SetVisibilityChangedAnimationsEnabled(bool value) override;
+  bool ShouldUseNativeFrame() const override;
+  bool ShouldWindowContentsBeTransparent() const override;
+  void FrameTypeChanged() override;
+  void SetFullscreen(bool fullscreen) override;
+  bool IsFullscreen() const override;
+  void SetOpacity(unsigned char opacity) override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void InitModalType(ui::ModalType modal_type) override;
+  void FlashFrame(bool flash_frame) override;
+  void OnRootViewLayout() override;
+  void OnNativeWidgetFocus() override;
+  void OnNativeWidgetBlur() override;
+  bool IsAnimatingClosed() const override;
+  bool IsTranslucentWindowOpacitySupported() const override;
+  void SizeConstraintsChanged() override;
 
   // Overridden from aura::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 SetCursorNative(gfx::NativeCursor cursor) override;
-  virtual void OnCursorVisibilityChangedNative(bool show) override;
-  virtual void MoveCursorToNative(const gfx::Point& location) 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 SetCursorNative(gfx::NativeCursor cursor) override;
+  void OnCursorVisibilityChangedNative(bool show) override;
+  void MoveCursorToNative(const gfx::Point& location) override;
 
   // Overridden frm ui::EventSource
-  virtual ui::EventProcessor* GetEventProcessor() override;
+  ui::EventProcessor* GetEventProcessor() override;
 
   // Overridden from aura::client::AnimationHost
-  virtual void SetHostTransitionOffsets(
+  void SetHostTransitionOffsets(
       const gfx::Vector2d& top_left_delta,
       const gfx::Vector2d& bottom_right_delta) override;
-  virtual void OnWindowHidingAnimationCompleted() override;
+  void OnWindowHidingAnimationCompleted() override;
 
   // Overridden from HWNDMessageHandlerDelegate:
-  virtual bool IsWidgetWindow() const override;
-  virtual bool IsUsingCustomFrame() const override;
-  virtual void SchedulePaint() override;
-  virtual void EnableInactiveRendering() override;
-  virtual bool IsInactiveRenderingDisabled() override;
-  virtual bool CanResize() const override;
-  virtual bool CanMaximize() const override;
-  virtual bool CanMinimize() const override;
-  virtual bool CanActivate() const override;
-  virtual bool WidgetSizeIsClientSize() const override;
-  virtual bool IsModal() const override;
-  virtual int GetInitialShowState() const override;
-  virtual bool WillProcessWorkAreaChange() const override;
-  virtual int GetNonClientComponent(const gfx::Point& point) const override;
-  virtual void GetWindowMask(const gfx::Size& size, gfx::Path* path) override;
-  virtual bool GetClientAreaInsets(gfx::Insets* insets) const override;
-  virtual void GetMinMaxSize(gfx::Size* min_size,
-                             gfx::Size* max_size) const override;
-  virtual gfx::Size GetRootViewSize() const override;
-  virtual void ResetWindowControls() override;
-  virtual void PaintLayeredWindow(gfx::Canvas* canvas) override;
-  virtual gfx::NativeViewAccessible GetNativeViewAccessible() override;
-  virtual bool ShouldHandleSystemCommands() const override;
-  virtual InputMethod* GetInputMethod() override;
-  virtual void HandleAppDeactivated() override;
-  virtual void HandleActivationChanged(bool active) override;
-  virtual bool HandleAppCommand(short command) override;
-  virtual void HandleCancelMode() override;
-  virtual void HandleCaptureLost() override;
-  virtual void HandleClose() override;
-  virtual bool HandleCommand(int command) override;
-  virtual void HandleAccelerator(const ui::Accelerator& accelerator) override;
-  virtual void HandleCreate() override;
-  virtual void HandleDestroying() override;
-  virtual void HandleDestroyed() override;
-  virtual bool HandleInitialFocus(ui::WindowShowState show_state) override;
-  virtual void HandleDisplayChange() override;
-  virtual void HandleBeginWMSizeMove() override;
-  virtual void HandleEndWMSizeMove() override;
-  virtual void HandleMove() override;
-  virtual void HandleWorkAreaChanged() override;
-  virtual void HandleVisibilityChanging(bool visible) override;
-  virtual void HandleVisibilityChanged(bool visible) override;
-  virtual void HandleClientSizeChanged(const gfx::Size& new_size) override;
-  virtual void HandleFrameChanged() override;
-  virtual void HandleNativeFocus(HWND last_focused_window) override;
-  virtual void HandleNativeBlur(HWND focused_window) override;
-  virtual bool HandleMouseEvent(const ui::MouseEvent& event) override;
-  virtual bool HandleKeyEvent(const ui::KeyEvent& event) override;
-  virtual bool HandleUntranslatedKeyEvent(const ui::KeyEvent& event) override;
-  virtual void HandleTouchEvent(const ui::TouchEvent& event) override;
-  virtual bool HandleIMEMessage(UINT message,
-                                WPARAM w_param,
-                                LPARAM l_param,
-                                LRESULT* result) override;
-  virtual void HandleInputLanguageChange(DWORD character_set,
-                                         HKL input_language_id) override;
-  virtual bool HandlePaintAccelerated(const gfx::Rect& invalid_rect) override;
-  virtual void HandlePaint(gfx::Canvas* canvas) override;
-  virtual bool HandleTooltipNotify(int w_param,
-                                   NMHDR* l_param,
-                                   LRESULT* l_result) override;
-  virtual void HandleMenuLoop(bool in_menu_loop) override;
-  virtual bool PreHandleMSG(UINT message,
-                            WPARAM w_param,
-                            LPARAM l_param,
-                            LRESULT* result) override;
-  virtual void PostHandleMSG(UINT message,
-                             WPARAM w_param,
-                             LPARAM l_param) override;
-  virtual bool HandleScrollEvent(const ui::ScrollEvent& event) override;
-  virtual void HandleWindowSizeChanging() override;
+  bool IsWidgetWindow() const override;
+  bool IsUsingCustomFrame() const override;
+  void SchedulePaint() override;
+  void EnableInactiveRendering() override;
+  bool IsInactiveRenderingDisabled() override;
+  bool CanResize() const override;
+  bool CanMaximize() const override;
+  bool CanMinimize() const override;
+  bool CanActivate() const override;
+  bool WidgetSizeIsClientSize() const override;
+  bool IsModal() const override;
+  int GetInitialShowState() const override;
+  bool WillProcessWorkAreaChange() const override;
+  int GetNonClientComponent(const gfx::Point& point) const override;
+  void GetWindowMask(const gfx::Size& size, gfx::Path* path) override;
+  bool GetClientAreaInsets(gfx::Insets* insets) const override;
+  void GetMinMaxSize(gfx::Size* min_size, gfx::Size* max_size) const override;
+  gfx::Size GetRootViewSize() const override;
+  void ResetWindowControls() override;
+  void PaintLayeredWindow(gfx::Canvas* canvas) override;
+  gfx::NativeViewAccessible GetNativeViewAccessible() override;
+  bool ShouldHandleSystemCommands() const override;
+  InputMethod* GetInputMethod() override;
+  void HandleAppDeactivated() override;
+  void HandleActivationChanged(bool active) override;
+  bool HandleAppCommand(short command) override;
+  void HandleCancelMode() override;
+  void HandleCaptureLost() override;
+  void HandleClose() override;
+  bool HandleCommand(int command) override;
+  void HandleAccelerator(const ui::Accelerator& accelerator) override;
+  void HandleCreate() override;
+  void HandleDestroying() override;
+  void HandleDestroyed() override;
+  bool HandleInitialFocus(ui::WindowShowState show_state) override;
+  void HandleDisplayChange() override;
+  void HandleBeginWMSizeMove() override;
+  void HandleEndWMSizeMove() override;
+  void HandleMove() override;
+  void HandleWorkAreaChanged() override;
+  void HandleVisibilityChanging(bool visible) override;
+  void HandleVisibilityChanged(bool visible) override;
+  void HandleClientSizeChanged(const gfx::Size& new_size) override;
+  void HandleFrameChanged() override;
+  void HandleNativeFocus(HWND last_focused_window) override;
+  void HandleNativeBlur(HWND focused_window) override;
+  bool HandleMouseEvent(const ui::MouseEvent& event) override;
+  bool HandleKeyEvent(const ui::KeyEvent& event) override;
+  bool HandleUntranslatedKeyEvent(const ui::KeyEvent& event) override;
+  void HandleTouchEvent(const ui::TouchEvent& event) override;
+  bool HandleIMEMessage(UINT message,
+                        WPARAM w_param,
+                        LPARAM l_param,
+                        LRESULT* result) override;
+  void HandleInputLanguageChange(DWORD character_set,
+                                 HKL input_language_id) override;
+  bool HandlePaintAccelerated(const gfx::Rect& invalid_rect) override;
+  void HandlePaint(gfx::Canvas* canvas) override;
+  bool HandleTooltipNotify(int w_param,
+                           NMHDR* l_param,
+                           LRESULT* l_result) override;
+  void HandleMenuLoop(bool in_menu_loop) override;
+  bool PreHandleMSG(UINT message,
+                    WPARAM w_param,
+                    LPARAM l_param,
+                    LRESULT* result) override;
+  void PostHandleMSG(UINT message, WPARAM w_param, LPARAM l_param) override;
+  bool HandleScrollEvent(const ui::ScrollEvent& event) override;
+  void HandleWindowSizeChanging() override;
 
   Widget* GetWidget();
   const Widget* GetWidget() const;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
index fb76c9b..3876873d 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
@@ -23,6 +23,8 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gl/gl_surface.h"
+#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/ime/input_method.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/test/x11_property_change_waiter.h"
 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@@ -251,4 +253,29 @@
   window2->RemovePreTargetHandler(&recorder2);
 }
 
+TEST_F(DesktopWindowTreeHostX11Test, InputMethodFocus) {
+  scoped_ptr<Widget> widget(CreateWidget(gfx::Rect(100, 100, 100, 100)));
+  scoped_ptr<Textfield> textfield(new Textfield);
+  textfield->SetBounds(0, 0, 200, 20);
+  widget->GetRootView()->AddChildView(textfield.get());
+  widget->Show();
+  textfield->RequestFocus();
+
+  EXPECT_FALSE(widget->IsActive());
+  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+            widget->GetInputMethod()->GetTextInputType());
+
+  widget->Activate();
+
+  EXPECT_TRUE(widget->IsActive());
+  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+            widget->GetInputMethod()->GetTextInputType());
+
+  widget->Deactivate();
+
+  EXPECT_FALSE(widget->IsActive());
+  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+            widget->GetInputMethod()->GetTextInputType());
+}
+
 }  // namespace views
diff --git a/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
index dc3c8acc..33b6347 100644
--- a/ui/views/widget/desktop_aura/x11_desktop_handler.cc
+++ b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
@@ -75,7 +75,7 @@
 }
 
 void X11DesktopHandler::ActivateWindow(::Window window) {
-  if (current_window_ == window &&
+  if ((current_window_ == None || current_window_ == window) &&
       current_window_active_state_ == NOT_ACTIVE) {
     // |window| is most likely still active wrt to the X server. Undo the
     // changes made in DeactivateWindow().
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h
index b7db7f2..a966eae2 100644
--- a/ui/views/win/hwnd_message_handler.h
+++ b/ui/views/win/hwnd_message_handler.h
@@ -115,7 +115,7 @@
     public ui::WindowEventTarget {
  public:
   explicit HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate);
-  ~HWNDMessageHandler();
+  ~HWNDMessageHandler() override;
 
   void Init(HWND parent, const gfx::Rect& bounds);
   void InitModalType(ui::ModalType modal_type);
@@ -212,38 +212,36 @@
   typedef std::set<DWORD> TouchIDs;
 
   // Overridden from internal::InputMethodDelegate:
-  virtual void DispatchKeyEventPostIME(const ui::KeyEvent& key) override;
+  void DispatchKeyEventPostIME(const ui::KeyEvent& key) override;
 
   // Overridden from WindowImpl:
-  virtual HICON GetDefaultWindowIcon() const override;
-  virtual HICON GetSmallWindowIcon() const override;
-  virtual LRESULT OnWndProc(UINT message,
-                            WPARAM w_param,
-                            LPARAM l_param) override;
+  HICON GetDefaultWindowIcon() const override;
+  HICON GetSmallWindowIcon() const override;
+  LRESULT OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) override;
 
   // Overridden from WindowEventTarget
-  virtual LRESULT HandleMouseMessage(unsigned int message,
-                                     WPARAM w_param,
-                                     LPARAM l_param,
-                                     bool* handled) override;
-  virtual LRESULT HandleKeyboardMessage(unsigned int message,
-                                        WPARAM w_param,
-                                        LPARAM l_param,
-                                        bool* handled) override;
-  virtual LRESULT HandleTouchMessage(unsigned int message,
-                                     WPARAM w_param,
-                                     LPARAM l_param,
-                                     bool* handled) override;
+  LRESULT HandleMouseMessage(unsigned int message,
+                             WPARAM w_param,
+                             LPARAM l_param,
+                             bool* handled) override;
+  LRESULT HandleKeyboardMessage(unsigned int message,
+                                WPARAM w_param,
+                                LPARAM l_param,
+                                bool* handled) override;
+  LRESULT HandleTouchMessage(unsigned int message,
+                             WPARAM w_param,
+                             LPARAM l_param,
+                             bool* handled) override;
 
-  virtual LRESULT HandleScrollMessage(unsigned int message,
-                                      WPARAM w_param,
-                                      LPARAM l_param,
-                                      bool* handled) override;
+  LRESULT HandleScrollMessage(unsigned int message,
+                              WPARAM w_param,
+                              LPARAM l_param,
+                              bool* handled) override;
 
-  virtual LRESULT HandleNcHitTestMessage(unsigned int message,
-                                         WPARAM w_param,
-                                         LPARAM l_param,
-                                         bool* handled) override;
+  LRESULT HandleNcHitTestMessage(unsigned int message,
+                                 WPARAM w_param,
+                                 LPARAM l_param,
+                                 bool* handled) override;
 
   // Returns the auto-hide edges of the appbar. See
   // ViewsDelegate::GetAppbarAutohideEdges() for details. If the edges change,
diff --git a/ui/web_dialogs/test/test_web_dialog_delegate.cc b/ui/web_dialogs/test/test_web_dialog_delegate.cc
index e35eecf..41b07bc6 100644
--- a/ui/web_dialogs/test/test_web_dialog_delegate.cc
+++ b/ui/web_dialogs/test/test_web_dialog_delegate.cc
@@ -60,9 +60,8 @@
 }
 
 void TestWebDialogDelegate::OnCloseContents(WebContents* source,
-    bool* out_close_dialog) {
-  if (out_close_dialog)
-    *out_close_dialog = true;
+                                            bool* out_close_dialog) {
+  *out_close_dialog = true;
 }
 
 bool TestWebDialogDelegate::ShouldShowDialogTitle() const {
diff --git a/ui/web_dialogs/web_dialog_delegate.h b/ui/web_dialogs/web_dialog_delegate.h
index 6d2079d..640dfd0 100644
--- a/ui/web_dialogs/web_dialog_delegate.h
+++ b/ui/web_dialogs/web_dialog_delegate.h
@@ -98,6 +98,7 @@
   // away. Only relevant if your dialog hosts code that calls
   // windows.close() and you've allowed that.  If the output parameter
   // is set to true, then the dialog is closed.  The default is false.
+  // |out_close_dialog| is never NULL.
   virtual void OnCloseContents(content::WebContents* source,
                                bool* out_close_dialog) = 0;
 
diff --git a/ui/webui/resources/js/cr/ui/list.js b/ui/webui/resources/js/cr/ui/list.js
index e3f152a..e89713b 100644
--- a/ui/webui/resources/js/cr/ui/list.js
+++ b/ui/webui/resources/js/cr/ui/list.js
@@ -815,7 +815,7 @@
 
     /**
      * Creates a new list item.
-     * @param {*} value The value to use for the item.
+     * @param {?} value The value to use for the item.
      * @return {!cr.ui.ListItem} The newly created list item.
      */
     createItem: function(value) {
diff --git a/ui/webui/resources/js/cr/ui/menu_button.js b/ui/webui/resources/js/cr/ui/menu_button.js
index e240a32..e7f9804 100644
--- a/ui/webui/resources/js/cr/ui/menu_button.js
+++ b/ui/webui/resources/js/cr/ui/menu_button.js
@@ -44,6 +44,7 @@
     decorate: function() {
       this.addEventListener('mousedown', this);
       this.addEventListener('keydown', this);
+      this.addEventListener('dblclick', this);
 
       // Adding the 'custom-appearance' class prevents widgets.css from changing
       // the appearance of this element.
@@ -154,6 +155,19 @@
         case 'resize':
           this.hideMenu();
           break;
+        case 'contextmenu':
+          if ((!this.menu || !this.menu.contains(e.target)) &&
+              (!this.hideTimestamp_ || Date.now() - this.hideTimestamp_ > 50))
+            this.showMenu(true);
+          e.preventDefault();
+          // Don't allow elements further up in the DOM to show their menus.
+          e.stopPropagation();
+          break;
+        case 'dblclick':
+          // Don't allow double click events to propagate.
+          e.preventDefault();
+          e.stopPropagation();
+          break;
       }
     },
 
@@ -186,6 +200,7 @@
       this.showingEvents_.add(doc, 'scroll', this, true);
       this.showingEvents_.add(win, 'popstate', this);
       this.showingEvents_.add(win, 'resize', this);
+      this.showingEvents_.add(this.menu, 'contextmenu', this);
       this.showingEvents_.add(this.menu, 'activate', this);
       this.positionMenu_();
 
@@ -212,6 +227,11 @@
 
       this.showingEvents_.removeAll();
       this.focus();
+
+      // On windows we might hide the menu in a right mouse button up and if
+      // that is the case we wait some short period before we allow the menu
+      // to be shown again.
+      this.hideTimestamp_ = cr.isWindows ? Date.now() : 0;
     },
 
     /**
diff --git a/ui/wm/core/nested_accelerator_dispatcher_win.cc b/ui/wm/core/nested_accelerator_dispatcher_win.cc
index f3fc5d78..8fa42fef 100644
--- a/ui/wm/core/nested_accelerator_dispatcher_win.cc
+++ b/ui/wm/core/nested_accelerator_dispatcher_win.cc
@@ -31,16 +31,16 @@
   NestedAcceleratorDispatcherWin(NestedAcceleratorDelegate* delegate,
                                  MessagePumpDispatcher* nested)
       : NestedAcceleratorDispatcher(delegate), nested_dispatcher_(nested) {}
-  virtual ~NestedAcceleratorDispatcherWin() {}
+  ~NestedAcceleratorDispatcherWin() override {}
 
  private:
   // NestedAcceleratorDispatcher:
-  virtual scoped_ptr<base::RunLoop> CreateRunLoop() override {
+  scoped_ptr<base::RunLoop> CreateRunLoop() override {
     return make_scoped_ptr(new base::RunLoop(this));
   }
 
   // MessagePumpDispatcher:
-  virtual uint32_t Dispatch(const MSG& event) override {
+  uint32_t Dispatch(const MSG& event) override {
     if (IsKeyEvent(event)) {
       ui::KeyEvent key_event(event);
       ui::Accelerator accelerator = CreateAcceleratorFromKeyEvent(key_event);
diff --git a/url/gurl.h b/url/gurl.h
index 5e804a1..b9136b8 100644
--- a/url/gurl.h
+++ b/url/gurl.h
@@ -225,12 +225,13 @@
 
   // Returns true if the scheme indicates a secure connection.
   //
-  // NOTE: This function is deprecated. You probably want |SchemeUsesTLS| (if
-  // you just want to know if a scheme uses TLS for network transport) or
-  // Chromium's |IsOriginSecure| for a higher-level test about an origin's
-  // security. See those functions' documentation for more detail.
+  // NOTE: This function is deprecated. You probably want
+  // |SchemeIsCryptographic| (if you just want to know if a scheme uses TLS for
+  // network transport) or Chromium's |IsOriginSecure| for a higher-level test
+  // about an origin's security. See those functions' documentation for more
+  // detail.
   //
-  // TODO(palmer): Audit callers and change them to |SchemeUsesTLS| or
+  // TODO(palmer): Audit callers and change them to |SchemeIsCryptographic| or
   // |IsOriginSecure|, as appropriate. Then remove |SchemeIsSecure|.
   // crbug.com/362214
   bool SchemeIsSecure() const {
@@ -239,14 +240,14 @@
             inner_url()->SchemeIsSecure());
   }
 
-  // Returns true if the scheme indicates a network connection that uses TLS for
-  // security.
+  // Returns true if the scheme indicates a network connection that uses TLS or
+  // some other cryptographic protocol (e.g. QUIC) for security.
   //
   // This function is a not a complete test of whether or not an origin's code
   // is minimally trustworthy. For that, see Chromium's |IsOriginSecure| for a
   // higher-level and more complete semantics. See that function's documentation
   // for more detail.
-  bool SchemeUsesTLS() const {
+  bool SchemeIsCryptographic() const {
     return SchemeIs(url::kHttpsScheme) || SchemeIs(url::kWssScheme);
   }