diff --git a/.gitignore b/.gitignore
index 1c40b90a..5f0fead 100644
--- a/.gitignore
+++ b/.gitignore
@@ -63,6 +63,7 @@
 /build/android/bin
 /build/Debug
 /build/Debug_x64
+/build/goma/client
 /build/gomacc.lock
 /build/ipch/
 /build/Release
diff --git a/DEPS b/DEPS
index 791ed8b..540a4e19 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'a5ab9ec295b2e6dca166775a98db67a9a8c18c37',
+  'skia_revision': '28f45b949acc746849100fbe112ee5280f0594c9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'f31c787725eb23f0771a8c98821fe240dcb534a8',
+  'v8_revision': '3a64285df68a0f0791271cccf242e59e6b40b669',
   # 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.
@@ -149,7 +149,7 @@
     Var('chromium_git') + '/external/snappy.git' + '@' + '762bb32f0c9d2f31ba4958c7c0933d22e80c20bf',
 
   'src/tools/gyp':
-    Var('chromium_git') + '/external/gyp.git' + '@' + 'ed163ce233f76a950dce1751ac851dbe4b1c00cc',
+    Var('chromium_git') + '/external/gyp.git' + '@' + '61259d585ce99d9de8b35188cd0025bdbcb58411',
 
   'src/tools/swarming_client':
    Var('chromium_git') + '/external/swarming.client.git' + '@' +  Var('swarming_revision'),
@@ -215,7 +215,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' + '@' + 'ea56a15c2228c9c57429ec6244bbe60a30318722', # commit position 11871
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '73a89e6a418e17421667bdebbd9a8ad40512fecb', # commit position 11890
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -270,7 +270,7 @@
 
   'src/third_party/catapult':
     Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
-    '5528c88fc65d8bf58a26205bd370b93d8a267ff2',
+    '1ae15ca2ece76a60c1b1b20951c3cd38c2fa855a',
 
   'src/third_party/openh264/src':
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc
index d2a19f6..9021deb 100644
--- a/android_webview/browser/deferred_gpu_command_service.cc
+++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -12,6 +12,7 @@
 #include "base/synchronization/lock.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/browser/gpu_utils.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
 #include "gpu/command_buffer/service/gpu_preferences.h"
@@ -27,75 +28,6 @@
 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
     g_service = LAZY_INSTANCE_INITIALIZER;
 
-bool GetSizeTFromSwitch(const base::CommandLine* command_line,
-                        const base::StringPiece& switch_string,
-                        size_t* value) {
-  if (!command_line->HasSwitch(switch_string))
-    return false;
-  std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
-  return base::StringToSizeT(switch_value, value);
-}
-
-gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
-  // TODO(penghuang): share below code with content/gpu/gpu_child_thread.cc
-  // http://crbug.com/590825
-  DCHECK(base::CommandLine::InitializedForCurrentProcess());
-  const base::CommandLine* command_line =
-      base::CommandLine::ForCurrentProcess();
-  gpu::GpuPreferences gpu_preferences;
-  gpu_preferences.single_process =
-      command_line->HasSwitch(switches::kSingleProcess);
-  gpu_preferences.in_process_gpu =
-      command_line->HasSwitch(switches::kInProcessGPU);
-  gpu_preferences.ui_prioritize_in_gpu_process =
-      command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
-  gpu_preferences.compile_shader_always_succeeds =
-      command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
-  gpu_preferences.disable_gl_error_limit =
-    command_line->HasSwitch(switches::kDisableGLErrorLimit);
-  gpu_preferences.disable_glsl_translator =
-    command_line->HasSwitch(switches::kDisableGLSLTranslator);
-  gpu_preferences.disable_gpu_driver_bug_workarounds =
-    command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
-  gpu_preferences.disable_shader_name_hashing =
-    command_line->HasSwitch(switches::kDisableShaderNameHashing);
-  gpu_preferences.enable_gpu_command_logging =
-    command_line->HasSwitch(switches::kEnableGPUCommandLogging);
-  gpu_preferences.enable_gpu_debugging =
-    command_line->HasSwitch(switches::kEnableGPUDebugging);
-  gpu_preferences.enable_gpu_service_logging_gpu =
-    command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
-  gpu_preferences.disable_gpu_program_cache =
-    command_line->HasSwitch(switches::kDisableGpuProgramCache);
-  gpu_preferences.enforce_gl_minimums =
-    command_line->HasSwitch(switches::kEnforceGLMinimums);
-  if (GetSizeTFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
-                         &gpu_preferences.force_gpu_mem_available)) {
-    gpu_preferences.force_gpu_mem_available *= 1024 * 1024;
-  }
-  if (GetSizeTFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
-                         &gpu_preferences.gpu_program_cache_size)) {
-    gpu_preferences.gpu_program_cache_size *= 1024;
-  }
-  gpu_preferences.enable_share_group_async_texture_upload =
-    command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload);
-  gpu_preferences.enable_subscribe_uniform_extension =
-    command_line->HasSwitch(switches::kEnableSubscribeUniformExtension);
-  gpu_preferences.enable_threaded_texture_mailboxes =
-    command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
-  gpu_preferences.gl_shader_interm_output =
-    command_line->HasSwitch(switches::kGLShaderIntermOutput);
-  gpu_preferences.emulate_shader_precision =
-    command_line->HasSwitch(switches::kEmulateShaderPrecision);
-  gpu_preferences.enable_gpu_service_logging =
-      command_line->HasSwitch(switches::kEnableGPUServiceLogging);
-  gpu_preferences.enable_gpu_service_tracing =
-      command_line->HasSwitch(switches::kEnableGPUServiceTracing);
-  gpu_preferences.enable_unsafe_es3_apis =
-    command_line->HasSwitch(switches::kEnableUnsafeES3APIs);
-  return gpu_preferences;
-}
-
 }  // namespace
 
 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
@@ -140,7 +72,8 @@
 }
 
 DeferredGpuCommandService::DeferredGpuCommandService()
-    : gpu::InProcessCommandBuffer::Service(GetGpuPreferencesFromCommandLine()),
+    : gpu::InProcessCommandBuffer::Service(
+          content::GetGpuPreferencesFromCommandLine()),
       sync_point_manager_(new gpu::SyncPointManager(true)) {
 }
 
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper.cc b/android_webview/browser/net/aw_cookie_store_wrapper.cc
index 8edc444..35af1a5 100644
--- a/android_webview/browser/net/aw_cookie_store_wrapper.cc
+++ b/android_webview/browser/net/aw_cookie_store_wrapper.cc
@@ -195,6 +195,8 @@
     : client_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       weak_factory_(this) {}
 
+AwCookieStoreWrapper::~AwCookieStoreWrapper() {}
+
 void AwCookieStoreWrapper::SetCookieWithOptionsAsync(
     const GURL& url,
     const std::string& cookie_line,
@@ -333,8 +335,6 @@
   return subscription->Subscribe(url, name, callback);
 }
 
-AwCookieStoreWrapper::~AwCookieStoreWrapper() {}
-
 base::Closure AwCookieStoreWrapper::CreateWrappedClosureCallback(
     const base::Closure& callback) {
   if (callback.is_null())
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper.h b/android_webview/browser/net/aw_cookie_store_wrapper.h
index 6db831de..86114fac 100644
--- a/android_webview/browser/net/aw_cookie_store_wrapper.h
+++ b/android_webview/browser/net/aw_cookie_store_wrapper.h
@@ -35,6 +35,7 @@
 class AwCookieStoreWrapper : public net::CookieStore {
  public:
   AwCookieStoreWrapper();
+  ~AwCookieStoreWrapper() override;
 
   // CookieStore implementation:
   void SetCookieWithOptionsAsync(const GURL& url,
@@ -85,8 +86,6 @@
       const CookieChangedCallback& callback) override;
 
  private:
-  ~AwCookieStoreWrapper() override;
-
   // Used by CreateWrappedCallback below. Takes an arugment of Type and posts
   // a task to |task_runner| to invoke |callback| with that argument. If
   // |weak_cookie_store| is deleted before the task is run, the task will not
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper_unittest.cc b/android_webview/browser/net/aw_cookie_store_wrapper_unittest.cc
index b193229..c95f42e 100644
--- a/android_webview/browser/net/aw_cookie_store_wrapper_unittest.cc
+++ b/android_webview/browser/net/aw_cookie_store_wrapper_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "android_webview/browser/net/aw_cookie_store_wrapper.h"
 
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "net/cookies/cookie_store.h"
 #include "net/cookies/cookie_store_test_callbacks.h"
 #include "net/cookies/cookie_store_unittest.h"
@@ -13,8 +13,8 @@
 namespace android_webview {
 
 struct AwCookieStoreWrapperTestTraits {
-  static scoped_refptr<net::CookieStore> Create() {
-    scoped_refptr<net::CookieStore> cookie_store(new AwCookieStoreWrapper());
+  static scoped_ptr<net::CookieStore> Create() {
+    scoped_ptr<net::CookieStore> cookie_store(new AwCookieStoreWrapper());
 
     // Android Webview can run multiple tests without restarting the binary,
     // so have to delete any cookies the global store may have from an earlier
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index 08ef8df..726883f 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -200,8 +200,6 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(!url_request_context_);
 
-  cookie_store_ = new AwCookieStoreWrapper();
-
   net::URLRequestContextBuilder builder;
   scoped_ptr<AwNetworkDelegate> aw_network_delegate(new AwNetworkDelegate());
 
@@ -237,8 +235,9 @@
   builder.set_proxy_service(net::ProxyService::CreateWithoutProxyResolver(
       std::move(proxy_config_service_), net_log_.get()));
   builder.set_net_log(net_log_.get());
-  builder.SetCookieAndChannelIdStores(cookie_store_,
-                                      std::move(channel_id_service));
+  builder.SetCookieAndChannelIdStores(
+      make_scoped_ptr(new AwCookieStoreWrapper()),
+      std::move(channel_id_service));
 
   net::URLRequestContextBuilder::HttpCacheParams cache_params;
   cache_params.type =
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h
index 763a45cf..023449e9 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.h
+++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -17,7 +17,6 @@
 class PrefService;
 
 namespace net {
-class CookieStore;
 class HostResolver;
 class HttpAuthHandlerFactory;
 class HttpAuthPreferences;
@@ -81,7 +80,6 @@
 
   scoped_ptr<net::NetLog> net_log_;
   scoped_ptr<net::ProxyConfigService> proxy_config_service_;
-  scoped_refptr<net::CookieStore> cookie_store_;
   scoped_ptr<net::URLRequestJobFactory> job_factory_;
   scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings_;
   // http_auth_preferences_ holds the preferences for the negotiate
diff --git a/android_webview/native/cookie_manager.cc b/android_webview/native/cookie_manager.cc
index ebbc67f..edbd83ac 100644
--- a/android_webview/native/cookie_manager.cc
+++ b/android_webview/native/cookie_manager.cc
@@ -21,6 +21,8 @@
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/path_service.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
@@ -224,7 +226,7 @@
   base::Thread cookie_store_backend_thread_;
 
   scoped_refptr<base::SingleThreadTaskRunner> cookie_store_task_runner_;
-  scoped_refptr<net::CookieStore> cookie_store_;
+  scoped_ptr<net::CookieStore> cookie_store_;
 
   DISALLOW_COPY_AND_ASSIGN(CookieManager);
 };
diff --git a/apps/ui/views/app_window_frame_view.cc b/apps/ui/views/app_window_frame_view.cc
index 4b6246b..728e038 100644
--- a/apps/ui/views/app_window_frame_view.cc
+++ b/apps/ui/views/app_window_frame_view.cc
@@ -374,10 +374,8 @@
 
   // If the frame is dark, we should use the light images so they have
   // some contrast.
-  unsigned char frame_luma =
-      color_utils::GetLuminanceForColor(CurrentFrameColor());
-  const unsigned char kLuminanceThreshold = 100;
-  bool use_light = frame_luma < kLuminanceThreshold;
+  const uint8_t kLumaThreshold = 100;
+  bool use_light = color_utils::GetLuma(CurrentFrameColor()) < kLumaThreshold;
 
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   if (use_light) {
diff --git a/ash/frame/custom_frame_view_ash.cc b/ash/frame/custom_frame_view_ash.cc
index 90d5c6a..a38845d 100644
--- a/ash/frame/custom_frame_view_ash.cc
+++ b/ash/frame/custom_frame_view_ash.cc
@@ -322,7 +322,7 @@
 void CustomFrameViewAsh::HeaderView::OnImmersiveRevealStarted() {
   fullscreen_visible_fraction_ = 0;
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
   parent()->Layout();
 }
 
diff --git a/ash/frame/default_header_painter.cc b/ash/frame/default_header_painter.cc
index 432764b..18086ac 100644
--- a/ash/frame/default_header_painter.cc
+++ b/ash/frame/default_header_painter.cc
@@ -42,8 +42,6 @@
 const SkColor kDefaultFrameColor = SkColorSetRGB(242, 242, 242);
 // Duration of crossfade animation for activating and deactivating frame.
 const int kActivationCrossfadeDurationMs = 200;
-// Luminance below which to use white caption buttons.
-const int kMaxLuminanceForLightButtons = 125;
 
 // Tiles an image into an area, rounding the top corners.
 void TileRoundRect(gfx::Canvas* canvas,
@@ -279,9 +277,8 @@
 }
 
 bool DefaultHeaderPainter::ShouldUseLightImages() {
-  int luminance = color_utils::GetLuminanceForColor(
-      mode_ == MODE_INACTIVE ? inactive_frame_color_ : active_frame_color_);
-  return luminance < kMaxLuminanceForLightButtons;
+  return color_utils::IsDark(mode_ == MODE_INACTIVE ? inactive_frame_color_
+                                                    : active_frame_color_);
 }
 
 void DefaultHeaderPainter::UpdateAllButtonImages() {
diff --git a/ash/shelf/overflow_bubble_view.cc b/ash/shelf/overflow_bubble_view.cc
index d982820..ff0f2c38 100644
--- a/ash/shelf/overflow_bubble_view.cc
+++ b/ash/shelf/overflow_bubble_view.cc
@@ -49,7 +49,7 @@
 
   // Makes bubble view has a layer and clip its children layers.
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
   layer()->SetMasksToBounds(true);
 
   shelf_view_ = shelf_view;
diff --git a/ash/shelf/shelf_button.cc b/ash/shelf/shelf_button.cc
index 43d98c5..5d44aa5 100644
--- a/ash/shelf/shelf_button.cc
+++ b/ash/shelf/shelf_button.cc
@@ -506,7 +506,7 @@
 
   // TODO: refactor the layers so each button doesn't require 2.
   icon_view_->SetPaintToLayer(true);
-  icon_view_->SetFillsBoundsOpaquely(false);
+  icon_view_->layer()->SetFillsBoundsOpaquely(false);
   icon_view_->SetHorizontalAlignment(views::ImageView::CENTER);
   icon_view_->SetVerticalAlignment(views::ImageView::LEADING);
 
diff --git a/ash/system/status_area_widget_delegate.cc b/ash/system/status_area_widget_delegate.cc
index bf0dfc0..c58649b5 100644
--- a/ash/system/status_area_widget_delegate.cc
+++ b/ash/system/status_area_widget_delegate.cc
@@ -55,7 +55,7 @@
   // navigation completion by the user.
   set_allow_deactivate_on_esc(true);
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 StatusAreaWidgetDelegate::~StatusAreaWidgetDelegate() {
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc
index 936917e..0c125bf 100644
--- a/ash/system/tray/tray_background_view.cc
+++ b/ash/system/tray/tray_background_view.cc
@@ -247,7 +247,7 @@
   tray_event_filter_.reset(new TrayEventFilter);
 
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
   // Start the tray items not visible, because visibility changes are animated.
   views::View::SetVisible(false);
 }
diff --git a/ash/system/tray/tray_empty.cc b/ash/system/tray/tray_empty.cc
index 8216322..ceb2209 100644
--- a/ash/system/tray/tray_empty.cc
+++ b/ash/system/tray/tray_empty.cc
@@ -46,7 +46,7 @@
   view->SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
         0, 0, 0));
   view->SetPaintToLayer(true);
-  view->SetFillsBoundsOpaquely(false);
+  view->layer()->SetFillsBoundsOpaquely(false);
   return view;
 }
 
diff --git a/ash/system/tray/tray_item_view.cc b/ash/system/tray/tray_item_view.cc
index ea2262dd..b338358 100644
--- a/ash/system/tray/tray_item_view.cc
+++ b/ash/system/tray/tray_item_view.cc
@@ -30,7 +30,7 @@
       label_(NULL),
       image_view_(NULL) {
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
   SetLayoutManager(
       new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
 }
diff --git a/ash/system/tray/tray_popup_item_container.cc b/ash/system/tray/tray_popup_item_container.cc
index 9a21399..7fa3814 100644
--- a/ash/system/tray/tray_popup_item_container.cc
+++ b/ash/system/tray/tray_popup_item_container.cc
@@ -27,9 +27,10 @@
       views::BoxLayout::kVertical, 0, 0, 0);
   layout->SetDefaultFlex(1);
   SetLayoutManager(layout);
-  SetPaintToLayer(view->layer() != NULL);
-  if (view->layer())
-    SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely());
+  if (view->layer()) {
+    SetPaintToLayer(true);
+    layer()->SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely());
+  }
   AddChildView(view);
   SetVisible(view->visible());
 }
diff --git a/ash/touch/touch_hud_debug.cc b/ash/touch/touch_hud_debug.cc
index 099233b..68441382 100644
--- a/ash/touch/touch_hud_debug.cc
+++ b/ash/touch/touch_hud_debug.cc
@@ -242,7 +242,7 @@
       : touch_log_(touch_log),
         scale_(1) {
     SetPaintToLayer(true);
-    SetFillsBoundsOpaquely(false);
+    layer()->SetFillsBoundsOpaquely(false);
 
     paint_.setStyle(SkPaint::kFill_Style);
   }
diff --git a/ash/touch/touch_hud_projection.cc b/ash/touch/touch_hud_projection.cc
index 30312af..af38df2 100644
--- a/ash/touch/touch_hud_projection.cc
+++ b/ash/touch/touch_hud_projection.cc
@@ -36,7 +36,7 @@
         gradient_center_(SkPoint::Make(kPointRadius + 1,
                                        kPointRadius + 1)) {
     SetPaintToLayer(true);
-    SetFillsBoundsOpaquely(false);
+    layer()->SetFillsBoundsOpaquely(false);
 
     SetSize(gfx::Size(2 * kPointRadius + 2, 2 * kPointRadius + 2));
 
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index d0fa2ad..90d64bb 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -5,6 +5,7 @@
 #include "base/metrics/statistics_recorder.h"
 
 #include "base/at_exit.h"
+#include "base/debug/alias.h"
 #include "base/debug/leak_annotations.h"
 #include "base/json/string_escape.h"
 #include "base/logging.h"
@@ -123,13 +124,17 @@
         histogram_to_return = histogram;
       } else {
         // We already have one histogram with this name.
-        DCHECK_EQ(histogram->histogram_name(),
-                  it->second->histogram_name()) << "hash collision";
+        CHECK_EQ(histogram->histogram_name(),
+                 it->second->histogram_name()) << "hash collision";
         histogram_to_return = it->second;
         histogram_to_delete = histogram;
       }
+      base::debug::Alias(&it);
+      base::debug::Alias(&name);
+      base::debug::Alias(&name_hash);
     }
   }
+  base::debug::Alias(&histogram);
   delete histogram_to_delete;
   return histogram_to_return;
 }
@@ -279,10 +284,22 @@
   if (histograms_ == NULL)
     return NULL;
 
-  HistogramMap::iterator it = histograms_->find(HashMetricName(name));
+  const uint64_t lookup_hash = HashMetricName(name);
+  HistogramMap::iterator it = histograms_->find(lookup_hash);
   if (histograms_->end() == it)
     return NULL;
-  DCHECK_EQ(name, it->second->histogram_name()) << "hash collision";
+
+  const uint64_t existing_hash = it->first;
+  const char* existing_name = it->second->histogram_name().c_str();
+  HistogramMap* histograms = histograms_;
+  CHECK_EQ(name, it->second->histogram_name()) << "hash collision";
+  base::debug::Alias(&lookup_hash);
+  base::debug::Alias(&existing_hash);
+  base::debug::Alias(&name);
+  base::debug::Alias(&existing_name);
+  base::debug::Alias(&it);
+  base::debug::Alias(&histograms);
+
   return it->second;
 }
 
diff --git a/base/test/android/OWNERS b/base/test/android/OWNERS
index 3c9067cf..85ff7a79 100644
--- a/base/test/android/OWNERS
+++ b/base/test/android/OWNERS
@@ -1,3 +1,3 @@
-feng@chromium.org
+jbudorick@chromium.org
 nyquist@chromium.org
 yfriedman@chromium.org
diff --git a/base/tuple.h b/base/tuple.h
index 8898fe0d..78dfd75 100644
--- a/base/tuple.h
+++ b/base/tuple.h
@@ -110,28 +110,6 @@
 template <size_t N>
 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type;
 
-// Traits ----------------------------------------------------------------------
-//
-// A simple traits class for tuple arguments.
-//
-// ValueType: the bare, nonref version of a type (same as the type for nonrefs).
-// RefType: the ref version of a type (same as the type for refs).
-// ParamType: what type to pass to functions (refs should not be constified).
-
-template <class P>
-struct TupleTraits {
-  typedef P ValueType;
-  typedef P& RefType;
-  typedef const P& ParamType;
-};
-
-template <class P>
-struct TupleTraits<P&> {
-  typedef P ValueType;
-  typedef P& RefType;
-  typedef P& ParamType;
-};
-
 // Tuple -----------------------------------------------------------------------
 //
 // This set of classes is useful for bundling 0 or more heterogeneous data types
@@ -151,21 +129,6 @@
 
 using std::get;
 
-// Tuple types ----------------------------------------------------------------
-//
-// Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the
-// definitions of class types the tuple takes as parameters.
-
-template <typename T>
-struct TupleTypes;
-
-template <typename... Ts>
-struct TupleTypes<Tuple<Ts...>> {
-  using ValueTuple = Tuple<typename TupleTraits<Ts>::ValueType...>;
-  using RefTuple = Tuple<typename TupleTraits<Ts>::RefType...>;
-  using ParamTuple = Tuple<typename TupleTraits<Ts>::ParamType...>;
-};
-
 // Tuple creators -------------------------------------------------------------
 //
 // Helper functions for constructing tuples while inferring the template
diff --git a/blimp/net/exact_match_cert_verifier.cc b/blimp/net/exact_match_cert_verifier.cc
index c140c368..1209fbb 100644
--- a/blimp/net/exact_match_cert_verifier.cc
+++ b/blimp/net/exact_match_cert_verifier.cc
@@ -17,7 +17,7 @@
 ExactMatchCertVerifier::ExactMatchCertVerifier(
     scoped_refptr<net::X509Certificate> engine_cert)
     : engine_cert_(std::move(engine_cert)) {
-  DCHECK(engine_cert);
+  DCHECK(engine_cert_);
 
   net::SHA1HashValue sha1_hash;
   sha1_hash = net::X509Certificate::CalculateFingerprint(
diff --git a/build/android/devil/android/device_utils.py b/build/android/devil/android/device_utils.py
index 4ca2bc1..71ccff4 100644
--- a/build/android/devil/android/device_utils.py
+++ b/build/android/devil/android/device_utils.py
@@ -78,6 +78,7 @@
     'android.permission.READ_SYNC_SETTINGS',
     'android.permission.READ_SYNC_STATS',
     'android.permission.RECEIVE_BOOT_COMPLETED',
+    'android.permission.RUN_INSTRUMENTATION',
     'android.permission.USE_CREDENTIALS',
     'android.permission.VIBRATE',
     'android.permission.WAKE_LOCK',
diff --git a/build/android/gyp/lint.py b/build/android/gyp/lint.py
index 5bd8f69c..bc761ff3 100755
--- a/build/android/gyp/lint.py
+++ b/build/android/gyp/lint.py
@@ -10,6 +10,7 @@
 import optparse
 import os
 import sys
+import traceback
 from xml.dom import minidom
 
 from util import build_utils
@@ -123,11 +124,12 @@
 
     try:
       build_utils.CheckOutput(cmd, cwd=_SRC_ROOT)
-    except build_utils.CalledProcessError as e:
+    except build_utils.CalledProcessError:
+      if can_fail_build:
+        traceback.print_exc()
+
       # There is a problem with lint usage
       if not os.path.exists(result_path):
-        print 'Something is wrong:'
-        print e
         raise
 
       # There are actual lint issues
diff --git a/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java b/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java
index 8bf3779..ac51be9e 100644
--- a/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java
+++ b/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java
@@ -93,9 +93,8 @@
 
         Object dexPathList = Reflect.getField(mClassLoader, "pathList");
         Object[] dexElements = (Object[]) Reflect.getField(dexPathList, "dexElements");
-        Object[] additionalElements = makeDexElements(dexFilesArr, optimizedDir);
-        Reflect.setField(dexPathList, "dexElements",
-                Reflect.concatArrays(dexElements, dexElements, additionalElements));
+        dexElements = addDexElements(dexFilesArr, optimizedDir, dexElements);
+        Reflect.setField(dexPathList, "dexElements", dexElements);
     }
 
     /**
@@ -222,17 +221,26 @@
         return entries;
     }
 
-    private static Object[] makeDexElements(File[] files, File optimizedDirectory)
+    private Object[] addDexElements(File[] files, File optimizedDirectory, Object[] curDexElements)
             throws ReflectiveOperationException {
         Class<?> entryClazz = Class.forName("dalvik.system.DexPathList$Element");
         Class<?> clazz = Class.forName("dalvik.system.DexPathList");
-        Object[] entries = new Object[files.length];
+        Object[] ret =
+                Reflect.concatArrays(curDexElements, curDexElements, new Object[files.length]);
         File emptyDir = new File("");
         for (int i = 0; i < files.length; ++i) {
             File file = files[i];
-            Object dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, optimizedDirectory);
-            entries[i] = Reflect.newInstance(entryClazz, emptyDir, false, file, dexFile);
+            Object dexFile;
+            if ("N".equals(Build.VERSION.CODENAME)) {
+                // loadDexFile requires that ret contain all previously added elements.
+                dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, optimizedDirectory,
+                                               mClassLoader, ret);
+            } else {
+                dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, optimizedDirectory);
+            }
+            ret[curDexElements.length + i] =
+                    Reflect.newInstance(entryClazz, emptyDir, false, file, dexFile);
         }
-        return entries;
+        return ret;
     }
 }
diff --git a/build/args/blimp_client.gn b/build/args/blimp_client.gn
index a072eab5..7fde28f4 100644
--- a/build/args/blimp_client.gn
+++ b/build/args/blimp_client.gn
@@ -2,7 +2,7 @@
 #
 # Add import to arg.gn in out directory and run gn gen on the directory to use.
 # E.g. for out directory out/foo:
-# echo "import(\"build/args/blimp_client.gn\")"  > out/foo/args.gn
+# echo "import(\"//build/args/blimp_client.gn\")"  > out/foo/args.gn
 # gn gen out/foo
 #
 # Use gn args to add your own build preference args.
diff --git a/build/args/blimp_engine.gn b/build/args/blimp_engine.gn
index 22a5e43..b78ba7a 100644
--- a/build/args/blimp_engine.gn
+++ b/build/args/blimp_engine.gn
@@ -2,7 +2,7 @@
 #
 # Add import to arg.gn in out directory and run gn gen on the directory to use.
 # E.g. for out directory out/foo:
-# echo "import(\"build/args/blimp_engine.gn\")" > out/foo/args.gn
+# echo "import(\"//build/args/blimp_engine.gn\")" > out/foo/args.gn
 # gn gen out/foo
 #
 # Use gn args to add your own build preference args.
diff --git a/build/common.gypi b/build/common.gypi
index f0faad2..e8042fe 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -2421,10 +2421,6 @@
         ],
       }],
 
-      ['OS=="win" and (clang==1 or asan==1)', {
-        'chromium_win_pch': 0,
-      }],
-
       ['host_clang==1', {
         'host_cc': '<(make_clang_dir)/bin/clang',
         'host_cxx': '<(make_clang_dir)/bin/clang++',
@@ -4228,6 +4224,13 @@
                   '-Wno-uninitialized',
                 ],
               }],
+              ['_toolset=="target" and _type=="executable"', {
+                'conditions': [
+                  ['OS=="linux"', {
+                    'ldflags': ['-pie'],
+                  }],
+                ],
+              }],
             ],
           }],
           ['target_arch=="mips64el"', {
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 73b98e4..52e38512 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1327,7 +1327,9 @@
       data_deps += invoker.data_deps
     }
     if (defined(invoker.main_class)) {
-      data_deps += [ ":$_binary_script_target_name" ]
+      # Some targets use the generated script while building, so make it a dep
+      # rather than a data_dep.
+      deps += [ ":$_binary_script_target_name" ]
     }
   }
 }
@@ -1456,6 +1458,7 @@
     if (_enable_incremental_javac) {
       args += [ "--incremental" ]
       deps += [ "//third_party/jmake" ]
+      inputs += [ "$root_out_dir/bin/jmake" ]
       outputs += [ "${_javac_jar_path}.pdb" ]
     }
     if (_supports_android) {
@@ -1693,7 +1696,9 @@
   }
 
   if (defined(invoker.main_class)) {
-    _final_datadeps += [ ":${_template_name}__java_binary_script" ]
+    # Targets might use the generated script while building, so make it a dep
+    # rather than a data_dep.
+    _final_deps += [ ":${_template_name}__java_binary_script" ]
     java_binary_script("${_template_name}__java_binary_script") {
       forward_variables_from(invoker,
                              [
diff --git a/build/config/gcc/BUILD.gn b/build/config/gcc/BUILD.gn
index c3eec24..41473eb 100644
--- a/build/config/gcc/BUILD.gn
+++ b/build/config/gcc/BUILD.gn
@@ -93,6 +93,9 @@
       # and the new DT_RUNPATH doesn't work without --no-as-needed flag.
       "-Wl,--disable-new-dtags",
     ]
+    if (current_cpu == "mipsel") {
+      ldflags += [ "-pie" ]
+    }
   }
 }
 
diff --git a/build/win_precompile.gypi b/build/win_precompile.gypi
index fb86076..8849eb1 100644
--- a/build/win_precompile.gypi
+++ b/build/win_precompile.gypi
@@ -11,10 +11,11 @@
   'conditions': [
     ['OS=="win" and chromium_win_pch==1', {
         'target_defaults': {
-          'msvs_precompiled_header': '<(DEPTH)/build/precompile.h',
+          'msvs_precompiled_header': 'build/precompile.h',
           'msvs_precompiled_source': '<(DEPTH)/build/precompile.cc',
           'sources': ['<(DEPTH)/build/precompile.cc'],
+          'include_dirs': [ '<(DEPTH)' ],
         }
-      }],
+    }],
   ],
 }
diff --git a/cc/debug/debug_colors.cc b/cc/debug/debug_colors.cc
index 55d71198..564452d9 100644
--- a/cc/debug/debug_colors.cc
+++ b/cc/debug/debug_colors.cc
@@ -146,6 +146,14 @@
   return Scale(1, tree_impl);
 }
 
+// Compressed tile borders are blue.
+SkColor DebugColors::CompressedTileBorderColor() {
+  return SkColorSetARGB(100, 20, 20, 240);
+}
+int DebugColors::CompressedTileBorderWidth(const LayerTreeImpl* tree_impl) {
+  return Scale(2, tree_impl);
+}
+
 // ======= Checkerboard colors =======
 
 // Non-debug checkerboards are grey.
diff --git a/cc/debug/debug_colors.h b/cc/debug/debug_colors.h
index 673f199..03f8855 100644
--- a/cc/debug/debug_colors.h
+++ b/cc/debug/debug_colors.h
@@ -62,6 +62,9 @@
   static SkColor DirectPictureBorderColor();
   static int DirectPictureBorderWidth(const LayerTreeImpl* tree_impl);
 
+  static SkColor CompressedTileBorderColor();
+  static int CompressedTileBorderWidth(const LayerTreeImpl* tree_impl);
+
   static SkColor DefaultCheckerboardColor();
   static SkColor EvictedTileCheckerboardColor();
   static SkColor InvalidatedTileCheckerboardColor();
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 076ee23..8e823d93 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -230,6 +230,9 @@
         } else if (mode == TileDrawInfo::OOM_MODE) {
           color = DebugColors::OOMTileBorderColor();
           width = DebugColors::OOMTileBorderWidth(layer_tree_impl());
+        } else if (iter->draw_info().has_compressed_resource()) {
+          color = DebugColors::CompressedTileBorderColor();
+          width = DebugColors::CompressedTileBorderWidth(layer_tree_impl());
         } else if (iter.resolution() == HIGH_RESOLUTION) {
           color = DebugColors::HighResTileBorderColor();
           width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
index 5c6fa88a..7446afdc 100644
--- a/cc/output/direct_renderer.cc
+++ b/cc/output/direct_renderer.cc
@@ -199,8 +199,7 @@
       "Renderer4.renderPassCount",
       base::saturated_cast<int>(render_passes_in_draw_order->size()));
 
-  const RenderPass* root_render_pass =
-      render_passes_in_draw_order->back().get();
+  RenderPass* root_render_pass = render_passes_in_draw_order->back().get();
   DCHECK(root_render_pass);
 
   DrawingFrame frame;
@@ -224,9 +223,16 @@
 
   BeginDrawingFrame(&frame);
 
+  // Draw all non-root render passes except for the root render pass.
+  for (const auto& pass : *render_passes_in_draw_order) {
+    if (pass.get() == root_render_pass)
+      break;
+    DrawRenderPassAndExecuteCopyRequests(&frame, pass.get());
+  }
+
+  // Create the overlay candidate for the output surface, and mark it as
+  // always handled.
   if (output_surface_->IsDisplayedAsOverlayPlane()) {
-    // Create the overlay candidate for the output surface, and mark it as
-    // always handled.
     OverlayCandidate output_surface_plane;
     output_surface_plane.display_rect =
         gfx::RectF(root_render_pass->output_rect);
@@ -237,36 +243,22 @@
     frame.overlay_list.push_back(output_surface_plane);
   }
 
-  // If we have any copy requests, we can't remove any quads for overlays or
-  // CALayers because the framebuffer would be missing the removed quads'
-  // contents.
-  bool has_copy_requests = false;
-  for (const auto& pass : *render_passes_in_draw_order) {
-    if (!pass->copy_requests.empty()) {
-      has_copy_requests = true;
-      break;
-    }
-  }
-  if (has_copy_requests) {
-    overlay_processor_->SkipProcessForOverlays();
-  } else {
-    overlay_processor_->ProcessForOverlays(
-        resource_provider_, render_passes_in_draw_order, &frame.overlay_list,
-        &frame.ca_layer_overlay_list, &frame.root_damage_rect);
-  }
+  // Attempt to replace some or all of the quads of the root render pass with
+  // overlays.
+  overlay_processor_->ProcessForOverlays(
+      resource_provider_, root_render_pass, &frame.overlay_list,
+      &frame.ca_layer_overlay_list, &frame.root_damage_rect);
 
-  // The damage rect might be empty now, but if empty swap isn't allowed we
-  // still have to draw.
-  bool should_draw = has_copy_requests || !frame.root_damage_rect.IsEmpty() ||
-                     !Capabilities().allow_empty_swap;
-  // If we have to draw but don't support partial swap the whole output should
+  // We can skip all drawing if the damage rect is now empty.
+  bool skip_drawing_root_render_pass =
+      frame.root_damage_rect.IsEmpty() && Capabilities().allow_empty_swap;
+
+  // If we have to draw but don't support partial swap, the whole output should
   // be considered damaged.
-  if (should_draw && !Capabilities().using_partial_swap)
+  if (!skip_drawing_root_render_pass && !Capabilities().using_partial_swap)
     frame.root_damage_rect = root_render_pass->output_rect;
 
-  // If all damage is being drawn with overlays or CALayers then skip drawing
-  // the render passes.
-  if (!should_draw) {
+  if (skip_drawing_root_render_pass) {
     // If any of the overlays is the output surface, then ensure that the
     // backbuffer be allocated (allocation of the backbuffer is a side-effect
     // of BindFramebufferToOutputSurface).
@@ -277,20 +269,9 @@
       }
     }
   } else {
-    for (const auto& pass : *render_passes_in_draw_order) {
-      DrawRenderPass(&frame, pass.get());
-
-      bool first_request = true;
-      for (auto& copy_request : pass->copy_requests) {
-        // Doing a readback is destructive of our state on Mac, so make sure
-        // we restore the state between readbacks. http://crbug.com/99393.
-        if (!first_request)
-          UseRenderPass(&frame, pass.get());
-        CopyCurrentRenderPassToBitmap(&frame, std::move(copy_request));
-        first_request = false;
-      }
-    }
+    DrawRenderPassAndExecuteCopyRequests(&frame, root_render_pass);
   }
+
   FinishDrawingFrame(&frame);
   render_passes_in_draw_order->clear();
 }
@@ -431,6 +412,22 @@
   DCHECK(poly_list->empty());
 }
 
+void DirectRenderer::DrawRenderPassAndExecuteCopyRequests(
+    DrawingFrame* frame,
+    RenderPass* render_pass) {
+  DrawRenderPass(frame, render_pass);
+
+  bool first_request = true;
+  for (auto& copy_request : render_pass->copy_requests) {
+    // Doing a readback is destructive of our state on Mac, so make sure
+    // we restore the state between readbacks. http://crbug.com/99393.
+    if (!first_request)
+      UseRenderPass(frame, render_pass);
+    CopyCurrentRenderPassToBitmap(frame, std::move(copy_request));
+    first_request = false;
+  }
+}
+
 void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
                                     const RenderPass* render_pass) {
   TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass");
diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h
index 0d032f15..1328a3d 100644
--- a/cc/output/direct_renderer.h
+++ b/cc/output/direct_renderer.h
@@ -110,6 +110,8 @@
                      DrawingFrame* frame,
                      const gfx::Rect& render_pass_scissor,
                      bool use_render_pass_scissor);
+  void DrawRenderPassAndExecuteCopyRequests(DrawingFrame* frame,
+                                            RenderPass* render_pass);
   void DrawRenderPass(DrawingFrame* frame, const RenderPass* render_pass);
   bool UseRenderPass(DrawingFrame* frame, const RenderPass* render_pass);
 
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 5d50b0e..1bc3e63 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -1958,7 +1958,7 @@
     ~Strategy() override {}
     MOCK_METHOD3(Attempt,
                  bool(ResourceProvider* resource_provider,
-                      RenderPassList* render_passes,
+                      RenderPass* render_pass,
                       OverlayCandidateList* candidates));
   };
 
diff --git a/cc/output/overlay_processor.cc b/cc/output/overlay_processor.cc
index 74e68d2..bad6f3e 100644
--- a/cc/output/overlay_processor.cc
+++ b/cc/output/overlay_processor.cc
@@ -34,46 +34,54 @@
 
 bool OverlayProcessor::ProcessForCALayers(
     ResourceProvider* resource_provider,
-    RenderPassList* render_passes,
+    RenderPass* render_pass,
     OverlayCandidateList* overlay_candidates,
     CALayerOverlayList* ca_layer_overlays,
     gfx::Rect* damage_rect) {
-  RenderPass* root_render_pass = render_passes->back().get();
-
   OverlayCandidateValidator* overlay_validator =
       surface_->GetOverlayCandidateValidator();
   if (!overlay_validator || !overlay_validator->AllowCALayerOverlays())
     return false;
 
-  if (!ProcessForCALayerOverlays(
-          resource_provider, gfx::RectF(root_render_pass->output_rect),
-          root_render_pass->quad_list, ca_layer_overlays))
+  if (!ProcessForCALayerOverlays(resource_provider,
+                                 gfx::RectF(render_pass->output_rect),
+                                 render_pass->quad_list, ca_layer_overlays))
     return false;
 
   // CALayer overlays are all-or-nothing. If all quads were replaced with
   // layers then clear the list and remove the backbuffer from the overcandidate
   // list.
   overlay_candidates->clear();
-  render_passes->back()->quad_list.clear();
-  overlay_damage_rect_ = root_render_pass->output_rect;
+  render_pass->quad_list.clear();
+  overlay_damage_rect_ = render_pass->output_rect;
   *damage_rect = gfx::Rect();
   return true;
 }
 
 void OverlayProcessor::ProcessForOverlays(ResourceProvider* resource_provider,
-                                          RenderPassList* render_passes,
+                                          RenderPass* render_pass,
                                           OverlayCandidateList* candidates,
                                           CALayerOverlayList* ca_layer_overlays,
                                           gfx::Rect* damage_rect) {
+  // If we have any copy requests, we can't remove any quads for overlays or
+  // CALayers because the framebuffer would be missing the removed quads'
+  // contents.
+  if (!render_pass->copy_requests.empty()) {
+    // If overlay processing was skipped for a frame there's no way to be sure
+    // of the state of the previous frame, so reset.
+    previous_frame_underlay_rect_ = gfx::Rect();
+    return;
+  }
+
   // First attempt to process for CALayers.
-  if (ProcessForCALayers(resource_provider, render_passes, candidates,
+  if (ProcessForCALayers(resource_provider, render_pass, candidates,
                          ca_layer_overlays, damage_rect)) {
     return;
   }
 
   // Only if that fails, attempt hardware overlay strategies.
   for (const auto& strategy : strategies_) {
-    if (!strategy->Attempt(resource_provider, render_passes, candidates))
+    if (!strategy->Attempt(resource_provider, render_pass, candidates))
       continue;
 
     UpdateDamageRect(candidates, damage_rect);
@@ -81,12 +89,6 @@
   }
 }
 
-void OverlayProcessor::SkipProcessForOverlays() {
-  // If overlay processing was skipped for a frame there's no way to be sure
-  // of the state of the previous frame, so reset.
-  previous_frame_underlay_rect_ = gfx::Rect();
-}
-
 // Subtract on-top overlays from the damage rect, unless the overlays use
 // the backbuffer as their content (in which case, add their combined rect
 // back to the damage at the end).
diff --git a/cc/output/overlay_processor.h b/cc/output/overlay_processor.h
index beaae08..4a441a8 100644
--- a/cc/output/overlay_processor.h
+++ b/cc/output/overlay_processor.h
@@ -26,7 +26,7 @@
     // and adds any additional passes necessary to represent overlays to
     // |render_passes|.
     virtual bool Attempt(ResourceProvider* resource_provider,
-                         RenderPassList* render_passes,
+                         RenderPass* render_pass,
                          OverlayCandidateList* candidates) = 0;
   };
   using StrategyList = std::vector<scoped_ptr<Strategy>>;
@@ -38,15 +38,14 @@
 
   gfx::Rect GetAndResetOverlayDamage();
 
+  // Attempt to replace quads from the specified root render pass with overlays
+  // or CALayers. This must be called every frame.
   void ProcessForOverlays(ResourceProvider* resource_provider,
-                          RenderPassList* render_passes,
+                          RenderPass* root_render_pass,
                           OverlayCandidateList* overlay_candidates,
                           CALayerOverlayList* ca_layer_overlays,
                           gfx::Rect* damage_rect);
 
-  // Notify the processor that ProcessForOverlays is being skipped this frame.
-  void SkipProcessForOverlays();
-
  protected:
   StrategyList strategies_;
   OutputSurface* surface_;
@@ -55,7 +54,7 @@
 
  private:
   bool ProcessForCALayers(ResourceProvider* resource_provider,
-                          RenderPassList* render_passes,
+                          RenderPass* render_pass,
                           OverlayCandidateList* overlay_candidates,
                           CALayerOverlayList* ca_layer_overlays,
                           gfx::Rect* damage_rect);
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc
index 10ffcef..ecc4009 100644
--- a/cc/output/overlay_strategy_single_on_top.cc
+++ b/cc/output/overlay_strategy_single_on_top.cc
@@ -20,9 +20,9 @@
 OverlayStrategySingleOnTop::~OverlayStrategySingleOnTop() {}
 
 bool OverlayStrategySingleOnTop::Attempt(ResourceProvider* resource_provider,
-                                         RenderPassList* render_passes,
+                                         RenderPass* render_pass,
                                          OverlayCandidateList* candidate_list) {
-  QuadList* quad_list = &render_passes->back()->quad_list;
+  QuadList* quad_list = &render_pass->quad_list;
   for (auto it = quad_list->begin(); it != quad_list->end(); ++it) {
     OverlayCandidate candidate;
     if (OverlayCandidate::FromDrawQuad(resource_provider, *it, &candidate) &&
diff --git a/cc/output/overlay_strategy_single_on_top.h b/cc/output/overlay_strategy_single_on_top.h
index 0613b89..c93ff95 100644
--- a/cc/output/overlay_strategy_single_on_top.h
+++ b/cc/output/overlay_strategy_single_on_top.h
@@ -19,7 +19,7 @@
   ~OverlayStrategySingleOnTop() override;
 
   bool Attempt(ResourceProvider* resource_provider,
-               RenderPassList* render_passes,
+               RenderPass* render_pass,
                OverlayCandidateList* candidate_list) override;
 
  private:
diff --git a/cc/output/overlay_strategy_underlay.cc b/cc/output/overlay_strategy_underlay.cc
index f9bb0391..2a67092 100644
--- a/cc/output/overlay_strategy_underlay.cc
+++ b/cc/output/overlay_strategy_underlay.cc
@@ -19,9 +19,9 @@
 OverlayStrategyUnderlay::~OverlayStrategyUnderlay() {}
 
 bool OverlayStrategyUnderlay::Attempt(ResourceProvider* resource_provider,
-                                      RenderPassList* render_passes,
+                                      RenderPass* render_pass,
                                       OverlayCandidateList* candidate_list) {
-  QuadList& quad_list = render_passes->back()->quad_list;
+  QuadList& quad_list = render_pass->quad_list;
   for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
     OverlayCandidate candidate;
     if (!OverlayCandidate::FromDrawQuad(resource_provider, *it, &candidate))
diff --git a/cc/output/overlay_strategy_underlay.h b/cc/output/overlay_strategy_underlay.h
index 806753bd..40cae04 100644
--- a/cc/output/overlay_strategy_underlay.h
+++ b/cc/output/overlay_strategy_underlay.h
@@ -24,7 +24,7 @@
   ~OverlayStrategyUnderlay() override;
 
   bool Attempt(ResourceProvider* resource_provider,
-               RenderPassList* render_passes,
+               RenderPass* render_pass,
                OverlayCandidateList* candidate_list) override;
 
  private:
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index bc5cf561..62dbfdd 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -403,19 +403,14 @@
   CreateFullscreenOpaqueQuad(resource_provider_.get(),
                              pass->shared_quad_state_list.back(), pass.get());
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
   // Check for potential candidates.
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-
-  ASSERT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
 
-  RenderPass* main_pass = pass_list.back().get();
+  RenderPass* main_pass = pass.get();
   // Check that the quad is gone.
   EXPECT_EQ(2U, main_pass->quad_list.size());
   const QuadList& quad_list = main_pass->quad_list;
@@ -442,9 +437,6 @@
   CreateFullscreenOpaqueQuad(resource_provider_.get(),
                              pass->shared_quad_state_list.back(), pass.get());
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
   // Check for potential candidates.
   OverlayCandidateList candidate_list;
 
@@ -456,7 +448,7 @@
   output_surface_plane.overlay_handled = true;
   candidate_list.push_back(output_surface_plane);
 
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
   DCHECK(damage_rect_.IsEmpty());
@@ -476,9 +468,9 @@
   RenderPass::CopyAll(pass_list, &original_pass_list);
 
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
-                                         &candidate_list, nullptr,
-                                         &damage_rect_);
+  overlay_processor_->ProcessForOverlays(
+      resource_provider_.get(), pass_list.back().get(), &candidate_list,
+      nullptr, &damage_rect_);
   EXPECT_EQ(0U, candidate_list.size());
   // There should be nothing new here.
   CompareRenderPassLists(pass_list, original_pass_list);
@@ -502,9 +494,9 @@
   RenderPass::CopyAll(pass_list, &original_pass_list);
 
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
-                                         &candidate_list, nullptr,
-                                         &damage_rect_);
+  overlay_processor_->ProcessForOverlays(
+      resource_provider_.get(), pass_list.back().get(), &candidate_list,
+      nullptr, &damage_rect_);
   EXPECT_EQ(0U, candidate_list.size());
   // There should be nothing new here.
   CompareRenderPassLists(pass_list, original_pass_list);
@@ -512,9 +504,6 @@
 
 // Test with multiple render passes.
 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
-  RenderPassList pass_list;
-  pass_list.push_back(CreateRenderPass());
-
   scoped_ptr<RenderPass> pass = CreateRenderPass();
   CreateFullscreenCandidateQuad(resource_provider_.get(),
                                 pass->shared_quad_state_list.back(),
@@ -526,20 +515,12 @@
   CreateFullscreenOpaqueQuad(resource_provider_.get(),
                              pass->shared_quad_state_list.back(), pass.get());
 
-  pass_list.push_back(std::move(pass));
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
   // Check for potential candidates.
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
   EXPECT_EQ(1U, candidate_list.size());
-
-  // This should be the same.
-  ASSERT_EQ(2U, pass_list.size());
 }
 
 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
@@ -550,13 +531,10 @@
                                     pass.get());
   quad->premultiplied_alpha = true;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -568,13 +546,10 @@
                                     pass.get());
   quad->needs_blending = true;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -586,13 +561,10 @@
                                     pass.get());
   quad->background_color = SK_ColorBLACK;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -603,13 +575,10 @@
                                 pass.get());
   pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -620,13 +589,10 @@
                                 pass.get());
   pass->shared_quad_state_list.back()->opacity = 0.5f;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -638,13 +604,10 @@
   pass->shared_quad_state_list.back()
       ->quad_to_target_transform.RotateAboutXAxis(45.f);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -656,13 +619,10 @@
   pass->shared_quad_state_list.back()->is_clipped = true;
   pass->shared_quad_state_list.back()->clip_rect = kOverlayClipRect;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -675,14 +635,10 @@
                         pass->shared_quad_state_list.back(), pass.get(), rect);
   pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
                                                                       -1.0f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL,
             candidate_list.back().transform);
@@ -698,13 +654,10 @@
   pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(-1.0f,
                                                                       2.0f);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL,
             candidate_list.back().transform);
@@ -718,14 +671,10 @@
                         pass->shared_quad_state_list.back(), pass.get(), rect);
   pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
                                                                       1.0f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -738,13 +687,10 @@
   pass->shared_quad_state_list.back()
       ->quad_to_target_transform.RotateAboutZAxis(90.f);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90, candidate_list.back().transform);
 }
@@ -758,13 +704,10 @@
   pass->shared_quad_state_list.back()
       ->quad_to_target_transform.RotateAboutZAxis(180.f);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180, candidate_list.back().transform);
 }
@@ -778,13 +721,10 @@
   pass->shared_quad_state_list.back()
       ->quad_to_target_transform.RotateAboutZAxis(270.f);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270, candidate_list.back().transform);
 }
@@ -799,17 +739,10 @@
                         pass.get(),
                         kOverlayBottomRightRect);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -824,17 +757,10 @@
   CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
                         kOverlayBottomRightRect);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -847,17 +773,10 @@
                         pass->shared_quad_state_list.back(), pass.get(),
                         kOverlayBottomRightRect);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -872,17 +791,10 @@
   CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
                         kOverlayBottomRightRect);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -895,17 +807,10 @@
   CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
                         kOverlayBottomRightRect);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -915,13 +820,10 @@
                                      pass->shared_quad_state_list.back(),
                                      pass.get(), kSwapTransform);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(0U, candidate_list.size());
 }
 
@@ -931,13 +833,10 @@
                                      pass->shared_quad_state_list.back(),
                                      pass.get(), kXMirrorTransform);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -947,13 +846,10 @@
                                      pass->shared_quad_state_list.back(),
                                      pass.get(), kBothMirrorTransform);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -963,13 +859,10 @@
                                      pass->shared_quad_state_list.back(),
                                      pass.get(), kNormalTransform);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -979,13 +872,10 @@
                                      pass->shared_quad_state_list.back(),
                                      pass.get(), kYMirrorTransform);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  ASSERT_EQ(1U, pass_list.size());
   EXPECT_EQ(1U, candidate_list.size());
 }
 
@@ -997,19 +887,15 @@
                         pass->shared_quad_state_list.back(), pass.get(),
                         kOverlayBottomRightRect);
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(-1, candidate_list[0].plane_z_order);
-  EXPECT_EQ(2U, pass_list[0]->quad_list.size());
+  EXPECT_EQ(2U, pass->quad_list.size());
   // The overlay quad should have changed to a SOLID_COLOR quad.
-  EXPECT_EQ(pass_list[0]->quad_list.back()->material, DrawQuad::SOLID_COLOR);
+  EXPECT_EQ(pass->quad_list.back()->material, DrawQuad::SOLID_COLOR);
 }
 
 TEST_F(UnderlayTest, AllowOnTop) {
@@ -1021,18 +907,14 @@
   CreateFullscreenOpaqueQuad(resource_provider_.get(),
                              pass->shared_quad_state_list.back(), pass.get());
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
-  EXPECT_EQ(1U, pass_list.size());
   ASSERT_EQ(1U, candidate_list.size());
   EXPECT_EQ(-1, candidate_list[0].plane_z_order);
   // The overlay quad should have changed to a SOLID_COLOR quad.
-  EXPECT_EQ(pass_list[0]->quad_list.front()->material, DrawQuad::SOLID_COLOR);
+  EXPECT_EQ(pass->quad_list.front()->material, DrawQuad::SOLID_COLOR);
 }
 
 // The first time an underlay is scheduled its damage must not be subtracted.
@@ -1044,11 +926,8 @@
 
   damage_rect_ = kOverlayRect;
 
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
-
   OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &candidate_list, nullptr,
                                          &damage_rect_);
 
@@ -1070,10 +949,8 @@
     CreateFullscreenOpaqueQuad(resource_provider_.get(),
                                pass->shared_quad_state_list.back(), pass.get());
 
-    RenderPassList pass_list;
-    pass_list.push_back(std::move(pass));
     OverlayCandidateList candidate_list;
-    overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+    overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                            &candidate_list, nullptr,
                                            &damage_rect_);
   }
@@ -1096,10 +973,8 @@
 
     damage_rect_ = overlay_rects[i];
 
-    RenderPassList pass_list;
-    pass_list.push_back(std::move(pass));
     OverlayCandidateList candidate_list;
-    overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+    overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                            &candidate_list, nullptr,
                                            &damage_rect_);
 
@@ -1119,10 +994,8 @@
 
     damage_rect_ = kOverlayRect;
 
-    RenderPassList pass_list;
-    pass_list.push_back(std::move(pass));
     OverlayCandidateList candidate_list;
-    overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+    overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                            &candidate_list, nullptr,
                                            &damage_rect_);
   }
@@ -1143,10 +1016,8 @@
 
     damage_rect_ = kOverlayBottomRightRect;
 
-    RenderPassList pass_list;
-    pass_list.push_back(std::move(pass));
     OverlayCandidateList candidate_list;
-    overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+    overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                            &candidate_list, nullptr,
                                            &damage_rect_);
   }
@@ -1175,16 +1046,12 @@
       ->quad_to_target_transform.RotateAboutZAxis(45.f);
 
   gfx::Rect damage_rect;
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   CALayerOverlayList ca_layer_list;
-  OverlayCandidateList overlay_list(
-      BackbufferOverlayList(pass_list.back().get()));
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  OverlayCandidateList overlay_list(BackbufferOverlayList(pass.get()));
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &overlay_list, &ca_layer_list,
                                          &damage_rect);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, pass_list.back()->quad_list.size());
+  EXPECT_EQ(0U, pass->quad_list.size());
   EXPECT_EQ(0U, overlay_list.size());
   EXPECT_EQ(1U, ca_layer_list.size());
   EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
@@ -1199,16 +1066,11 @@
       ->quad_to_target_transform.RotateAboutXAxis(45.f);
 
   gfx::Rect damage_rect;
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   CALayerOverlayList ca_layer_list;
-  OverlayCandidateList overlay_list(
-      BackbufferOverlayList(pass_list.back().get()));
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  OverlayCandidateList overlay_list(BackbufferOverlayList(pass.get()));
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &overlay_list, &ca_layer_list,
                                          &damage_rect);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, pass_list.back()->quad_list.size());
   EXPECT_EQ(0U, overlay_list.size());
   EXPECT_EQ(1U, ca_layer_list.size());
   gfx::Transform expected_transform;
@@ -1227,16 +1089,12 @@
   pass->shared_quad_state_list.back()->clip_rect = kOverlayRect;
 
   gfx::Rect damage_rect;
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   CALayerOverlayList ca_layer_list;
-  OverlayCandidateList overlay_list(
-      BackbufferOverlayList(pass_list.back().get()));
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  OverlayCandidateList overlay_list(BackbufferOverlayList(pass.get()));
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &overlay_list, &ca_layer_list,
                                          &damage_rect);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, pass_list.back()->quad_list.size());
+  EXPECT_EQ(0U, pass->quad_list.size());
   EXPECT_EQ(0U, overlay_list.size());
   EXPECT_EQ(1U, ca_layer_list.size());
   EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
@@ -1251,17 +1109,12 @@
   pass->shared_quad_state_list.back()->clip_rect = gfx::Rect(64, 64, 128, 128);
 
   gfx::Rect damage_rect;
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   CALayerOverlayList ca_layer_list;
-  OverlayCandidateList overlay_list(
-      BackbufferOverlayList(pass_list.back().get()));
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  OverlayCandidateList overlay_list(BackbufferOverlayList(pass.get()));
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &overlay_list, &ca_layer_list,
                                          &damage_rect);
-
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, pass_list.back()->quad_list.size());
+  EXPECT_EQ(0U, pass->quad_list.size());
   EXPECT_EQ(0U, overlay_list.size());
   EXPECT_EQ(1U, ca_layer_list.size());
   EXPECT_TRUE(ca_layer_list.back().is_clipped);
@@ -1277,16 +1130,12 @@
   pass->shared_quad_state_list.back()->opacity = 0;
 
   gfx::Rect damage_rect;
-  RenderPassList pass_list;
-  pass_list.push_back(std::move(pass));
   CALayerOverlayList ca_layer_list;
-  OverlayCandidateList overlay_list(
-      BackbufferOverlayList(pass_list.back().get()));
-  overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list,
+  OverlayCandidateList overlay_list(BackbufferOverlayList(pass.get()));
+  overlay_processor_->ProcessForOverlays(resource_provider_.get(), pass.get(),
                                          &overlay_list, &ca_layer_list,
                                          &damage_rect);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, pass_list.back()->quad_list.size());
+  EXPECT_EQ(0U, pass->quad_list.size());
   EXPECT_EQ(0U, overlay_list.size());
   EXPECT_EQ(0U, ca_layer_list.size());
   EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
diff --git a/cc/tiles/tile_draw_info.h b/cc/tiles/tile_draw_info.h
index 05596ba..6d694eb 100644
--- a/cc/tiles/tile_draw_info.h
+++ b/cc/tiles/tile_draw_info.h
@@ -73,6 +73,10 @@
 
   inline bool has_resource() const { return !!resource_; }
 
+  inline bool has_compressed_resource() const {
+    return resource_ ? IsResourceFormatCompressed(resource_->format()) : false;
+  }
+
   void SetSolidColorForTesting(SkColor color) { set_solid_color(color); }
 
   void AsValueInto(base::trace_event::TracedValue* state) const;
diff --git a/chrome/android/examples/partner_browser_customizations_provider/AndroidManifest.xml b/chrome/android/examples/partner_browser_customizations_provider/AndroidManifest.xml
index 5c261da..32eeac9c 100644
--- a/chrome/android/examples/partner_browser_customizations_provider/AndroidManifest.xml
+++ b/chrome/android/examples/partner_browser_customizations_provider/AndroidManifest.xml
@@ -4,11 +4,15 @@
      found in the LICENSE file. -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.partnerbrowsercustomizations.example">
+        package="org.chromium.example.partnercustomizations">
     <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />
     <application>
-        <!--android:authorities must remain as it is. -->
+        <!-- Provider for partner bookmarks. android:authorities must not be changed. -->
+        <provider android:name="PartnerBookmarksProviderExample"
+            android:authorities="com.android.partnerbookmarks" />
+
+        <!-- Provider for other partner customizations. android:authorities must not be changed. -->
         <provider android:name="PartnerBrowserCustomizationsProviderExample"
-                android:authorities="com.android.partnerbrowsercustomizations" />
+            android:authorities="com.android.partnerbrowsercustomizations" />
     </application>
 </manifest>
diff --git a/chrome/android/examples/partner_browser_customizations_provider/README b/chrome/android/examples/partner_browser_customizations_provider/README
index 5a68efcc..b1716dcd 100644
--- a/chrome/android/examples/partner_browser_customizations_provider/README
+++ b/chrome/android/examples/partner_browser_customizations_provider/README
@@ -1,3 +1,7 @@
+# An example app for partner customizations. When this APK is installed, Chrome
+# will show a homepage button and partner bookmarks, disable incognito mode, and
+# disable bookmark editing.
+
 # Remount /system/ as read-write.
 # < MNC instructions
   adb root && adb wait-for-device
@@ -17,11 +21,16 @@
 adb shell mkdir -p /system/app
 adb push bin/PartnerCustomizationProviderExample-debug.apk /system/app/ChromeCustomizations.apk
 
+# If you want partner bookmarks to work, delete the preinstalled partner
+# bookmarks provider (which typically provides zero bookmarks).
+adb shell rm -r /system/app/PartnerBookmarksProvider
+
+# To get partner bookmarks even when Chrome isn't preinstalled, remove the
+# ApplicationInfo.FLAG_SYSTEM check from PartnerBookmarksShim.java
+
 # Restart Java services to ensure dex caching.
 adb shell stop && adb shell start
 
 # Start Chrome.
 adb shell am start -S -n com.android.chrome/.Main
 
-# If it worked correctly, Chrome should enable homepage button, disable incognito mode and partner bookmark editing mode.
-
diff --git a/chrome/android/examples/partner_browser_customizations_provider/res/values/bookmarks_icons.xml b/chrome/android/examples/partner_browser_customizations_provider/res/values/bookmarks_icons.xml
new file mode 100644
index 0000000..8daf56d
--- /dev/null
+++ b/chrome/android/examples/partner_browser_customizations_provider/res/values/bookmarks_icons.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2016 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources>
+    <array name="bookmark_preloads" />
+</resources>
diff --git a/chrome/android/examples/partner_browser_customizations_provider/res/values/strings.xml b/chrome/android/examples/partner_browser_customizations_provider/res/values/strings.xml
new file mode 100644
index 0000000..b761b67
--- /dev/null
+++ b/chrome/android/examples/partner_browser_customizations_provider/res/values/strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2016 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources>
+    <string name="bookmarks_folder_name" translatable="false">Partner Bookmarks</string>
+    <string-array name="bookmarks">
+        <item>YouTube</item><item>http://youtube.com</item>
+        <item>Google Maps</item><item>http://maps.google.com</item>
+        <item>Example</item><item>http://example.com</item>
+    </string-array>
+</resources>
+
diff --git a/chrome/android/examples/partner_browser_customizations_provider/src/org/chromium/example/partnercustomizations/PartnerBookmarksProviderExample.java b/chrome/android/examples/partner_browser_customizations_provider/src/org/chromium/example/partnercustomizations/PartnerBookmarksProviderExample.java
new file mode 100644
index 0000000..86eb627
--- /dev/null
+++ b/chrome/android/examples/partner_browser_customizations_provider/src/org/chromium/example/partnercustomizations/PartnerBookmarksProviderExample.java
@@ -0,0 +1,579 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.example.partnercustomizations;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.UriMatcher;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.MatrixCursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Default partner bookmarks provider implementation of {@link PartnerBookmarksContract} API.
+ * It reads the flat list of bookmarks and the name of the root partner
+ * bookmarks folder using getResources() API.
+ *
+ * Sample resources structure:
+ *     res/
+ *         values/
+ *             strings.xml
+ *                  string name="bookmarks_folder_name"
+ *                  string-array name="bookmarks"
+ *                      item TITLE1
+ *                      item URL1
+ *                      item TITLE2
+ *                      item URL2...
+ *             bookmarks_icons.xml
+ *                  array name="bookmark_preloads"
+ *                      item @raw/favicon1
+ *                      item @raw/touchicon1
+ *                      item @raw/favicon2
+ *                      item @raw/touchicon2
+ *                      ...
+ */
+public class PartnerBookmarksProviderExample extends ContentProvider {
+    private static final String TAG = "PartnerBookmarksProviderExample";
+
+    // URI matcher
+    private static final int URI_MATCH_BOOKMARKS = 1000;
+    private static final int URI_MATCH_BOOKMARKS_ID = 1001;
+    private static final int URI_MATCH_BOOKMARKS_FOLDER = 1002;
+    private static final int URI_MATCH_BOOKMARKS_FOLDER_ID = 1003;
+    private static final int URI_MATCH_BOOKMARKS_PARTNER_BOOKMARKS_FOLDER_ID = 1004;
+
+    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+    private static final Map<String, String> BOOKMARKS_PROJECTION_MAP =
+            new HashMap<String, String>();
+
+    // Default sort order for unsync'd bookmarks
+    private static final String DEFAULT_BOOKMARKS_SORT_ORDER =
+            PartnerBookmarksContract.Bookmarks.ID + " DESC, "
+            + PartnerBookmarksContract.Bookmarks.ID + " ASC";
+
+    // Initial bookmark id when for getResources() importing
+    // Make sure to fix tests if you are changing this
+    private static final long FIXED_ID_PARTNER_BOOKMARKS_ROOT =
+            PartnerBookmarksContract.Bookmarks.BOOKMARK_PARENT_ROOT_ID + 1;
+
+    // DB table name
+    private static final String TABLE_BOOKMARKS = "bookmarks";
+
+    static {
+        final UriMatcher matcher = URI_MATCHER;
+        final String authority = PartnerBookmarksContract.AUTHORITY;
+        matcher.addURI(authority, "bookmarks", URI_MATCH_BOOKMARKS);
+        matcher.addURI(authority, "bookmarks/#", URI_MATCH_BOOKMARKS_ID);
+        matcher.addURI(authority, "bookmarks/folder", URI_MATCH_BOOKMARKS_FOLDER);
+        matcher.addURI(authority, "bookmarks/folder/#", URI_MATCH_BOOKMARKS_FOLDER_ID);
+        matcher.addURI(authority, "bookmarks/folder/id",
+                URI_MATCH_BOOKMARKS_PARTNER_BOOKMARKS_FOLDER_ID);
+        // Projection maps
+        Map<String, String> map = BOOKMARKS_PROJECTION_MAP;
+        map.put(PartnerBookmarksContract.Bookmarks.ID,
+                PartnerBookmarksContract.Bookmarks.ID);
+        map.put(PartnerBookmarksContract.Bookmarks.TITLE,
+                PartnerBookmarksContract.Bookmarks.TITLE);
+        map.put(PartnerBookmarksContract.Bookmarks.URL,
+                PartnerBookmarksContract.Bookmarks.URL);
+        map.put(PartnerBookmarksContract.Bookmarks.TYPE,
+                PartnerBookmarksContract.Bookmarks.TYPE);
+        map.put(PartnerBookmarksContract.Bookmarks.PARENT,
+                PartnerBookmarksContract.Bookmarks.PARENT);
+        map.put(PartnerBookmarksContract.Bookmarks.FAVICON,
+                PartnerBookmarksContract.Bookmarks.FAVICON);
+        map.put(PartnerBookmarksContract.Bookmarks.TOUCHICON,
+                PartnerBookmarksContract.Bookmarks.TOUCHICON);
+    }
+
+    private final class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String DATABASE_FILENAME = "partnerBookmarks.db";
+        private static final int DATABASE_VERSION = 1;
+        private static final String PREFERENCES_FILENAME = "pbppref";
+        private static final String ACTIVE_CONFIGURATION_PREFNAME = "config";
+        private final SharedPreferences mSharedPreferences;
+
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_FILENAME, null, DATABASE_VERSION);
+            mSharedPreferences = context.getSharedPreferences(
+                    PREFERENCES_FILENAME, Context.MODE_PRIVATE);
+        }
+
+        private String getConfigSignature(Configuration config) {
+            return "mmc=" + Integer.toString(config.mcc)
+                    + "-mnc=" + Integer.toString(config.mnc)
+                    + "-loc=" + config.locale.toString();
+        }
+
+        public synchronized void prepareForConfiguration(Configuration config) {
+            final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            String newSignature = getConfigSignature(config);
+            String activeSignature =
+                    mSharedPreferences.getString(ACTIVE_CONFIGURATION_PREFNAME, null);
+            if (activeSignature == null || !activeSignature.equals(newSignature)) {
+                db.delete(TABLE_BOOKMARKS, null, null);
+                if (!createDefaultBookmarks(db)) {
+                    // Failure to read/insert bookmarks should be treated as "no bookmarks"
+                    db.delete(TABLE_BOOKMARKS, null, null);
+                }
+            }
+        }
+
+        private void setActiveConfiguration(Configuration config) {
+            Editor editor = mSharedPreferences.edit();
+            editor.putString(ACTIVE_CONFIGURATION_PREFNAME, getConfigSignature(config));
+            editor.apply();
+        }
+
+        private void createTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE_BOOKMARKS + "("
+                    + PartnerBookmarksContract.Bookmarks.ID
+                    + " INTEGER NOT NULL DEFAULT 0,"
+                    + PartnerBookmarksContract.Bookmarks.TITLE
+                    + " TEXT,"
+                    + PartnerBookmarksContract.Bookmarks.URL
+                    + " TEXT,"
+                    + PartnerBookmarksContract.Bookmarks.TYPE
+                    + " INTEGER NOT NULL DEFAULT 0,"
+                    + PartnerBookmarksContract.Bookmarks.PARENT
+                    + " INTEGER,"
+                    + PartnerBookmarksContract.Bookmarks.FAVICON
+                    + " BLOB,"
+                    + PartnerBookmarksContract.Bookmarks.TOUCHICON
+                    + " BLOB" + ");");
+        }
+
+        private void dropTable(SQLiteDatabase db) {
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKS);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            synchronized (this) {
+                createTable(db);
+                if (!createDefaultBookmarks(db)) {
+                    // Failure to read/insert bookmarks should be treated as "no bookmarks"
+                    dropTable(db);
+                    createTable(db);
+                }
+            }
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            dropTable(db);
+            onCreate(db);
+        }
+
+        @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            dropTable(db);
+            onCreate(db);
+        }
+
+        private boolean createDefaultBookmarks(SQLiteDatabase db) {
+            Resources res = getContext().getResources();
+            try {
+                CharSequence bookmarksFolderName = res.getText(R.string.bookmarks_folder_name);
+                final CharSequence[] bookmarks = res.getTextArray(R.array.bookmarks);
+                if (bookmarks.length >= 1) {
+                    if (bookmarksFolderName.length() < 1) {
+                        Log.i(TAG, "bookmarks_folder_name was not specified; bailing out");
+                        return false;
+                    }
+                    if (!addRootFolder(db,
+                            FIXED_ID_PARTNER_BOOKMARKS_ROOT, bookmarksFolderName.toString())) {
+                        Log.i(TAG, "failed to insert root folder; bailing out");
+                        return false;
+                    }
+                    if (!addDefaultBookmarks(db,
+                            FIXED_ID_PARTNER_BOOKMARKS_ROOT, FIXED_ID_PARTNER_BOOKMARKS_ROOT + 1)) {
+                        Log.i(TAG, "failed to insert bookmarks; bailing out");
+                        return false;
+                    }
+                }
+                setActiveConfiguration(res.getConfiguration());
+            } catch (android.content.res.Resources.NotFoundException e) {
+                Log.i(TAG, "failed to fetch resources; bailing out");
+                return false;
+            }
+            return true;
+        }
+
+        private boolean addRootFolder(SQLiteDatabase db, long id, String bookmarksFolderName) {
+            ContentValues values = new ContentValues();
+            values.put(PartnerBookmarksContract.Bookmarks.ID, id);
+            values.put(PartnerBookmarksContract.Bookmarks.TITLE,
+                    bookmarksFolderName);
+            values.put(PartnerBookmarksContract.Bookmarks.PARENT,
+                    PartnerBookmarksContract.Bookmarks.BOOKMARK_PARENT_ROOT_ID);
+            values.put(PartnerBookmarksContract.Bookmarks.TYPE,
+                    PartnerBookmarksContract.Bookmarks.BOOKMARK_TYPE_FOLDER);
+            return db.insertOrThrow(TABLE_BOOKMARKS, null, values) != -1;
+        }
+
+        private boolean addDefaultBookmarks(SQLiteDatabase db, long parentId,
+                long firstBookmarkId) {
+            long bookmarkId = firstBookmarkId;
+            Resources res = getContext().getResources();
+            final CharSequence[] bookmarks = res.getTextArray(R.array.bookmarks);
+            int size = bookmarks.length;
+            TypedArray preloads = res.obtainTypedArray(R.array.bookmark_preloads);
+            DatabaseUtils.InsertHelper insertHelper = null;
+            try {
+                insertHelper = new DatabaseUtils.InsertHelper(db, TABLE_BOOKMARKS);
+                final int idColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.ID);
+                final int titleColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.TITLE);
+                final int urlColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.URL);
+                final int typeColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.TYPE);
+                final int parentColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.PARENT);
+                final int faviconColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.FAVICON);
+                final int touchiconColumn = insertHelper.getColumnIndex(
+                        PartnerBookmarksContract.Bookmarks.TOUCHICON);
+
+                for (int i = 0; i + 1 < size; i = i + 2) {
+                    CharSequence bookmarkDestination = bookmarks[i + 1];
+
+                    String bookmarkTitle = bookmarks[i].toString();
+                    String bookmarkUrl = bookmarkDestination.toString();
+                    byte[] favicon = null;
+                    if (i < preloads.length()) {
+                        int faviconId = preloads.getResourceId(i, 0);
+                        try {
+                            favicon = readRaw(res, faviconId);
+                        } catch (IOException e) {
+                            Log.i(TAG, "Failed to read favicon for " + bookmarkTitle, e);
+                        }
+                    }
+                    byte[] touchicon = null;
+                    if (i + 1 < preloads.length()) {
+                        int touchiconId = preloads.getResourceId(i + 1, 0);
+                        try {
+                            touchicon = readRaw(res, touchiconId);
+                        } catch (IOException e) {
+                            Log.i(TAG, "Failed to read touchicon for " + bookmarkTitle, e);
+                        }
+                    }
+                    insertHelper.prepareForInsert();
+                    insertHelper.bind(idColumn, bookmarkId);
+                    insertHelper.bind(titleColumn, bookmarkTitle);
+                    insertHelper.bind(urlColumn, bookmarkUrl);
+                    insertHelper.bind(typeColumn,
+                            PartnerBookmarksContract.Bookmarks.BOOKMARK_TYPE_BOOKMARK);
+                    insertHelper.bind(parentColumn, parentId);
+                    if (favicon != null) {
+                        insertHelper.bind(faviconColumn, favicon);
+                    }
+                    if (touchicon != null) {
+                        insertHelper.bind(touchiconColumn, touchicon);
+                    }
+                    bookmarkId++;
+                    if (insertHelper.execute() == -1) {
+                        Log.i(TAG, "Failed to insert bookmark " + bookmarkTitle);
+                        return false;
+                    }
+                }
+            } finally {
+                preloads.recycle();
+                insertHelper.close();
+            }
+            return true;
+        }
+
+        private byte[] readRaw(Resources res, int id) throws IOException {
+            if (id == 0) return null;
+            InputStream is = res.openRawResource(id);
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            try {
+                byte[] buf = new byte[4096];
+                int read;
+                while ((read = is.read(buf)) > 0) {
+                    bos.write(buf, 0, read);
+                }
+                bos.flush();
+                return bos.toByteArray();
+            } finally {
+                is.close();
+                bos.close();
+            }
+        }
+    }
+
+    private DatabaseHelper mOpenHelper;
+
+    @Override
+    public boolean onCreate() {
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        mOpenHelper.prepareForConfiguration(getContext().getResources().getConfiguration());
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder) {
+        final int match = URI_MATCHER.match(uri);
+        mOpenHelper.prepareForConfiguration(getContext().getResources().getConfiguration());
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        String limit = uri.getQueryParameter(PartnerBookmarksContract.PARAM_LIMIT);
+        String groupBy = uri.getQueryParameter(PartnerBookmarksContract.PARAM_GROUP_BY);
+        switch (match) {
+            case URI_MATCH_BOOKMARKS_FOLDER_ID:
+            case URI_MATCH_BOOKMARKS_ID:
+            case URI_MATCH_BOOKMARKS: {
+                if (match == URI_MATCH_BOOKMARKS_ID) {
+                    // Tack on the ID of the specific bookmark requested
+                    selection = DatabaseUtils.concatenateWhere(selection,
+                            TABLE_BOOKMARKS + "."
+                            + PartnerBookmarksContract.Bookmarks.ID + "=?");
+                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                            new String[] { Long.toString(ContentUris.parseId(uri)) });
+                } else if (match == URI_MATCH_BOOKMARKS_FOLDER_ID) {
+                    // Tack on the ID of the specific folder requested
+                    selection = DatabaseUtils.concatenateWhere(selection,
+                            TABLE_BOOKMARKS + "."
+                            + PartnerBookmarksContract.Bookmarks.PARENT + "=?");
+                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                            new String[] { Long.toString(ContentUris.parseId(uri)) });
+                }
+                // Set a default sort order if one isn't specified
+                if (TextUtils.isEmpty(sortOrder)) {
+                    sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER;
+                }
+                qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
+                qb.setTables(TABLE_BOOKMARKS);
+                break;
+            }
+
+            case URI_MATCH_BOOKMARKS_FOLDER: {
+                qb.setTables(TABLE_BOOKMARKS);
+                String[] args;
+                String query;
+                // Set a default sort order if one isn't specified
+                if (TextUtils.isEmpty(sortOrder)) {
+                    sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER;
+                }
+                qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
+                String where = PartnerBookmarksContract.Bookmarks.PARENT + "=?";
+                where = DatabaseUtils.concatenateWhere(where, selection);
+                args = new String[] { Long.toString(FIXED_ID_PARTNER_BOOKMARKS_ROOT) };
+                if (selectionArgs != null) {
+                    args = DatabaseUtils.appendSelectionArgs(args, selectionArgs);
+                }
+                query = qb.buildQuery(projection, where, null, null, sortOrder, null);
+                Cursor cursor = db.rawQuery(query, args);
+                return cursor;
+            }
+
+            case URI_MATCH_BOOKMARKS_PARTNER_BOOKMARKS_FOLDER_ID: {
+                MatrixCursor c = new MatrixCursor(
+                        new String[] {PartnerBookmarksContract.Bookmarks.ID});
+                c.newRow().add(FIXED_ID_PARTNER_BOOKMARKS_ROOT);
+                return c;
+            }
+
+            default: {
+                throw new UnsupportedOperationException("Unknown URL " + uri.toString());
+            }
+        }
+
+        return qb.query(db, projection, selection, selectionArgs, groupBy, null, sortOrder, limit);
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        final int match = URI_MATCHER.match(uri);
+        if (match == UriMatcher.NO_MATCH) return null;
+        return PartnerBookmarksContract.Bookmarks.CONTENT_ITEM_TYPE;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * <p>
+     * The contract between the partner bookmarks provider and applications.
+     * Contains the definition for the supported URIs and columns.
+     * </p>
+     * <p>
+     * Authority URI: content://com.android.partnerbookmarks
+     * </p>
+     * <p>
+     * Partner bookmarks URI: content://com.android.partnerbookmarks/bookmarks
+     * </p>
+     * <p>
+     * If the provider is found, and the set of bookmarks is non-empty, exactly one
+     * top-level folder with “parent” set to {@link #BOOKMARK_PARENT_ROOT_ID}
+     * shall be provided; more than one bookmark with “parent” set to
+     * {@link #BOOKMARK_PARENT_ROOT_ID} will cause the import to fail.
+     * </p>
+     */
+    public static class PartnerBookmarksContract {
+        /** The authority for the partner bookmarks provider */
+        public static final String AUTHORITY = "com.android.partnerbookmarks";
+
+        /** A content:// style uri to the authority for the partner bookmarks provider */
+        public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+
+        /**
+         * A parameter for use when querying any table that allows specifying
+         * a limit on the number of rows returned.
+         */
+        public static final String PARAM_LIMIT = "limit";
+
+        /**
+         * A parameter for use when querying any table that allows specifying
+         * grouping of the rows returned.
+         */
+        public static final String PARAM_GROUP_BY = "groupBy";
+
+        /**
+         * The bookmarks table, which holds the partner bookmarks.
+         */
+        public static final class Bookmarks {
+            /**
+             * This utility class cannot be instantiated.
+             */
+            private Bookmarks() {}
+
+            /**
+             * The content:// style URI for this table
+             */
+            public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "bookmarks");
+
+            /**
+             * The content:// style URI for the root partner bookmarks folder
+             */
+            public static final Uri CONTENT_URI_PARTNER_BOOKMARKS_FOLDER =
+                    Uri.withAppendedPath(CONTENT_URI, "folder");
+
+            /**
+             * Builds a URI that points to a specific folder.
+             * @param folderId the ID of the folder to point to
+             */
+            public static final Uri buildFolderUri(long folderId) {
+                return ContentUris.withAppendedId(CONTENT_URI_PARTNER_BOOKMARKS_FOLDER, folderId);
+            }
+
+            /**
+             * The MIME type of {@link #CONTENT_URI} providing a directory of bookmarks.
+             */
+            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/partnerbookmark";
+
+            /**
+             * The MIME type of a {@link #CONTENT_URI} of a single bookmark.
+             */
+            public static final String CONTENT_ITEM_TYPE =
+                    "vnd.android.cursor.item/partnerbookmark";
+
+            /**
+             * Used in {@link #TYPE} column and indicates the row is a bookmark.
+             */
+            public static final int BOOKMARK_TYPE_BOOKMARK = 1;
+
+            /**
+             * Used in {@link #TYPE} column and indicates the row is a folder.
+             */
+            public static final int BOOKMARK_TYPE_FOLDER = 2;
+
+            /**
+             * Used in {@link #PARENT} column and indicates the row doesn't have a parent.
+             */
+            public static final int BOOKMARK_PARENT_ROOT_ID = 0;
+
+            /**
+             * The type of the item.
+             * <p>Type: INTEGER</p>
+             * <p>Allowed values are:</p>
+             * <p>
+             * <ul>
+             * <li>{@link #BOOKMARK_TYPE_BOOKMARK}</li>
+             * <li>{@link #BOOKMARK_TYPE_FOLDER}</li>
+             * </ul>
+             * </p>
+             */
+            public static final String TYPE = "type";
+
+            /**
+             * The unique ID for a row.  Cannot be BOOKMARK_PARENT_ROOT_ID.
+             * <p>Type: INTEGER (long)</p>
+             */
+            public static final String ID = "_id";
+
+            /**
+             * This column is valid when the row is not a folder.
+             * <p>Type: TEXT (URL)</p>
+             */
+            public static final String URL = "url";
+
+            /**
+             * The user visible title.
+             * <p>Type: TEXT</p>
+             */
+            public static final String TITLE = "title";
+
+            /**
+             * The favicon of the bookmark, may be NULL.
+             * Must decode via {@link BitmapFactory#decodeByteArray}.
+             * <p>Type: BLOB (image)</p>
+             */
+            public static final String FAVICON = "favicon";
+
+            /**
+             * The touch icon for the web page, may be NULL.
+             * Must decode via {@link BitmapFactory#decodeByteArray}.
+             * <p>Type: BLOB (image)</p>
+             */
+            public static final String TOUCHICON = "touchicon";
+
+            /**
+             * The ID of the parent folder. BOOKMARK_PARENT_ROOT_ID is the root folder.
+             * <p>Type: INTEGER (long) (reference to item in the same table)</p>
+             */
+            public static final String PARENT = "parent";
+        }
+    }
+}
diff --git a/chrome/android/examples/partner_browser_customizations_provider/src/com/android/partnerbrowsercustomizations/example/PartnerBrowserCustomizationsProviderExample.java b/chrome/android/examples/partner_browser_customizations_provider/src/org/chromium/example/partnercustomizations/PartnerBrowserCustomizationsProviderExample.java
similarity index 98%
rename from chrome/android/examples/partner_browser_customizations_provider/src/com/android/partnerbrowsercustomizations/example/PartnerBrowserCustomizationsProviderExample.java
rename to chrome/android/examples/partner_browser_customizations_provider/src/org/chromium/example/partnercustomizations/PartnerBrowserCustomizationsProviderExample.java
index 324a260..8919570e 100644
--- a/chrome/android/examples/partner_browser_customizations_provider/src/com/android/partnerbrowsercustomizations/example/PartnerBrowserCustomizationsProviderExample.java
+++ b/chrome/android/examples/partner_browser_customizations_provider/src/org/chromium/example/partnercustomizations/PartnerBrowserCustomizationsProviderExample.java
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 // Package path can be changed, but should match <manifest package="..."> in AndroidManifest.xml.
-package com.android.partnerbrowsercustomizations.example;
+package org.chromium.example.partnercustomizations;
 
 import android.content.ContentProvider;
 import android.content.ContentValues;
diff --git a/chrome/android/java/res/drawable-hdpi/offline_bolt.png b/chrome/android/java/res/drawable-hdpi/offline_bolt.png
index 7fda6ae..f5ca4e3 100644
--- a/chrome/android/java/res/drawable-hdpi/offline_bolt.png
+++ b/chrome/android/java/res/drawable-hdpi/offline_bolt.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/offline_bolt_light.png b/chrome/android/java/res/drawable-hdpi/offline_bolt_light.png
deleted file mode 100644
index 2b8ac85..0000000
--- a/chrome/android/java/res/drawable-hdpi/offline_bolt_light.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/offline_bolt.png b/chrome/android/java/res/drawable-mdpi/offline_bolt.png
index 49e7778..1029720 100644
--- a/chrome/android/java/res/drawable-mdpi/offline_bolt.png
+++ b/chrome/android/java/res/drawable-mdpi/offline_bolt.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/offline_bolt_light.png b/chrome/android/java/res/drawable-mdpi/offline_bolt_light.png
deleted file mode 100644
index ff582c6..0000000
--- a/chrome/android/java/res/drawable-mdpi/offline_bolt_light.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/offline_bolt.png b/chrome/android/java/res/drawable-xhdpi/offline_bolt.png
index 2f3cd79..804bccf 100644
--- a/chrome/android/java/res/drawable-xhdpi/offline_bolt.png
+++ b/chrome/android/java/res/drawable-xhdpi/offline_bolt.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/offline_bolt_light.png b/chrome/android/java/res/drawable-xhdpi/offline_bolt_light.png
deleted file mode 100644
index b48db80..0000000
--- a/chrome/android/java/res/drawable-xhdpi/offline_bolt_light.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/offline_bolt.png b/chrome/android/java/res/drawable-xxhdpi/offline_bolt.png
index 3c01228..c8058710 100644
--- a/chrome/android/java/res/drawable-xxhdpi/offline_bolt.png
+++ b/chrome/android/java/res/drawable-xxhdpi/offline_bolt.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/offline_bolt_light.png b/chrome/android/java/res/drawable-xxhdpi/offline_bolt_light.png
deleted file mode 100644
index cf9b0d6..0000000
--- a/chrome/android/java/res/drawable-xxhdpi/offline_bolt_light.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/offline_bolt.png b/chrome/android/java/res/drawable-xxxhdpi/offline_bolt.png
index a40ec568..ce62357a 100644
--- a/chrome/android/java/res/drawable-xxxhdpi/offline_bolt.png
+++ b/chrome/android/java/res/drawable-xxxhdpi/offline_bolt.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/offline_bolt_light.png b/chrome/android/java/res/drawable-xxxhdpi/offline_bolt_light.png
deleted file mode 100644
index 2c6c38a..0000000
--- a/chrome/android/java/res/drawable-xxxhdpi/offline_bolt_light.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/layout/location_bar_status.xml b/chrome/android/java/res/layout/location_bar_status.xml
index 2b5271a..549b158 100644
--- a/chrome/android/java/res/layout/location_bar_status.xml
+++ b/chrome/android/java/res/layout/location_bar_status.xml
@@ -13,7 +13,7 @@
         android:gravity="center_vertical"
         android:textAlignment="viewStart"
         android:textAppearance="@android:style/TextAppearance.Medium"
-        android:textColor="@color/locationbar_verbose_status_color"
+        android:textColor="@color/locationbar_status_color"
         android:textSize="@dimen/location_bar_url_text_size"
         android:text="@string/location_bar_verbose_status_offline"
         android:visibility="gone" />
diff --git a/chrome/android/java/res/layout/physical_web_diagnostics.xml b/chrome/android/java/res/layout/physical_web_diagnostics.xml
index 5f2aebc..005e9132 100644
--- a/chrome/android/java/res/layout/physical_web_diagnostics.xml
+++ b/chrome/android/java/res/layout/physical_web_diagnostics.xml
@@ -8,6 +8,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:paddingTop="@dimen/toolbar_height_no_shadow"
+    android:background="@color/ntp_bg"
     android:focusable="true"
     android:focusableInTouchMode="true" >
 
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml
index ed9e9b6..d7075bab 100644
--- a/chrome/android/java/res/values/colors.xml
+++ b/chrome/android/java/res/values/colors.xml
@@ -118,10 +118,10 @@
     <!-- LocationBar colors -->
     <color name="locationbar_light_hint_text">#80ffffff</color>
     <color name="locationbar_light_selection_color">#cc5595fe</color>
-    <color name="locationbar_verbose_status_color">#8a000000</color>
-    <color name="locationbar_light_verbose_status_color">#b3ffffff</color>
-    <color name="locationbar_status_separator_color">#1f000000</color>
-    <color name="locationbar_light_status_separator_color">#26ffffff</color>
+    <color name="locationbar_status_color">@color/light_normal_color</color>
+    <color name="locationbar_status_color_light">#ffffff</color>
+    <color name="locationbar_status_separator_color">#3d000000</color>
+    <color name="locationbar_status_separator_color_light">#3dffffff</color>
 
     <!-- Find in Page colors -->
     <color name="find_result_bar_background_color">#bfffffff</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBookmarkRow.java
index 84d5d996..7a17f6f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBookmarkRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBookmarkRow.java
@@ -18,6 +18,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback;
+import org.chromium.chrome.browser.offlinepages.ClientId;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
 import org.chromium.chrome.browser.widget.RoundedIconGenerator;
@@ -90,7 +91,8 @@
         OfflinePageItem offlinePage = null;
         OfflinePageBridge bridge = mDelegate.getModel().getOfflinePageBridge();
         if (mDelegate.getCurrentState() == BookmarkUIState.STATE_FILTER && bridge != null) {
-            offlinePage = bridge.getPageByBookmarkId(bookmarkId);
+            offlinePage =
+                    bridge.getPageByClientId(ClientId.createClientIdForBookmarkId(bookmarkId));
         }
         TextView textView = (TextView) findViewById(R.id.offline_page_size);
         View bookmarkRowView = findViewById(R.id.bookmark_row);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
index 3f40894..d341cbc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
@@ -20,6 +20,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
+import org.chromium.chrome.browser.offlinepages.ClientId;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.DeletePageCallback;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver;
@@ -119,7 +120,8 @@
 
             mOfflinePageModelObserver = new OfflinePageModelObserver() {
                 @Override
-                public void offlinePageDeleted(BookmarkId bookmarkId) {
+                public void offlinePageDeleted(long offlineId, ClientId clientId) {
+                    BookmarkId bookmarkId = BookmarkModel.getBookmarkIdForOfflineClientId(clientId);
                     if (mBookmarkId.equals(bookmarkId)) {
                         updateOfflineSection();
                     }
@@ -199,9 +201,9 @@
                     && mModel.getBookmarkById(mBookmarkId).isUrlEditable()) {
                 String fixedUrl = UrlUtilities.fixupUrl(url);
                 if (fixedUrl != null && !fixedUrl.equals(originalUrl)) {
+                    ClientId clientId = ClientId.createClientIdForBookmarkId(mBookmarkId);
                     boolean hasOfflinePage = OfflinePageBridge.isEnabled()
-                            && mModel.getOfflinePageBridge()
-                                    .getPageByBookmarkId(mBookmarkId) != null;
+                            && mModel.getOfflinePageBridge().getPageByClientId(clientId) != null;
                     RecordHistogram.recordBooleanHistogram(
                             "OfflinePages.Edit.BookmarkUrlChangedForOfflinePage", hasOfflinePage);
                     mModel.setBookmarkUrl(mBookmarkId, fixedUrl);
@@ -243,7 +245,8 @@
         Button saveRemoveVisitButton = (Button) findViewById(R.id.offline_page_save_remove_button);
         TextView offlinePageInfoTextView = (TextView) findViewById(R.id.offline_page_info_text);
 
-        OfflinePageItem offlinePage = offlinePageBridge.getPageByBookmarkId(mBookmarkId);
+        ClientId clientId = ClientId.createClientIdForBookmarkId(mBookmarkId);
+        OfflinePageItem offlinePage = offlinePageBridge.getPageByClientId(clientId);
         if (offlinePage != null) {
             // Offline page exists. Show information and button to remove.
             offlinePageInfoTextView.setText(
@@ -280,15 +283,15 @@
             @Override
             public void onClick(View v) {
                 recordOfflineButtonAction(true);
-                mModel.getOfflinePageBridge().deletePage(
-                        mBookmarkId, new DeletePageCallback() {
-                            @Override
-                            public void onDeletePageDone(int deletePageResult) {
-                                // TODO(fgorski): Add snackbar upon failure.
-                                // Always update UI, as buttons might be disabled.
-                                updateOfflineSection();
-                            }
-                        });
+                ClientId clientId = ClientId.createClientIdForBookmarkId(mBookmarkId);
+                mModel.getOfflinePageBridge().deletePage(clientId, new DeletePageCallback() {
+                    @Override
+                    public void onDeletePageDone(int deletePageResult) {
+                        // TODO(fgorski): Add snackbar upon failure.
+                        // Always update UI, as buttons might be disabled.
+                        updateOfflineSection();
+                    }
+                });
                 button.setClickable(false);
             }
         });
@@ -301,8 +304,9 @@
             @Override
             public void onClick(View v) {
                 recordOfflineButtonAction(true);
+                ClientId clientId = ClientId.createClientIdForBookmarkId(mBookmarkId);
                 mModel.getOfflinePageBridge().savePage(
-                        mWebContents, mBookmarkId, new SavePageCallback() {
+                        mWebContents, clientId, new SavePageCallback() {
                             @Override
                             public void onSavePageDone(
                                     int savePageResult, String url, long offlineId) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
index 9f89b12..313fff87 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.bookmarks.BookmarkPromoHeader.PromoHeaderShowingChangeListener;
+import org.chromium.chrome.browser.offlinepages.ClientId;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver;
 import org.chromium.chrome.browser.offlinepages.OfflinePageFreeUpSpaceCallback;
@@ -282,9 +283,10 @@
                 }
 
                 @Override
-                public void offlinePageDeleted(BookmarkId bookmarkId) {
+                public void offlinePageDeleted(long offlineId, ClientId clientId) {
                     if (mDelegate.getCurrentState() == BookmarkUIState.STATE_FILTER) {
-                        int deletedPosition = getPositionForBookmark(bookmarkId);
+                        BookmarkId id = BookmarkModel.getBookmarkIdForOfflineClientId(clientId);
+                        int deletedPosition = getPositionForBookmark(id);
                         if (deletedPosition >= 0) {
                             removeItem(deletedPosition);
                         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
index 43e77768..f231e750 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
@@ -7,6 +7,7 @@
 import org.chromium.base.ObserverList;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.offlinepages.ClientId;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.SavePageCallback;
@@ -233,7 +234,8 @@
         if (mOfflinePageBridge != null) {
             RecordHistogram.recordBooleanHistogram("OfflinePages.IncognitoSave",
                     webContents.isIncognito());
-            mOfflinePageBridge.savePage(webContents, bookmarkId, new SavePageCallback() {
+            ClientId clientId = ClientId.createClientIdForBookmarkId(bookmarkId);
+            mOfflinePageBridge.savePage(webContents, clientId, new SavePageCallback() {
                 @Override
                 public void onSavePageDone(int savePageResult, String url, long offlineId) {
                     int saveResult;
@@ -268,8 +270,9 @@
         String url = getBookmarkById(bookmarkId).getUrl();
         if (mOfflinePageBridge == null) return url;
 
+        ClientId clientId = ClientId.createClientIdForBookmarkId(bookmarkId);
         return mOfflinePageBridge.getLaunchUrlAndMarkAccessed(
-                mOfflinePageBridge.getPageByBookmarkId(bookmarkId), url);
+                mOfflinePageBridge.getPageByClientId(clientId), url);
     }
 
     /**
@@ -299,8 +302,9 @@
 
         List<BookmarkId> bookmarkIds = new ArrayList<BookmarkId>();
         for (OfflinePageItem offlinePage : offlinePages) {
-            if (existingBookmarks.contains(offlinePage.getBookmarkId())) {
-                bookmarkIds.add(offlinePage.getBookmarkId());
+            BookmarkId bookmarkId = getBookmarkIdForOfflineClientId(offlinePage.getClientId());
+            if (existingBookmarks.contains(bookmarkId)) {
+                bookmarkIds.add(bookmarkId);
             }
         }
         return bookmarkIds;
@@ -312,4 +316,15 @@
     public OfflinePageBridge getOfflinePageBridge() {
         return mOfflinePageBridge;
     }
+
+    /**
+     * @param id The client id to convert.
+     * @return The bookmark id contained in the specified client id.
+     */
+    public static BookmarkId getBookmarkIdForOfflineClientId(ClientId id) {
+        if (id.getNamespace() != OfflinePageBridge.BOOKMARK_NAMESPACE) {
+            return new BookmarkId(BookmarkType.NORMAL, -1);
+        }
+        return BookmarkId.getBookmarkIdFromString(id.getId());
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index f718492b..c7cc7ff0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -26,6 +26,7 @@
 import android.widget.RemoteViews;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.FieldTrialList;
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.VisibleForTesting;
@@ -33,6 +34,7 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeVersionInfo;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.IntentHandler.ExternalAppId;
 import org.chromium.chrome.browser.KeyboardShortcuts;
@@ -740,7 +742,10 @@
             StrictMode.setThreadPolicy(oldPolicy);
         }
 
-        if (chromeIsDefault) {
+        boolean enableTabReparenting = ChromeVersionInfo.isLocalBuild()
+                || ChromeVersionInfo.isCanaryBuild() || ChromeVersionInfo.isDevBuild()
+                || FieldTrialList.findFullName("TabReparenting").startsWith("Enabled");
+        if (enableTabReparenting && chromeIsDefault) {
             // Take the activity tab and set it aside for reparenting.
             final Tab tab = getActivityTab();
             // TODO(yusufo): The removal should happen as a part of the callback or as a part of
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/ClientId.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/ClientId.java
new file mode 100644
index 0000000..dacfa490
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/ClientId.java
@@ -0,0 +1,51 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.offlinepages;
+
+import org.chromium.components.bookmarks.BookmarkId;
+
+/**
+ * Object to hold a client identifier for an offline page.
+ */
+public class ClientId {
+    private String mNamespace;
+    private String mId;
+
+    public ClientId(String namespace, String id) {
+        mNamespace = namespace;
+        mId = id;
+    }
+
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    public String getId() {
+        return mId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof ClientId) {
+            ClientId otherId = (ClientId) o;
+            return otherId.getNamespace().equals(mNamespace) && otherId.getId().equals(mId);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (mNamespace + ":" + mId).hashCode();
+    }
+
+    /**
+     * Create a client id for a bookmark
+     * @param id The bookmark id to wrap.
+     * @return A {@link ClientId} that represents this BookmarkId.
+     */
+    public static ClientId createClientIdForBookmarkId(BookmarkId id) {
+        return new ClientId(OfflinePageBridge.BOOKMARK_NAMESPACE, id.toString());
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
index b0dc37cfb..25165dd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -12,8 +12,6 @@
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.offlinepages.DeletePageResult;
 import org.chromium.components.offlinepages.FeatureMode;
 import org.chromium.components.offlinepages.SavePageResult;
@@ -88,11 +86,11 @@
 
         /**
          * Called when an offline page is deleted. This can be called as a result of
-         * TODO(bburns): Switch to offline id/client id
          * #checkOfflinePageMetadata().
-         * @param bookmarkId A bookmark ID of the deleted offline page.
+         * @param offlineId The offline ID of the deleted offline page.
+         * @param clientId The client supplied ID of the deleted offline page.
          */
-        public void offlinePageDeleted(BookmarkId id) {}
+        public void offlinePageDeleted(long offlineId, ClientId clientId) {}
     }
 
     private static long getTotalSize(List<OfflinePageItem> offlinePages) {
@@ -229,10 +227,10 @@
      * @return A list of all offline ids that match a particular
      * (namespace, client_id)
      */
-    private Set<Long> getOfflineIdsForClientId(String clientIdNamespace, String clientId) {
+    private Set<Long> getOfflineIdsForClientId(ClientId clientId) {
         assert mIsNativeOfflinePageModelLoaded;
         long[] offlineIds = nativeGetOfflineIdsForClientId(
-                mNativeOfflinePageBridge, clientIdNamespace, clientId);
+                mNativeOfflinePageBridge, clientId.getNamespace(), clientId.getId());
         Set<Long> result = new HashSet<>(offlineIds.length);
         for (long id : offlineIds) {
             result.add(id);
@@ -243,18 +241,17 @@
     /**
      * Gets an offline page associated with a provided bookmark ID.
      *
-     * @param bookmarkId Id of the bookmark associated with an offline page.
-     * @return An {@link OfflinePageItem} matching the bookmark Id or <code>null</code> if none
+     * @param clientId Client's ID associated with an offline page.
+     * @return A {@link OfflinePageItem} matching the bookmark Id or <code>null</code> if none
      * exist.
      */
-    public OfflinePageItem getPageByBookmarkId(BookmarkId bookmarkId) {
-        Set<Long> ids =
-                getOfflineIdsForClientId(BOOKMARK_NAMESPACE, Long.toString(bookmarkId.getId()));
+    public OfflinePageItem getPageByClientId(ClientId clientId) {
+        Set<Long> ids = getOfflineIdsForClientId(clientId);
         if (ids.size() == 0) {
             return null;
         }
-        Long offlineId = ids.iterator().next();
-        // TODO(bburns): Handle multiple client ids better.
+        // TODO: a better job of choosing which page (e.g. timestamp?)
+        long offlineId = ids.iterator().next();
         return nativeGetPageByOfflineId(mNativeOfflinePageBridge, offlineId);
     }
 
@@ -272,7 +269,8 @@
      * Gets an offline page associated with a provided offline URL.
      *
      * @param string URL pointing to the offline copy of the web page.
-     * @return An {@link OfflinePageItem} matching the offline URL or <code>null</code> if not
+     * @return An {@link OfflinePageItem} matching the offline URL or <code>null
+     </code> if not
      * found.
      */
     public OfflinePageItem getPageByOfflineUrl(String offlineUrl) {
@@ -283,11 +281,11 @@
      * Saves the web page loaded into web contents offline.
      *
      * @param webContents Contents of the page to save.
-     * @param bookmarkId Id of the bookmark related to the offline page.
+     * @param ClientId of the bookmark related to the offline page.
      * @param callback Interface that contains a callback.
      * @see SavePageCallback
      */
-    public void savePage(final WebContents webContents, final BookmarkId bookmarkId,
+    public void savePage(final WebContents webContents, final ClientId clientId,
             final SavePageCallback callback) {
         assert mIsNativeOfflinePageModelLoaded;
         assert webContents != null;
@@ -313,70 +311,67 @@
         };
         recordFreeSpaceHistograms(
                 "OfflinePages.SavePage.FreeSpacePercentage", "OfflinePages.SavePage.FreeSpaceMB");
-        String namespace = BOOKMARK_NAMESPACE;
-        String clientId = Long.toString(bookmarkId.getId());
 
-        nativeSavePage(mNativeOfflinePageBridge, callbackWrapper, webContents, namespace, clientId);
+        nativeSavePage(mNativeOfflinePageBridge, callbackWrapper, webContents,
+                clientId.getNamespace(), clientId.getId());
     }
 
     /**
      * Marks that an offline page related to a specified bookmark has been accessed.
      *
-     * @param bookmarkId Bookmark ID for which the offline copy will be deleted.
+     * @param offlineId offline ID for which the offline copy will be deleted.
      */
-    private void markPageAccessed(BookmarkId bookmarkId) {
+    private void markPageAccessed(long offlineId) {
         assert mIsNativeOfflinePageModelLoaded;
-        Set<Long> ids =
-                getOfflineIdsForClientId(BOOKMARK_NAMESPACE, Long.toString(bookmarkId.getId()));
-        if (ids.size() == 0) {
-            return;
-        }
-        Long offlineId = ids.iterator().next();
         nativeMarkPageAccessed(mNativeOfflinePageBridge, offlineId);
     }
 
     /**
      * Deletes an offline page related to a specified bookmark.
      *
-     * @param bookmarkId Bookmark ID for which the offline copy will be deleted.
+     * @param clientId Client ID for which the offline copy will be deleted.
      * @param callback Interface that contains a callback.
      * @see DeletePageCallback
      */
-    public void deletePage(final BookmarkId bookmarkId, DeletePageCallback callback) {
+    public void deletePage(final ClientId clientId, DeletePageCallback callback) {
         assert mIsNativeOfflinePageModelLoaded;
 
         recordFreeSpaceHistograms("OfflinePages.DeletePage.FreeSpacePercentage",
                 "OfflinePages.DeletePage.FreeSpaceMB");
 
         DeletePageCallback callbackWrapper = wrapCallbackWithHistogramReporting(callback);
-        Set<Long> ids =
-                getOfflineIdsForClientId(BOOKMARK_NAMESPACE, Long.toString(bookmarkId.getId()));
+        Set<Long> ids = getOfflineIdsForClientId(clientId);
         if (ids.size() == 0) {
             callback.onDeletePageDone(DeletePageResult.NOT_FOUND);
             return;
         }
-        Long offlineId = ids.iterator().next();
-        nativeDeletePage(mNativeOfflinePageBridge, callbackWrapper, offlineId);
+        for (Long offlineId : ids) {
+            nativeDeletePage(mNativeOfflinePageBridge, callbackWrapper, offlineId);
+        }
     }
 
     /**
-     * Deletes offline pages based on the list of provided bookamrk IDs. Calls the callback
+     * Deletes offline pages based on the list of provided client IDs. Calls the callback
      * when operation is complete. Requires that the model is already loaded.
      *
-     * @param bookmarkIds A list of bookmark IDs for which the offline pages will be deleted.
+     * @param clientIds A list of Client IDs for which the offline pages will be deleted.
      * @param callback A callback that will be called once operation is completed.
      */
-    public void deletePages(List<BookmarkId> bookmarkIds, DeletePageCallback callback) {
+    public void deletePagesByClientId(List<ClientId> clientIds, DeletePageCallback callback) {
         assert mIsNativeOfflinePageModelLoaded;
-        List<Long> idList = new ArrayList<>(bookmarkIds.size());
-        for (int i = 0; i < bookmarkIds.size(); i++) {
-            idList.addAll(getOfflineIdsForClientId(
-                    BOOKMARK_NAMESPACE, Long.toString(bookmarkIds.get(i).getId())));
+        List<Long> idList = new ArrayList<>(clientIds.size());
+        for (ClientId clientId : clientIds) {
+            idList.addAll(getOfflineIdsForClientId(clientId));
         }
-        long[] ids = new long[idList.size()];
-        for (int i = 0; i < idList.size(); i++) {
-            ids[i] = idList.get(i);
+        deletePages(idList, callback);
+    }
+
+    protected void deletePages(List<Long> offlineIds, DeletePageCallback callback) {
+        long[] ids = new long[offlineIds.size()];
+        for (int i = 0; i < offlineIds.size(); i++) {
+            ids[i] = offlineIds.get(i);
         }
+
         recordFreeSpaceHistograms("OfflinePages.DeletePage.FreeSpacePercentage",
                 "OfflinePages.DeletePage.FreeSpaceMB");
 
@@ -440,7 +435,7 @@
 
         // Mark that the offline page has been accessed, that will cause last access time and access
         // count being updated.
-        nativeMarkPageAccessed(mNativeOfflinePageBridge, page.getBookmarkId().getId());
+        markPageAccessed(page.getOfflineId());
 
         // Returns the offline URL for offline access.
         return page.getOfflineUrl();
@@ -473,6 +468,10 @@
         };
     }
 
+    private ClientId getClientIdForOfflineId(long offlineId) {
+        return nativeGetPageByOfflineId(mNativeOfflinePageBridge, offlineId).getClientId();
+    }
+
     @CalledByNative
     private void offlinePageModelLoaded() {
         mIsNativeOfflinePageModelLoaded = true;
@@ -490,26 +489,26 @@
 
     @CalledByNative
     private void offlinePageDeleted(long offlineId) {
-        BookmarkId id = new BookmarkId(offlineId, BookmarkType.NORMAL);
+        ClientId clientId = getClientIdForOfflineId(offlineId);
         for (OfflinePageModelObserver observer : mObservers) {
-            observer.offlinePageDeleted(id);
+            observer.offlinePageDeleted(offlineId, clientId);
         }
     }
 
     @CalledByNative
     private static void createOfflinePageAndAddToList(List<OfflinePageItem> offlinePagesList,
-            String url, long offlineId, String offlineUrl, long fileSize, long creationTime,
-            int accessCount, long lastAccessTimeMs) {
-        offlinePagesList.add(createOfflinePageItem(
-                url, offlineId, offlineUrl, fileSize, creationTime, accessCount, lastAccessTimeMs));
+            String url, long offlineId, String clientNamespace, String clientId, String offlineUrl,
+            long fileSize, long creationTime, int accessCount, long lastAccessTimeMs) {
+        offlinePagesList.add(createOfflinePageItem(url, offlineId, clientNamespace, clientId,
+                offlineUrl, fileSize, creationTime, accessCount, lastAccessTimeMs));
     }
 
     @CalledByNative
     private static OfflinePageItem createOfflinePageItem(String url, long offlineId,
-            String offlineUrl, long fileSize, long creationTime, int accessCount,
-            long lastAccessTimeMs) {
-        return new OfflinePageItem(
-                url, offlineId, offlineUrl, fileSize, creationTime, accessCount, lastAccessTimeMs);
+            String clientNamespace, String clientId, String offlineUrl, long fileSize,
+            long creationTime, int accessCount, long lastAccessTimeMs) {
+        return new OfflinePageItem(url, offlineId, clientNamespace, clientId, offlineUrl, fileSize,
+                creationTime, accessCount, lastAccessTimeMs);
     }
 
     private static native int nativeGetFeatureMode();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java
index 4e7aa86..a611a76 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java
@@ -17,7 +17,6 @@
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.DeletePageCallback;
 import org.chromium.chrome.browser.snackbar.Snackbar;
 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
-import org.chromium.components.bookmarks.BookmarkId;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -89,7 +88,7 @@
             return;
         }
 
-        mOfflinePageBridge.deletePages(getBookmarkIdsToDelete(), new DeletePageCallback() {
+        mOfflinePageBridge.deletePages(getOfflineIdsToDelete(), new DeletePageCallback() {
             @Override
             public void onDeletePageDone(int deletePageResult) {
                 RecordUserAction.record("OfflinePages.FreeUpSpaceDialogButtonClicked");
@@ -98,13 +97,13 @@
         });
     }
 
-    /** Returns a list of Bookmark IDs for which the offline pages will be deleted. */
-    private List<BookmarkId> getBookmarkIdsToDelete() {
-        List<BookmarkId> bookmarkIds = new ArrayList<BookmarkId>();
+    /** Returns a list of IDs for which the offline pages will be deleted. */
+    private List<Long> getOfflineIdsToDelete() {
+        List<Long> offlineIds = new ArrayList<>();
         for (OfflinePageItem offlinePage : mOfflinePagesToDelete) {
-            bookmarkIds.add(offlinePage.getBookmarkId());
+            offlineIds.add(offlinePage.getOfflineId());
         }
-        return bookmarkIds;
+        return offlineIds;
     }
 
     /** Returns a total size of offline pages that will be deleted. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java
index cbc4c31..75b4973b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java
@@ -5,25 +5,26 @@
 package org.chromium.chrome.browser.offlinepages;
 
 import org.chromium.base.VisibleForTesting;
-import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkType;
 
 /**
  * Simple object representing an offline page.
  */
 public class OfflinePageItem {
     private final String mUrl;
-    private final BookmarkId mBookmarId;
+    private final long mOfflineId;
+    private final ClientId mClientId;
     private final String mOfflineUrl;
     private final long mFileSize;
     private final long mCreationTimeMs;
     private final int mAccessCount;
     private final long mLastAccessTimeMs;
 
-    public OfflinePageItem(String url, long bookmarkId, String offlineUrl, long fileSize,
-            long creationTimeMs, int accessCount, long lastAccessTimeMs) {
+    public OfflinePageItem(String url, long offlineId, String clientNamespace, String clientId,
+            String offlineUrl, long fileSize, long creationTimeMs, int accessCount,
+            long lastAccessTimeMs) {
         mUrl = url;
-        mBookmarId = new BookmarkId(bookmarkId, BookmarkType.NORMAL);
+        mOfflineId = offlineId;
+        mClientId = new ClientId(clientNamespace, clientId);
         mOfflineUrl = offlineUrl;
         mFileSize = fileSize;
         mCreationTimeMs = creationTimeMs;
@@ -37,10 +38,16 @@
         return mUrl;
     }
 
-    /** @return Bookmark Id related to the offline page. */
+    /** @return offline id for this offline page. */
     @VisibleForTesting
-    public BookmarkId getBookmarkId() {
-        return mBookmarId;
+    public long getOfflineId() {
+        return mOfflineId;
+    }
+
+    /** @return Client Id related to the offline page. */
+    @VisibleForTesting
+    public ClientId getClientId() {
+        return mClientId;
     }
 
     /** @return Path to the offline copy of the page. */
@@ -50,7 +57,6 @@
     }
 
     /** @return Size of the offline copy of the page. */
-    @VisibleForTesting
     public long getFileSize() {
         return mFileSize;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
index 6cde0c96..c34f4750 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -1290,8 +1290,12 @@
                 mNavigationButton.setImageDrawable(null);
                 break;
             case OFFLINE:
-                mNavigationButton.setImageResource(
-                        mUseDarkColors ? R.drawable.offline_bolt : R.drawable.offline_bolt_light);
+                Drawable bolt = ApiCompatibilityUtils.getDrawable(
+                        getResources(), R.drawable.offline_bolt);
+                bolt.setColorFilter(ApiCompatibilityUtils.getColor(getResources(), mUseDarkColors
+                        ? R.color.locationbar_status_color
+                        : R.color.locationbar_status_color_light), PorterDuff.Mode.SRC_IN);
+                mNavigationButton.setImageDrawable(bolt);
                 break;
             default:
                 assert false;
@@ -1317,14 +1321,14 @@
         int verboseStatusVisibility = verboseStatusVisible ? VISIBLE : GONE;
 
         mVerboseStatusTextView.setTextColor(ApiCompatibilityUtils.getColor(getResources(),
-                mUseDarkColors ? R.color.locationbar_verbose_status_color
-                        : R.color.locationbar_light_verbose_status_color));
+                mUseDarkColors ? R.color.locationbar_status_color
+                        : R.color.locationbar_status_color_light));
         mVerboseStatusTextView.setVisibility(verboseStatusVisibility);
 
         View separator = findViewById(R.id.location_bar_verbose_status_separator);
         separator.setBackgroundColor(ApiCompatibilityUtils.getColor(getResources(), mUseDarkColors
                 ? R.color.locationbar_status_separator_color
-                : R.color.locationbar_light_status_separator_color));
+                : R.color.locationbar_status_separator_color_light));
         separator.setVisibility(verboseStatusVisibility);
 
         findViewById(R.id.location_bar_verbose_status_extra_space)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabIdManager.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabIdManager.java
index 30113b1e..4ccdf7c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabIdManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabIdManager.java
@@ -10,6 +10,7 @@
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.browser.tabmodel.TabModel;
 
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -38,6 +39,8 @@
     private final Context mContext;
     private final AtomicInteger mIdCounter = new AtomicInteger();
 
+    private SharedPreferences mPreferences;
+
     /** Returns the Singleton instance of the TabIdManager. */
     public static TabIdManager getInstance() {
         return getInstance(ApplicationStatus.getApplicationContext());
@@ -80,14 +83,7 @@
         // It's possible idCounter has been incremented between the get and the add but that's OK --
         // in the worst case mIdCounter will just be overly incremented.
         mIdCounter.addAndGet(diff);
-        updateSharedPreference();
-    }
-
-    private void updateSharedPreference() {
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
-        SharedPreferences.Editor editor = prefs.edit();
-        editor.putInt(PREF_NEXT_ID, mIdCounter.get());
-        editor.apply();
+        mPreferences.edit().putInt(PREF_NEXT_ID, mIdCounter.get()).apply();
     }
 
     private TabIdManager(Context context) {
@@ -96,7 +92,7 @@
         // Read the shared preference.  This has to be done on the critical path to ensure that the
         // myriad Activities that serve as entries into Chrome are all synchronized on the correct
         // maximum Tab ID.
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
-        mIdCounter.set(prefs.getInt(PREF_NEXT_ID, 0));
+        mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+        mIdCounter.set(mPreferences.getInt(PREF_NEXT_ID, 0));
     }
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
index 232a88a..50daa6f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
@@ -13,7 +13,6 @@
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.ntp.NativePageFactory;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tab.TabIdManager;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
 import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabPersistentStoreObserver;
@@ -278,8 +277,7 @@
      * tabs shall not be restored until {@link #restoreTabs} is called.
      */
     public void loadState() {
-        int nextId = mTabSaver.loadState();
-        if (nextId >= 0) TabIdManager.getInstance().incrementIdCounterTo(nextId);
+        mTabSaver.loadState();
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
index fd870da..d2cb3f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -5,9 +5,11 @@
 package org.chromium.chrome.browser.tabmodel;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.os.AsyncTask;
 import android.os.StrictMode;
 import android.os.SystemClock;
+import android.preference.PreferenceManager;
 import android.support.annotation.Nullable;
 import android.support.v4.util.AtomicFile;
 import android.text.TextUtils;
@@ -24,6 +26,7 @@
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabIdManager;
 import org.chromium.content_public.browser.LoadUrlParams;
 
 import java.io.BufferedInputStream;
@@ -60,6 +63,9 @@
     @VisibleForTesting
     public static final String SAVED_STATE_FILE = "tab_state";
 
+    private static final String PREF_HAS_COMPUTED_MAX_ID =
+            "org.chromium.chrome.browser.tabmodel.TabPersistentStore.HAS_COMPUTED_MAX_ID";
+
     /** Prevents two copies of the Migration task from being created. */
     private static final Object MIGRATION_LOCK = new Object();
 
@@ -157,6 +163,8 @@
     private SparseIntArray mNormalTabsRestored;
     private SparseIntArray mIncognitoTabsRestored;
 
+    private SharedPreferences mPreferences;
+
 
     /**
      * Creates an instance of a TabPersistentStore.
@@ -176,6 +184,7 @@
         mTabsToRestore = new ArrayDeque<TabRestoreDetails>();
         mSelectorIndex = selectorIndex;
         mObserver = observer;
+        mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
         createMigrationTask();
     }
 
@@ -189,7 +198,7 @@
     }
 
     @Override
-    public File getStateDirectory() {
+    protected File getStateDirectory() {
         if (mStateDirectory == null) {
             mStateDirectory = getStateDirectory(mContext, mSelectorIndex);
         }
@@ -197,8 +206,8 @@
     }
 
     /**
-     * Sets where the base state directory is.  If overridding this value, set it before the
-     * instance's mStateDirectory field is initialized.
+     * Sets where the base state directory is.  If overriding this value, set it before
+     * instantiating TabPersistentStore.
      */
     @VisibleForTesting
     public static void setBaseStateDirectory(File directory) {
@@ -209,7 +218,7 @@
      * @return Folder that all metadata for the ChromeTabbedActivity TabModels should be located.
      *         Each subdirectory stores info about different instances of ChromeTabbedActivity.
      */
-    public static File getBaseStateDirectory(Context context) {
+    private static File getBaseStateDirectory(Context context) {
         if (sBaseStateDirectory == null) {
             setBaseStateDirectory(context.getDir(BASE_STATE_FOLDER, Context.MODE_PRIVATE));
         }
@@ -232,9 +241,13 @@
      * Waits for the task that migrates all state files to their new location to finish.
      */
     @VisibleForTesting
-    public static void waitForMigrationToFinish() throws InterruptedException, ExecutionException {
+    public static void waitForMigrationToFinish() {
         assert sMigrationTask != null : "The migration should be initialized by now.";
-        sMigrationTask.get();
+        try {
+            sMigrationTask.get();
+        } catch (InterruptedException e) {
+        } catch (ExecutionException e) {
+        }
     }
 
     private static void logSaveException(Exception e) {
@@ -330,41 +343,30 @@
 
     /**
      * Restore saved state. Must be called before any tabs are added to the list.
-     *
-     * @return The next tab ID to use for new tabs.
      */
-    public int loadState() {
-        try {
-            long time = SystemClock.elapsedRealtime();
-            waitForMigrationToFinish();
-            logExecutionTime("LoadStateTime", time);
-        } catch (InterruptedException e) {
-            // Ignore these exceptions, we'll do the best we can.
-        } catch (ExecutionException e) {
-            // Ignore these exceptions, we'll do the best we can.
-        }
+    public void loadState() {
+        long time = SystemClock.elapsedRealtime();
+        waitForMigrationToFinish();
+        logExecutionTime("LoadStateTime", time);
 
         mCancelNormalTabLoads = false;
         mCancelIncognitoTabLoads = false;
         mNormalTabsRestored = new SparseIntArray();
         mIncognitoTabsRestored = new SparseIntArray();
-        int nextId = 0;
         try {
-            nextId = loadStateInternal();
+            time = SystemClock.elapsedRealtime();
+            assert mTabModelSelector.getModel(true).getCount() == 0;
+            assert mTabModelSelector.getModel(false).getCount() == 0;
+            checkAndUpdateMaxTabId();
+            readSavedStateFile(getStateDirectory(),
+                    createOnTabStateReadCallback(mTabModelSelector.isIncognitoSelected()));
+            logExecutionTime("LoadStateInternalTime", time);
         } catch (Exception e) {
-            // Catch generic exception to prevent a corrupted state from crashing the app
-            // at startup.
+            // Catch generic exception to prevent a corrupted state from crashing app on startup.
             Log.d(TAG, "loadState exception: " + e.toString(), e);
         }
 
-        // As everything is loaded asynchronously user actions can create a tab that has ids
-        // pointing to old files and not deleted fast enough. This makes sure to delete everything
-        // that we are sure not to use.
-        // This assumes that the app will only create tab with id at and above nextId.
-        cleanupPersistentDataAtAndAboveId(nextId);
-
         if (mObserver != null) mObserver.onInitialized(mTabsToRestore.size());
-        return nextId;
     }
 
     /**
@@ -728,70 +730,62 @@
     }
 
     /**
-     * Load the saved state of the tab model. No tabs will be restored until you call
-     * {@link #restoreTabs(boolean)}. Must be called before any tabs are added to the list.
+     * @param isIncognitoSelected Whether the tab model is incognito.
+     * @return A callback for reading data from tab models.
+     */
+    private OnTabStateReadCallback createOnTabStateReadCallback(final boolean isIncognitoSelected) {
+        return new OnTabStateReadCallback() {
+            @Override
+            public void onDetailsRead(int index, int id, String url, Boolean isIncognito,
+                    boolean isStandardActiveIndex, boolean isIncognitoActiveIndex) {
+                // Note that incognito tab may not load properly so we may need to use
+                // the current tab from the standard model.
+                // This logic only works because we store the incognito indices first.
+                TabRestoreDetails details =
+                        new TabRestoreDetails(id, index, isIncognito, url);
+
+                if ((isIncognitoActiveIndex && isIncognitoSelected)
+                        || (isStandardActiveIndex && !isIncognitoSelected)) {
+                    // Active tab gets loaded first
+                    mTabsToRestore.addFirst(details);
+                } else {
+                    mTabsToRestore.addLast(details);
+                }
+
+                if (mObserver != null) {
+                    mObserver.onDetailsRead(
+                            index, id, url, isStandardActiveIndex, isIncognitoActiveIndex);
+                }
+            }
+        };
+    }
+
+    /**
+     * If a global max tab ID has not been computed and stored before, then check all the state
+     * folders and calculate a new global max tab ID to be used. Must be called before any new tabs
+     * are created.
      *
      * @throws IOException
      */
-    @VisibleForTesting
-    public int loadStateInternal() throws IOException {
+    private void checkAndUpdateMaxTabId() throws IOException {
+        if (mPreferences.getBoolean(PREF_HAS_COMPUTED_MAX_ID, false)) {
+            return;
+        }
+        int maxId = 0;
         // Temporarily allowing disk access. TODO: Fix. See http://crbug.com/473357
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
         try {
-            long time = SystemClock.elapsedRealtime();
-            assert  mTabModelSelector.getModel(true).getCount() == 0;
-            assert  mTabModelSelector.getModel(false).getCount() == 0;
-            int maxId = 0;
-
             File[] folders = getBaseStateDirectory(mContext).listFiles();
-            if (folders == null) return maxId;
-
-            File stateFolder = getStateDirectory();
+            if (folders == null) return;
             for (File folder : folders) {
-                assert folder.isDirectory();
                 if (!folder.isDirectory()) continue;
-                boolean readDir = folder.equals(stateFolder);
-                final Deque<TabRestoreDetails> restoreList = readDir ? mTabsToRestore : null;
-                final boolean isIncognitoSelected = mTabModelSelector.isIncognitoSelected();
-
-                // TODO(dfalcantara): Store the max tab ID in a shared preference so that it can be
-                //                    shared with all of the other modes that Chrome runs in and to
-                //                    avoid reading in all of the possible app_tabs subdirectories.
-                int curId = readSavedStateFile(folder, new OnTabStateReadCallback() {
-                    @Override
-                    public void onDetailsRead(int index, int id, String url, Boolean isIncognito,
-                            boolean isStandardActiveIndex, boolean isIncognitoActiveIndex) {
-                        // If we're not trying to build the restore list skip the build part.
-                        // We've already read all the state for this entry from the input stream.
-                        if (restoreList == null) return;
-
-                        // Note that incognito tab may not load properly so we may need to use
-                        // the current tab from the standard model.
-                        // This logic only works because we store the incognito indices first.
-                        TabRestoreDetails details =
-                                new TabRestoreDetails(id, index, isIncognito, url);
-
-                        if ((isIncognitoActiveIndex && isIncognitoSelected)
-                                || (isStandardActiveIndex && !isIncognitoSelected)) {
-                            // Active tab gets loaded first
-                            restoreList.addFirst(details);
-                        } else {
-                            restoreList.addLast(details);
-                        }
-
-                        if (mObserver != null) {
-                            mObserver.onDetailsRead(
-                                    index, id, url, isStandardActiveIndex, isIncognitoActiveIndex);
-                        }
-                    }
-                });
-                maxId = Math.max(maxId, curId);
+                maxId = Math.max(maxId, readSavedStateFile(folder, null));
             }
-            logExecutionTime("LoadStateInternalTime", time);
-            return maxId;
         } finally {
             StrictMode.setThreadPolicy(oldPolicy);
         }
+        TabIdManager.getInstance().incrementIdCounterTo(maxId);
+        mPreferences.edit().putBoolean(PREF_HAS_COMPUTED_MAX_ID, true).apply();
     }
 
     public static int readSavedStateFile(File folder, OnTabStateReadCallback callback)
@@ -836,8 +830,10 @@
                 if (id >= nextId) nextId = id + 1;
 
                 Boolean isIncognito = (incognitoCount < 0) ? null : i < incognitoCount;
-                callback.onDetailsRead(i, id, tabUrl, isIncognito,
-                        i == standardActiveIndex, i == incognitoActiveIndex);
+                if (callback != null) {
+                    callback.onDetailsRead(i, id, tabUrl, isIncognito,
+                            i == standardActiveIndex, i == incognitoActiveIndex);
+                }
             }
             logExecutionTime("ReadSavedStateTime", time);
             return nextId;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java
index 4391335..307bab5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java
@@ -4,18 +4,13 @@
 
 package org.chromium.chrome.browser;
 
-import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE;
-
 import android.content.Context;
 import android.os.Build;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
-import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.document.DocumentModeTestBase;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector;
@@ -162,9 +157,10 @@
      * Verifies that the .setProcessInForeground() signal is called correctly as the tabs are
      * created and switched.
      */
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
-    @LargeTest
-    @Feature({"ProcessManagement"})
+    // @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    // @LargeTest
+    // @Feature({"ProcessManagement"})
+    @DisabledTest // https://crbug.com/592404
     public void testTabSwitching() throws Exception {
         // Create two tabs and wait until they are loaded, so that their renderers are around.
         final Tab[] tabs = new Tab[2];
@@ -206,8 +202,9 @@
      * Verifies that a renderer that crashes in foreground has the correct visibility when
      * recreated.
      */
-    @LargeTest
-    @Feature({"ProcessManagement"})
+    // @LargeTest
+    // @Feature({"ProcessManagement"})
+    @DisabledTest // https://crbug.com/592404
     public void testCrashInForeground() throws Exception {
         // Create a tab in foreground and wait until it is loaded.
         final Tab tab = ChromeApplication.getDocumentTabModelSelector().getTabById(
@@ -260,9 +257,10 @@
      * Ensures correctness of the visibilityDetermined() calls, that should be always preceded by
      * setInForeground().
      */
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
-    @LargeTest
-    @Feature({"ProcessManagement"})
+    // @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    // @LargeTest
+    // @Feature({"ProcessManagement"})
+    @DisabledTest // https://crbug.com/592404
     public void testVisibilityDetermined() throws Exception {
         // Create a tab in foreground and wait until it is loaded.
         final Tab fgTab = ChromeApplication.getDocumentTabModelSelector().getTabById(
@@ -308,9 +306,10 @@
      * Verifies that BindingManager.releaseAllModerateBindings() is called once all the sandboxed
      * services are allocated.
      */
-    @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING + "=4")
-    @LargeTest
-    @Feature({"ProcessManagement"})
+    // @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING + "=4")
+    // @LargeTest
+    // @Feature({"ProcessManagement"})
+    @DisabledTest // https://crbug.com/592404
     public void testReleaseAllModerateBindings() throws Exception {
         launchViaViewIntent(false, URL_1, "Page 1");
         launchViaViewIntent(false, URL_1, "Page 1");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
index bd6757f..0788ce3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
@@ -12,6 +12,7 @@
 import android.test.suitebuilder.annotation.MediumTest;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.test.ChromeActivityTestCaseBase;
@@ -102,6 +103,7 @@
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
     @MediumTest
     @Feature({"TextInput", "Main"})
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/592627")
     public void testSelectFileAndCancelRequest() throws Throwable {
         DOMUtils.clickNode(this, mContentViewCore, "input_file");
         CriteriaHelper.pollForCriteria(new IntentSentCriteria());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
index f895f80..bf400dc2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -15,6 +15,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeSwitches;
@@ -211,6 +212,7 @@
 
     @LargeTest
     @Feature({"Browser"})
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/592594")
     public void testSaveDataUrl()
             throws InterruptedException, TimeoutException, SecurityException, IOException {
         saveMediaFromContextMenu("dataUrlIcon", R.id.contextmenu_save_image, "download.gif");
@@ -218,6 +220,7 @@
 
     @LargeTest
     @Feature({"Browser"})
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/592594")
     public void testSaveImage()
             throws InterruptedException, TimeoutException, SecurityException, IOException {
         saveMediaFromContextMenu("testImage", R.id.contextmenu_save_image, "test_image.png");
@@ -225,6 +228,7 @@
 
     @LargeTest
     @Feature({"Browser"})
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/592594")
     public void testSaveVideo()
             throws InterruptedException, TimeoutException, SecurityException, IOException {
         // Click the video to enable playback
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeLowEndTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeLowEndTest.java
index 2170ff2..9870175 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeLowEndTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeLowEndTest.java
@@ -4,18 +4,15 @@
 
 package org.chromium.chrome.browser.document;
 
-import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_LOW_END_DEVICE;
-
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningServiceInfo;
 import android.content.Context;
 import android.os.Build;
-import android.test.suitebuilder.annotation.MediumTest;
 
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
-import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
@@ -35,8 +32,9 @@
 @CommandLineFlags.Add(BaseSwitches.ENABLE_LOW_END_DEVICE_MODE)
 public class DocumentModeLowEndTest extends DocumentModeTestBase {
 
-    @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
-    @MediumTest
+    // @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testNewTabLoadLowEnd() throws Exception {
         launchViaLaunchDocumentInstance(false, HREF_LINK, "href link page");
 
@@ -80,8 +78,9 @@
      * Tests that "Open in new tab" command doesn't create renderer per tab
      * on low end devices.
      */
-    @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
-    @MediumTest
+    // @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testNewTabRenderersLowEnd() throws Exception {
         launchViaLaunchDocumentInstance(false, HREF_LINK, "href link page");
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java
index e2666244..f857bda6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java
@@ -9,8 +9,8 @@
 import android.net.Uri;
 import android.os.Build;
 import android.provider.Browser;
-import android.test.suitebuilder.annotation.MediumTest;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.IntentHandler;
@@ -42,7 +42,8 @@
         }
     }
 
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testReferrerExtra() throws Exception {
         Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(
                 DocumentActivity.class.getName(), null, false);
@@ -94,7 +95,8 @@
         assertEquals(URL_2, mReferrer);
     }
 
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testReferrerExtraAndroidApp() throws Exception {
         Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(
                 DocumentActivity.class.getName(), null, false);
@@ -146,7 +148,8 @@
         assertEquals(androidAppReferrer, mReferrer);
     }
 
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testReferrerExtraNotAndroidApp() throws Exception {
         Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(
                 DocumentActivity.class.getName(), null, false);
@@ -199,7 +202,8 @@
         assertNull(mReferrer);
     }
 
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testReferrerExtraFromExternalIntent() throws Exception {
         Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(
                 DocumentActivity.class.getName(), null, false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java
index 8bf72215..bae22df 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java
@@ -12,13 +12,12 @@
 import android.os.Build;
 import android.os.Environment;
 import android.test.FlakyTest;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.text.TextUtils;
 import android.view.View;
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
@@ -87,7 +86,8 @@
     /**
      * Confirm that you can't start ChromeTabbedActivity while the user is running in Document mode.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testDontStartTabbedActivityInDocumentMode() throws Exception {
         launchThreeTabs();
 
@@ -112,7 +112,8 @@
      * the DocumentActivity to finish itself and hopefully not flat crash (though that'd be better
      * than letting the user live in both tabbed and document mode simultaneously crbug.com/445136).
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testFireInvalidIntent() throws Exception {
         launchThreeTabs();
 
@@ -151,7 +152,8 @@
      * Confirm that firing an Intent for a document that has an ID for an already existing Tab kills
      * the original.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testDuplicateTabIDsKillsOldActivities() throws Exception {
         launchThreeTabs();
 
@@ -197,7 +199,8 @@
     /**
      * Confirm that firing a View Intent with a null URL acts like a Main Intent.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testRelaunchLatestTabWithInvalidViewIntent() throws Exception {
         launchThreeTabs();
 
@@ -232,7 +235,8 @@
      * Confirm that clicking the Chrome icon (e.g. firing an Intent with ACTION_MAIN) brings back
      * the last viewed Tab.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testRelaunchLatestTab() throws Exception {
         launchThreeTabs();
 
@@ -258,7 +262,8 @@
     /**
      * Confirm that setting the index brings the correct tab forward.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testSetIndex() throws Exception {
         int[] tabIds = launchThreeTabs();
 
@@ -284,7 +289,8 @@
     }
 
     /** Check that Intents that request reusing Tabs are honored. */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testReuseIntent() throws Exception {
         // Create a tab, then send the user back to the Home screen.
         int tabId = launchViaViewIntent(false, URL_1, "Page 1");
@@ -332,7 +338,8 @@
      * Tests both ways of launching Incognito tabs: via an Intent, and via
      * {@ref ChromeLauncherActivity#launchDocumentInstance()}.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testIncognitoLaunches() throws Exception {
         assertFalse(ChromeApplication.isDocumentTabModelSelectorInitializedForTests());
 
@@ -408,7 +415,8 @@
      * Tests that opening an Incognito tab via a context menu while in Incognito mode opens the tab
      * in the background.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testIncognitoOpensInBackgroundFromIncognito() throws Exception {
         // Create an Incognito tab via an Intent extra.
         assertFalse(ChromeApplication.isDocumentTabModelSelectorInitializedForTests());
@@ -445,7 +453,8 @@
      * Confirm that the incognito tabs and TabModel are destroyed when the "close all" notification
      * Intent is fired.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testIncognitoNotificationClosesTabs() throws Exception {
         final int regularId = launchViaLaunchDocumentInstance(false, URL_1, "Page 1");
         final DocumentTabModelSelector selector =
@@ -481,7 +490,8 @@
     /**
      * Tests that Incognito tabs are opened in the foreground when spawned from a regular tab.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testIncognitoOpensInForegroundViaLinkContextMenu() throws Exception {
         launchViaLaunchDocumentInstance(false, HREF_LINK, "href link page");
 
@@ -550,7 +560,8 @@
     /**
      * Tests that tab ID is properly set when tabs change.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testLastTabIdUpdates() throws Exception {
         launchViaLaunchDocumentInstance(false, HREF_LINK, "href link page");
 
@@ -596,7 +607,8 @@
      * Tests that the page loads fine when a new page is opened via:
      * <a href="" target="_blank" rel="noreferrer">
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testTargetBlank() throws Exception {
         Intent lastIntent = performNewWindowTest(
                 HREF_NO_REFERRER_LINK, "href no referrer link page", false, "Page 4", false);
@@ -608,7 +620,8 @@
      * Tabs opened this way have their WebContents paused while the new Activity that will host
      * the WebContents starts asynchronously.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testWindowOpen() throws Exception {
         Intent lastIntent = performNewWindowTest(
                 ONCLICK_LINK, "window.open page", true, "Page 4", false);
@@ -645,7 +658,8 @@
      * Tests that the page loads fine when a new page is opened via window.open() and the opener is
      * set to null immediately afterward.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testWindowOpenWithOpenerSuppressed() throws Exception {
         Intent lastIntent = performNewWindowTest(ONCLICK_NO_REFERRER_LINK,
                 "window.open page, opener set to null", true, "Page 4", false);
@@ -657,9 +671,10 @@
      * Tests that a Weblite url from an external app uses the lite_url param when Data Reduction
      * Proxy previews are being used.
      */
-    @MediumTest
-    @CommandLineFlags.Add({"enable-spdy-proxy-auth", "data-reduction-proxy-lo-fi=always-on",
-            "enable-data-reduction-proxy-lo-fi-preview"})
+    // @MediumTest
+    // @CommandLineFlags.Add({"enable-spdy-proxy-auth", "data-reduction-proxy-lo-fi=always-on",
+    //         "enable-data-reduction-proxy-lo-fi-preview"})
+    @DisabledTest // https://crbug.com/592404
     public void testLaunchWebLiteURL() throws Exception {
         EmbeddedTestServer testServer;
         testServer = EmbeddedTestServer.createAndStartFileServer(
@@ -685,7 +700,8 @@
      * Tests that a Weblite url from an external app does not use the lite_url param when Data
      * Reduction Proxy previews are not being used.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testLaunchWebLiteURLNoPreviews() throws Exception {
         String url = "http://googleweblight.com/?lite_url=chrome/test/data/android/about.html";
         Runnable viewIntentRunnable = getViewIntentRunnable(false, url);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java
index bd93894f..d7a8d80e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java
@@ -6,10 +6,10 @@
 
 import android.app.Activity;
 import android.os.Build;
-import android.test.suitebuilder.annotation.MediumTest;
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.document.DocumentActivity;
@@ -78,7 +78,8 @@
      * recently closed.  This test relies on mocking out the ActivityDelegate because we have no
      * obvious way to simulate a user closing a Tab while Chrome is closed.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testMissingTasksBecomeRecentlyClosed() throws Exception {
         // Set up the DocumentTabModel so that it finds a task in Android's Recents that it doesn't
         // know about, which results in adding the Tab to the DocumentTabModel.
@@ -132,7 +133,8 @@
     }
 
     /** Test that the "Recently closed" list is updated properly via the TabModel. */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testUpdateRecentlyClosedAfterTabModelClose() throws Exception {
         int[] tabIds = launchThreeTabs();
 
@@ -204,7 +206,8 @@
     /**
      * Test that the "Recently closed" list is updated when Chrome is alive but backgrounded.
      */
-    @MediumTest
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testUpdateRecentlyClosedWhenChromeInBackground() throws Exception {
         int[] tabIds = launchThreeTabs();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
index 06185e0..cba15df 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
@@ -17,8 +17,6 @@
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.SavePageCallback;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.ChromeActivityTestCaseBase;
-import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.offlinepages.DeletePageResult;
 import org.chromium.components.offlinepages.SavePageResult;
 import org.chromium.content.browser.test.util.Criteria;
@@ -38,7 +36,8 @@
     private static final String TEST_PAGE = "/chrome/test/data/android/about.html";
     private static final int TIMEOUT_MS = 5000;
     private static final long POLLING_INTERVAL = 100;
-    private static final BookmarkId BOOKMARK_ID = new BookmarkId(1234, BookmarkType.NORMAL);
+    private static final ClientId BOOKMARK_ID =
+            new ClientId(OfflinePageBridge.BOOKMARK_NAMESPACE, "1234");
 
     private OfflinePageBridge mOfflinePageBridge;
     private EmbeddedTestServer mTestServer;
@@ -165,7 +164,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                OfflinePageItem offlinePage = mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID);
+                OfflinePageItem offlinePage = mOfflinePageBridge.getPageByClientId(BOOKMARK_ID);
                 offlinePageRef.set(offlinePage);
                 assertEquals("", 0, offlinePage.getAccessCount());
                 long initialAccessTimeMs = offlinePage.getLastAccessTimeMs();
@@ -175,9 +174,9 @@
 
                 assertEquals("Get launch URL should not affect access time while online.",
                         initialAccessTimeMs,
-                        mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID).getLastAccessTimeMs());
+                        mOfflinePageBridge.getPageByClientId(BOOKMARK_ID).getLastAccessTimeMs());
                 assertEquals("Get launch URL should not affect access count while online.", 0,
-                        mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID).getAccessCount());
+                        mOfflinePageBridge.getPageByClientId(BOOKMARK_ID).getAccessCount());
 
                 // Switch to offline
                 NetworkChangeNotifier.forceConnectivityState(false);
@@ -196,7 +195,7 @@
                         @Override
                         public boolean isSatisfied() {
                             OfflinePageItem entry =
-                                    mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID);
+                                    mOfflinePageBridge.getPageByClientId(BOOKMARK_ID);
                             return entry.getAccessCount() != 0;
                         }
                     },
@@ -208,7 +207,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                OfflinePageItem entry = mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID);
+                OfflinePageItem entry = mOfflinePageBridge.getPageByClientId(BOOKMARK_ID);
                 assertEquals(
                         "GetLaunchUrl should increment accessed count when used while offline.", 1,
                         entry.getAccessCount());
@@ -223,7 +222,7 @@
     public void testGetPageByBookmarkId() throws Exception {
         loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
-        OfflinePageItem offlinePage = mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID);
+        OfflinePageItem offlinePage = mOfflinePageBridge.getPageByClientId(BOOKMARK_ID);
         assertEquals("Offline page item url incorrect.", mTestPage, offlinePage.getUrl());
         assertTrue("Offline page item offline file url doesn't start properly.",
                 offlinePage.getOfflineUrl().startsWith("file:///"));
@@ -233,7 +232,8 @@
                 offlinePage.getOfflineUrl().contains("About"));
 
         assertNull("Offline page is not supposed to exist",
-                mOfflinePageBridge.getPageByBookmarkId(new BookmarkId(-42, BookmarkType.NORMAL)));
+                mOfflinePageBridge.getPageByClientId(
+                        new ClientId(OfflinePageBridge.BOOKMARK_NAMESPACE, "-42")));
     }
 
     @SmallTest
@@ -242,17 +242,17 @@
         loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
         assertNotNull("Offline page should be available, but it is not.",
-                mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID));
+                mOfflinePageBridge.getPageByClientId(BOOKMARK_ID));
         deletePage(BOOKMARK_ID, DeletePageResult.SUCCESS);
         assertNull("Offline page should be gone, but it is available.",
-                mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID));
+                mOfflinePageBridge.getPageByClientId(BOOKMARK_ID));
     }
 
     @SmallTest
     public void testGetOfflineUrlForOnlineUrl() throws Exception {
         loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
-        OfflinePageItem offlinePage = mOfflinePageBridge.getPageByBookmarkId(BOOKMARK_ID);
+        OfflinePageItem offlinePage = mOfflinePageBridge.getPageByClientId(BOOKMARK_ID);
         assertEquals("We should get the same offline URL, when querying using online URL",
                 offlinePage.getOfflineUrl(),
                 mOfflinePageBridge.getOfflineUrlForOnlineUrl(offlinePage.getUrl()));
@@ -287,13 +287,13 @@
         assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
-    private void deletePage(BookmarkId bookmarkId, final int expectedResult)
+    private void deletePage(final ClientId bookmarkId, final int expectedResult)
             throws InterruptedException {
         final Semaphore semaphore = new Semaphore(0);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mOfflinePageBridge.deletePage(BOOKMARK_ID, new DeletePageCallback() {
+                mOfflinePageBridge.deletePage(bookmarkId, new DeletePageCallback() {
                     @Override
                     public void onDeletePageDone(int deletePageResult) {
                         assertEquals("Delete result incorrect.", expectedResult, deletePageResult);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
index e1ece759d..6bfd8850 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
@@ -18,8 +18,6 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
 import org.chromium.chrome.test.ChromeActivityTestCaseBase;
-import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.offlinepages.SavePageResult;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -38,7 +36,8 @@
     private static final String TAG = "OfflinePageUtilsTest";
     private static final String TEST_PAGE = "/chrome/test/data/android/about.html";
     private static final int TIMEOUT_MS = 5000;
-    private static final BookmarkId BOOKMARK_ID = new BookmarkId(1234, BookmarkType.NORMAL);
+    private static final ClientId BOOKMARK_ID =
+            new ClientId(OfflinePageBridge.BOOKMARK_NAMESPACE, "1234");
 
     private OfflinePageBridge mOfflinePageBridge;
     private EmbeddedTestServer mTestServer;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
index a4ba878d..aa30a90 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
@@ -15,6 +15,7 @@
 
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.preferences.website.ContentSetting;
 import org.chromium.chrome.browser.preferences.website.GeolocationInfo;
@@ -28,6 +29,7 @@
     private static final String SEARCH_URL_1 = "https://www.google.com/search?q=potatoes";
     private static final String SEARCH_URL_2 = "https://www.google.co.jp/webhp?#q=dinosaurs";
 
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/575277")
     @SmallTest
     @Feature({"Location"})
     @UiThreadTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
index 58a1a13c..d44c329c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
@@ -11,6 +11,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeApplication;
@@ -103,6 +104,7 @@
      */
     @SmallTest
     @Feature({"Preferences"})
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/571513")
     public void testSetAllowLocationEnabled() throws Exception {
         setAllowLocation(true);
         InfoBarTestAnimationListener listener = setInfoBarAnimationListener();
@@ -120,6 +122,7 @@
      */
     @SmallTest
     @Feature({"Preferences"})
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/571513")
     public void testSetAllowLocationNotEnabled() throws Exception {
         setAllowLocation(false);
 
@@ -444,6 +447,7 @@
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ChromeSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/571513")
     public void testCameraBlocked() throws Exception {
         setEnableCamera(false);
 
@@ -462,6 +466,7 @@
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ChromeSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/571513")
     public void testMicBlocked() throws Exception {
         setEnableMic(false);
 
@@ -480,6 +485,7 @@
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ChromeSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/571513")
     public void testCameraNotBlocked() throws Exception {
         setEnableCamera(true);
 
@@ -500,6 +506,7 @@
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ChromeSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
+    @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/571513")
     public void testMicNotBlocked() throws Exception {
         setEnableCamera(true);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java
index c7857abe..1e6c432 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java
@@ -12,6 +12,8 @@
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.TabState;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabIdManager;
 import org.chromium.chrome.test.util.ApplicationData;
 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector;
 
@@ -234,7 +236,9 @@
 
         int maxId = Math.max(getMaxId(selector0), getMaxId(selector1));
         RecordHistogram.disableForTests();
-        assertEquals("Invalid next id", maxId + 1, storeIn.loadStateInternal());
+        storeIn.loadState();
+        assertEquals("Invalid next id", maxId + 1,
+                TabIdManager.getInstance().generateValidId(Tab.INVALID_TAB_ID));
     }
 
     /**
@@ -261,8 +265,8 @@
                 getInstrumentation().getTargetContext(), null, null);
 
         RecordHistogram.disableForTests();
-        storeIn0.loadStateInternal();
-        storeIn1.loadStateInternal();
+        storeIn0.loadState();
+        storeIn1.loadState();
 
         assertEquals("Unexpected number of tabs to load", 6, storeIn0.getRestoredTabCount());
         assertEquals("Unexpected number of tabst o load", 3, storeIn1.getRestoredTabCount());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
index b17fdac..ba6e409 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
@@ -8,7 +8,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.os.Build;
 import android.preference.PreferenceManager;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.view.View;
@@ -16,7 +15,7 @@
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeSwitches;
@@ -220,8 +219,9 @@
     /**
      * Tests that WebappActivities handle window.open() properly in document mode.
      */
-    @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
-    @MediumTest
+    // @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testWebappHandlesWindowOpenInDocumentMode() throws Exception {
         triggerWindowOpenAndWaitForLoad(DocumentActivity.class, ONCLICK_LINK, true);
     }
@@ -238,8 +238,9 @@
     /**
      * Tests that WebappActivities handle suppressed window.open() properly in document mode.
      */
-    @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
-    @MediumTest
+    // @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
+    // @MediumTest
+    @DisabledTest // https://crbug.com/592404
     public void testWebappHandlesSuppressedWindowOpenInDocumentMode() throws Exception {
         triggerWindowOpenAndWaitForLoad(DocumentActivity.class, HREF_NO_REFERRER_LINK, false);
     }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
index c8524cb..7bb262e 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.sync;
 
+import android.test.FlakyTest;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Pair;
 
@@ -87,9 +88,13 @@
         waitForServerTabs(URL);
     }
 
+    /*
     // Test syncing multiple open tabs from client to server.
     @LargeTest
     @Feature({"Sync"})
+    https://crbug.com/592437
+    */
+    @FlakyTest
     public void testUploadMultipleOpenTabs() throws Exception {
         loadUrl(URL);
         loadUrlInNewTab(URL2);
@@ -98,9 +103,13 @@
         waitForServerTabs(URL, URL2, URL3);
     }
 
+    /*
     // Test syncing an open tab from client to server.
     @LargeTest
     @Feature({"Sync"})
+    https://crbug.com/592437
+    */
+    @FlakyTest
     public void testUploadAndCloseOpenTab() throws Exception {
         loadUrl(URL);
         // Can't have zero tabs, so we have to open two to test closing one.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 68527c38..08a164f8 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5561,12 +5561,6 @@
       <message name="IDS_FLAGS_ALTSVC_DESCRIPTION" desc="Description for the flag for Alternative Services.  Please do not translate &quot;Alternative Services&quot;.">
         Enable support for Alternative Services, an experimental HTTP feature.
       </message>
-      <message name="IDS_FLAGS_MEDIA_SOURCE_NAME" desc="Title for the flag for the Media Source API.">
-        Media Source API
-      </message>
-      <message name="IDS_FLAGS_MEDIA_SOURCE_DESCRIPTION" desc="Description for the flag for the Media Source API.">
-        The MediaSource object allows JavaScript to send media data directly to a video element.
-      </message>
       <message name="IDS_FLAGS_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_NAME" desc="Title for the flag for gesture requiment for media playback">
         Gesture requirement for media playback
       </message>
diff --git a/chrome/app/nibs/ActionBoxMenuItem.xib b/chrome/app/nibs/ActionBoxMenuItem.xib
deleted file mode 100644
index 48e99fa4..0000000
--- a/chrome/app/nibs/ActionBoxMenuItem.xib
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F1077" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
-    <dependencies>
-        <deployment version="1060" identifier="macosx"/>
-        <development version="5100" identifier="xcode"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="ActionBoxMenuItemController">
-            <connections>
-                <outlet property="iconView_" destination="2" id="49"/>
-                <outlet property="nameField_" destination="4" id="50"/>
-                <outlet property="view" destination="1" id="10"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application"/>
-        <customView id="1" customClass="ActionBoxMenuItemView">
-            <rect key="frame" x="0.0" y="0.0" width="175" height="29"/>
-            <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
-            <subviews>
-                <imageView id="2">
-                    <rect key="frame" x="10" y="5" width="19" height="19"/>
-                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-                    <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSUser" id="3" customClass="AccessibilityIgnoredImageCell"/>
-                </imageView>
-                <textField verticalHuggingPriority="750" id="4">
-                    <rect key="frame" x="39" y="6" width="126" height="17"/>
-                    <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
-                    <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Menu Text" id="5">
-                        <font key="font" metaFont="cellTitle"/>
-                        <color key="textColor" white="0.12" alpha="1" colorSpace="calibratedWhite"/>
-                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-            </subviews>
-            <connections>
-                <outlet property="viewController_" destination="-2" id="51"/>
-            </connections>
-        </customView>
-        <customObject id="42" customClass="ChromeUILocalizer">
-            <connections>
-                <outlet property="owner_" destination="-2" id="48"/>
-            </connections>
-        </customObject>
-    </objects>
-    <resources>
-        <image name="NSUser" width="32" height="32"/>
-    </resources>
-</document>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 1dba43a..f979642 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -138,6 +138,15 @@
   <message name="IDS_SETTINGS_PASSWORDS_DELETE_EXCEPTION" desc="The alt text for a button that deletes a site for which passwords would not be saved.">
     Delete this item
   </message>
+  <message name="IDS_SETTINGS_PASSWORDS_MENU" desc="Label for a button shows options available for this password item. Available options should be 'Edit' and 'Remove'">
+   Menu
+  </message>
+  <message name="IDS_SETTINGS_PASSWORDS_EDIT" desc="Label for a menu item that shows a dialog with edit options for a password.">
+   Edit
+  </message>
+  <message name="IDS_SETTINGS_PASSWORDS_REMOVE" desc="Label for a menu item that removes a saved password.">
+   Remove
+  </message>
 
   <!-- Default Browser Page -->
   <if expr="not chromeos">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f84d81a..6ec41ea 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -695,9 +695,6 @@
     {"enable-alternative-services", IDS_FLAGS_ALTSVC_NAME,
      IDS_FLAGS_ALTSVC_DESCRIPTION, kOsAll,
      SINGLE_VALUE_TYPE(switches::kEnableAlternativeServices)},
-    {"disable-media-source", IDS_FLAGS_MEDIA_SOURCE_NAME,
-     IDS_FLAGS_MEDIA_SOURCE_DESCRIPTION, kOsAll,
-     SINGLE_DISABLE_VALUE_TYPE(switches::kDisableMediaSource)},
     {"disable-javascript-harmony-shipping",
      IDS_FLAGS_JAVASCRIPT_HARMONY_SHIPPING_NAME,
      IDS_FLAGS_JAVASCRIPT_HARMONY_SHIPPING_DESCRIPTION, kOsAll,
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.cc b/chrome/browser/android/offline_pages/offline_page_bridge.cc
index 681b1a5..ed861c8 100644
--- a/chrome/browser/android/offline_pages/offline_page_bridge.cc
+++ b/chrome/browser/android/offline_pages/offline_page_bridge.cc
@@ -59,6 +59,8 @@
         env, j_result_obj,
         ConvertUTF8ToJavaString(env, offline_page.url.spec()).obj(),
         offline_page.offline_id,
+        ConvertUTF8ToJavaString(env, offline_page.client_id.name_space).obj(),
+        ConvertUTF8ToJavaString(env, offline_page.client_id.id).obj(),
         ConvertUTF8ToJavaString(env, offline_page.GetOfflineURL().spec()).obj(),
         offline_page.file_size, offline_page.creation_time.ToJavaTime(),
         offline_page.access_count, offline_page.last_access_time.ToJavaTime());
@@ -287,6 +289,8 @@
   return Java_OfflinePageBridge_createOfflinePageItem(
       env, ConvertUTF8ToJavaString(env, offline_page.url.spec()).obj(),
       offline_page.offline_id,
+      ConvertUTF8ToJavaString(env, offline_page.client_id.name_space).obj(),
+      ConvertUTF8ToJavaString(env, offline_page.client_id.id).obj(),
       ConvertUTF8ToJavaString(env, offline_page.GetOfflineURL().spec()).obj(),
       offline_page.file_size, offline_page.creation_time.ToJavaTime(),
       offline_page.access_count, offline_page.last_access_time.ToJavaTime());
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc
index cca1362..ec0a852 100644
--- a/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc
+++ b/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc
@@ -100,6 +100,7 @@
       OfflinePageTabHelper::FromWebContents(web_contents());
 
   // Enables offline pages feature.
+  // TODO(jianli): Remove this once the feature is completely enabled.
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kEnableOfflinePages);
 
diff --git a/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc b/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc
index 1cdcf05..f697070 100644
--- a/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc
+++ b/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc
@@ -95,7 +95,8 @@
 OfflinePageUtilsTest::~OfflinePageUtilsTest() {}
 
 void OfflinePageUtilsTest::SetUp() {
-  // Enable offline pages feature.
+  // Enables offline pages feature.
+  // TODO(jianli): Remove this once the feature is completely enabled.
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kEnableOfflinePages);
 
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 12512d5..d1b356c 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -1211,10 +1211,9 @@
     // The worker pointer is reference counted. While it is running, the
     // message loops of the FILE and UI thread will hold references to it
     // and it will be automatically freed once all its tasks have finished.
-    scoped_refptr<shell_integration::DefaultWebClientWorker>
-        set_browser_worker = new shell_integration::DefaultBrowserWorker(
-            nullptr,
-            /*delete_observer=*/false);
+    scoped_refptr<shell_integration::DefaultBrowserWorker> set_browser_worker =
+        new shell_integration::DefaultBrowserWorker(
+            shell_integration::DefaultWebClientWorkerCallback());
     // The user interaction must always be disabled when applying the default
     // browser policy since it is done at each browser startup and the result
     // of the interaction cannot be forced.
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 85936951..223fd0c 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -343,8 +343,8 @@
   }
 
  protected:
-  void SetMonster(net::CookieStore* monster) {
-    cookie_store_ = monster;
+  void SetCookieStore(net::CookieStore* cookie_store) {
+    cookie_store_ = cookie_store;
   }
 
  private:
@@ -365,11 +365,18 @@
 
   bool get_cookie_success_ = false;
   base::Closure quit_closure_;
+
+  // CookieStore must out live |this|.
   net::CookieStore* cookie_store_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(RemoveCookieTester);
 };
 
+void RunClosureAfterCookiesCleared(const base::Closure& task,
+                                   int cookies_deleted) {
+  task.Run();
+}
+
 class RemoveSafeBrowsingCookieTester : public RemoveCookieTester {
  public:
   RemoveSafeBrowsingCookieTester()
@@ -380,13 +387,16 @@
     sb_service->Initialize();
     base::MessageLoop::current()->RunUntilIdle();
 
-    // Create a cookiemonster that does not have persistant storage, and replace
-    // the SafeBrowsingService created one with it.
-    net::CookieStore* monster =
-        content::CreateCookieStore(content::CookieStoreConfig());
-    sb_service->url_request_context()->GetURLRequestContext()->
-        set_cookie_store(monster);
-    SetMonster(monster);
+    // Make sure the safe browsing cookie store has no cookies.
+    // TODO(mmenke): Is this really needed?
+    base::RunLoop run_loop;
+    net::URLRequestContext* request_context =
+        sb_service->url_request_context()->GetURLRequestContext();
+    request_context->cookie_store()->DeleteAllAsync(
+        base::Bind(&RunClosureAfterCookiesCleared, run_loop.QuitClosure()));
+    run_loop.Run();
+
+    SetCookieStore(request_context->cookie_store());
   }
 
   virtual ~RemoveSafeBrowsingCookieTester() {
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index e6726bf..4a9bbd5 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -224,10 +224,9 @@
        shell_integration::IS_DEFAULT)) {
     message_id = IDS_UNINSTALL_CLOSE_APP_IMMERSIVE;
   }
-  chrome::ShowMessageBox(NULL,
-                         l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-                         l10n_util::GetStringUTF16(message_id),
-                         chrome::MESSAGE_BOX_TYPE_WARNING);
+  chrome::ShowWarningMessageBox(NULL,
+                                l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+                                l10n_util::GetStringUTF16(message_id));
 }
 
 int DoUninstallTasks(bool chrome_still_running) {
@@ -309,10 +308,9 @@
   // TODO(viettrungluu): why don't we run this earlier?
   if (!parsed_command_line().HasSwitch(switches::kNoErrorDialogs) &&
       base::win::GetVersion() < base::win::VERSION_XP) {
-    chrome::ShowMessageBox(NULL,
-        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-        l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP),
-        chrome::MESSAGE_BOX_TYPE_WARNING);
+    chrome::ShowWarningMessageBox(
+        NULL, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+        l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP));
   }
 
   return rv;
diff --git a/chrome/browser/chromeos/enrollment_dialog_view.cc b/chrome/browser/chromeos/enrollment_dialog_view.cc
index f5ec1fd..4d219df 100644
--- a/chrome/browser/chromeos/enrollment_dialog_view.cc
+++ b/chrome/browser/chromeos/enrollment_dialog_view.cc
@@ -51,7 +51,6 @@
                          const base::Closure& connect);
 
   // views::DialogDelegateView overrides
-  int GetDialogButtons() const override;
   bool Accept() override;
   base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
 
@@ -111,10 +110,6 @@
   widget->Show();
 }
 
-int EnrollmentDialogView::GetDialogButtons() const {
-  return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK;
-}
-
 bool EnrollmentDialogView::Accept() {
   accepted_ = true;
   return true;
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index cdd081bc..decf10d 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -87,7 +87,6 @@
     ::switches::kDisableGpuCompositing,
     ::switches::kDisableGpuRasterization,
     ::switches::kDisableLowResTiling,
-    ::switches::kDisableMediaSource,
     ::switches::kDisablePreferCompositingToLCDText,
     ::switches::kDisablePanelFitting,
     ::switches::kDisableRGBA4444Textures,
@@ -100,7 +99,6 @@
     ::switches::kDisableDisplayList2dCanvas,
     ::switches::kEnableDisplayList2dCanvas,
     ::switches::kForceDisplayList2dCanvas,
-    ::switches::kDisableEncryptedMedia,
     ::switches::kDisableGpuSandbox,
     ::switches::kEnableDistanceFieldText,
     ::switches::kEnableGpuMemoryBufferVideoFrames,
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index c0e69ac..7cd1ce2c 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -69,7 +69,6 @@
     : public base::RefCountedThreadSafe<
           ProtocolHandlerRegistry::IOThreadDelegate> {
  public:
-
   // Creates a new instance. If |enabled| is true the registry is considered
   // enabled on the IO thread.
   explicit IOThreadDelegate(bool enabled);
@@ -230,42 +229,6 @@
   return job_factory_->IsSafeRedirectTarget(location);
 }
 
-// DefaultClientObserver ------------------------------------------------------
-
-ProtocolHandlerRegistry::DefaultClientObserver::DefaultClientObserver(
-    ProtocolHandlerRegistry* registry)
-    : worker_(NULL),
-      registry_(registry) {
-  DCHECK(registry_);
-}
-
-ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() {
-  if (worker_)
-    worker_->ObserverDestroyed();
-
-  DefaultClientObserverList::iterator iter = std::find(
-      registry_->default_client_observers_.begin(),
-      registry_->default_client_observers_.end(), this);
-  registry_->default_client_observers_.erase(iter);
-}
-
-void ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState(
-    shell_integration::DefaultWebClientUIState state) {
-  if (worker_) {
-    if (ShouldRemoveHandlersNotInOS() &&
-        (state == shell_integration::STATE_NOT_DEFAULT)) {
-      registry_->ClearDefault(worker_->protocol());
-    }
-  } else {
-    NOTREACHED();
-  }
-}
-
-void ProtocolHandlerRegistry::DefaultClientObserver::SetWorker(
-    shell_integration::DefaultProtocolClientWorker* worker) {
-  worker_ = worker;
-}
-
 // Delegate --------------------------------------------------------------------
 
 ProtocolHandlerRegistry::Delegate::~Delegate() {}
@@ -290,44 +253,34 @@
   return ProfileIOData::IsHandledProtocol(protocol);
 }
 
-shell_integration::DefaultProtocolClientWorker*
+scoped_refptr<shell_integration::DefaultProtocolClientWorker>
 ProtocolHandlerRegistry::Delegate::CreateShellWorker(
-    shell_integration::DefaultWebClientObserver* observer,
+    const shell_integration::DefaultWebClientWorkerCallback& callback,
     const std::string& protocol) {
-  return new shell_integration::DefaultProtocolClientWorker(
-      observer, protocol, /*delete_observer=*/true);
-}
-
-ProtocolHandlerRegistry::DefaultClientObserver*
-ProtocolHandlerRegistry::Delegate::CreateShellObserver(
-    ProtocolHandlerRegistry* registry) {
-  return new DefaultClientObserver(registry);
+  return new shell_integration::DefaultProtocolClientWorker(callback, protocol);
 }
 
 void ProtocolHandlerRegistry::Delegate::RegisterWithOSAsDefaultClient(
     const std::string& protocol, ProtocolHandlerRegistry* registry) {
-  DefaultClientObserver* observer = CreateShellObserver(registry);
   // The worker pointer is reference counted. While it is running, the
   // message loops of the FILE and UI thread will hold references to it
   // and it will be automatically freed once all its tasks have finished.
-  scoped_refptr<shell_integration::DefaultProtocolClientWorker> worker;
-  worker = CreateShellWorker(observer, protocol);
-  observer->SetWorker(worker.get());
-  registry->default_client_observers_.push_back(observer);
-  worker->StartSetAsDefault();
+  CreateShellWorker(registry->GetDefaultWebClientCallback(protocol), protocol)
+      ->StartSetAsDefault();
 }
 
 // ProtocolHandlerRegistry -----------------------------------------------------
 
 ProtocolHandlerRegistry::ProtocolHandlerRegistry(
-    content::BrowserContext* context, Delegate* delegate)
+    content::BrowserContext* context,
+    Delegate* delegate)
     : context_(context),
       delegate_(delegate),
       enabled_(true),
       is_loading_(false),
       is_loaded_(false),
-      io_thread_delegate_(new IOThreadDelegate(enabled_)){
-}
+      io_thread_delegate_(new IOThreadDelegate(enabled_)),
+      weak_ptr_factory_(this) {}
 
 bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest(
     const ProtocolHandler& handler) {
@@ -468,12 +421,13 @@
     for (ProtocolHandlerMap::const_iterator p = default_handlers_.begin();
          p != default_handlers_.end(); ++p) {
       ProtocolHandler handler = p->second;
-      DefaultClientObserver* observer = delegate_->CreateShellObserver(this);
-      scoped_refptr<shell_integration::DefaultProtocolClientWorker> worker;
-      worker = delegate_->CreateShellWorker(observer, handler.protocol());
-      observer->SetWorker(worker.get());
-      default_client_observers_.push_back(observer);
-      worker->StartCheckIsDefault();
+      // The worker pointer is reference counted. While it is running the
+      // message loops of the FILE and UI thread will hold references to it
+      // and it will be automatically freed once all its tasks have finished.
+      delegate_
+          ->CreateShellWorker(GetDefaultWebClientCallback(handler.protocol()),
+                              handler.protocol())
+          ->StartSetAsDefault();
     }
   }
 }
@@ -709,14 +663,8 @@
 void ProtocolHandlerRegistry::Shutdown() {
   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
-  // protocol handler registry after it was deleted.
-  // Observers remove themselves from this list when they are deleted; so
-  // we delete the last item until none are left in the list.
-  while (!default_client_observers_.empty()) {
-    delete default_client_observers_.back();
-  }
+
+  weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
 // static
@@ -731,7 +679,6 @@
 
 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(default_client_observers_.empty());
 }
 
 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) {
@@ -949,6 +896,15 @@
   list->erase(std::find(list->begin(), list->end(), handler));
 }
 
+void ProtocolHandlerRegistry::OnSetAsDefaultProtocolClientFinished(
+    const std::string& protocol,
+    shell_integration::DefaultWebClientUIState state) {
+  if (ShouldRemoveHandlersNotInOS() &&
+      state == shell_integration::STATE_NOT_DEFAULT) {
+    ClearDefault(protocol);
+  }
+}
+
 void ProtocolHandlerRegistry::AddPredefinedHandler(
     const ProtocolHandler& handler) {
   DCHECK(!is_loaded_);  // Must be called prior InitProtocolSettings.
@@ -956,6 +912,14 @@
   SetDefault(handler);
 }
 
+shell_integration::DefaultWebClientWorkerCallback
+ProtocolHandlerRegistry::GetDefaultWebClientCallback(
+    const std::string& protocol) {
+  return base::Bind(
+      &ProtocolHandlerRegistry::OnSetAsDefaultProtocolClientFinished,
+      weak_ptr_factory_.GetWeakPtr(), protocol);
+}
+
 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
 ProtocolHandlerRegistry::CreateJobInterceptorFactory() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h
index a2dcc07..c540c985 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.h
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.h
@@ -10,8 +10,8 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/sequenced_task_runner_helpers.h"
 #include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
@@ -34,40 +34,11 @@
 // Profile::InitRegisteredProtocolHandlers(), and they should be the only
 // instances of this class.
 class ProtocolHandlerRegistry : public KeyedService {
-
  public:
   enum HandlerSource {
     USER,    // The handler was installed by user
     POLICY,  // The handler was installed by policy
   };
-  // Provides notification of when the OS level user agent settings
-  // are changed.
-  class DefaultClientObserver
-      : public shell_integration::DefaultWebClientObserver {
-   public:
-    explicit DefaultClientObserver(ProtocolHandlerRegistry* registry);
-    ~DefaultClientObserver() override;
-
-    // Get response from the worker regarding whether Chrome is the default
-    // handler for the protocol.
-    void SetDefaultWebClientUIState(
-        shell_integration::DefaultWebClientUIState state) override;
-
-    // Give the observer a handle to the worker, so we can find out the protocol
-    // when we're called and also tell the worker if we get deleted.
-    void SetWorker(shell_integration::DefaultProtocolClientWorker* worker);
-
-   protected:
-    shell_integration::DefaultProtocolClientWorker* worker_;
-
-   private:
-    // This is a raw pointer, not reference counted, intentionally. In general
-    // subclasses of DefaultWebClientObserver are not able to be refcounted
-    // e.g. the browser options page
-    ProtocolHandlerRegistry* registry_;
-
-    DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver);
-  };
 
   // |Delegate| provides an interface for interacting asynchronously
   // with the underlying OS for the purposes of registering Chrome
@@ -78,11 +49,10 @@
     virtual void RegisterExternalHandler(const std::string& protocol);
     virtual void DeregisterExternalHandler(const std::string& protocol);
     virtual bool IsExternalHandlerRegistered(const std::string& protocol);
-    virtual shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-        shell_integration::DefaultWebClientObserver* observer,
+    virtual scoped_refptr<shell_integration::DefaultProtocolClientWorker>
+    CreateShellWorker(
+        const shell_integration::DefaultWebClientWorkerCallback& callback,
         const std::string& protocol);
-    virtual DefaultClientObserver* CreateShellObserver(
-        ProtocolHandlerRegistry* registry);
     virtual void RegisterWithOSAsDefaultClient(
         const std::string& protocol,
         ProtocolHandlerRegistry* registry);
@@ -140,7 +110,6 @@
   typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
   typedef std::vector<ProtocolHandler> ProtocolHandlerList;
   typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
-  typedef std::vector<DefaultClientObserver*> DefaultClientObserverList;
 
   // Creates a new instance. Assumes ownership of |delegate|.
   ProtocolHandlerRegistry(content::BrowserContext* context, Delegate* delegate);
@@ -261,6 +230,11 @@
   // load command was issued, otherwise the command will be ignored.
   void AddPredefinedHandler(const ProtocolHandler& handler);
 
+  // Gets the callback for DefaultProtocolClientWorker. Allows the Delegate to
+  // create the worker on behalf of ProtocolHandlerRegistry.
+  shell_integration::DefaultWebClientWorkerCallback GetDefaultWebClientCallback(
+      const std::string& protocol);
+
  private:
   friend class base::DeleteHelper<ProtocolHandlerRegistry>;
   friend struct content::BrowserThread::DeleteOnThread<
@@ -340,6 +314,12 @@
   // Erases the handler that is guaranteed to exist from the list.
   void EraseHandler(const ProtocolHandler& handler, ProtocolHandlerList* list);
 
+  // Called with the default state when the default protocol client worker is
+  // done.
+  void OnSetAsDefaultProtocolClientFinished(
+      const std::string& protocol,
+      shell_integration::DefaultWebClientUIState state);
+
   // Map from protocols (strings) to protocol handlers.
   ProtocolHandlerMultiMap protocol_handlers_;
 
@@ -384,7 +364,9 @@
   // are posted to the IO thread where updates are applied to this object.
   scoped_refptr<IOThreadDelegate> io_thread_delegate_;
 
-  DefaultClientObserverList default_client_observers_;
+  // Makes it possible to invalidate the callback for the
+  // DefaultProtocolClientWorker.
+  base::WeakPtrFactory<ProtocolHandlerRegistry> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
 };
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index 2ddfae0..8dfd2f7b 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -136,6 +136,42 @@
   return value;
 }
 
+class FakeProtocolClientWorker
+    : public shell_integration::DefaultProtocolClientWorker {
+ public:
+  FakeProtocolClientWorker(
+      const shell_integration::DefaultWebClientWorkerCallback& callback,
+      const std::string& protocol,
+      bool force_failure)
+      : shell_integration::DefaultProtocolClientWorker(callback, protocol),
+        force_failure_(force_failure) {}
+
+ private:
+  ~FakeProtocolClientWorker() override {}
+
+  void CheckIsDefault() override {
+    shell_integration::DefaultWebClientState state =
+        shell_integration::IS_DEFAULT;
+    if (force_failure_)
+      state = shell_integration::NOT_DEFAULT;
+
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&FakeProtocolClientWorker::OnCheckIsDefaultComplete, this,
+                   state));
+  }
+
+  void SetAsDefault() override {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&FakeProtocolClientWorker::OnSetAsDefaultAttemptComplete,
+                   this, AttemptResult::SUCCESS));
+  }
+
+ private:
+  bool force_failure_;
+};
+
 class FakeDelegate : public ProtocolHandlerRegistry::Delegate {
  public:
   FakeDelegate() : force_os_failure_(false) {}
@@ -150,20 +186,17 @@
     registered_protocols_.erase(protocol);
   }
 
-  shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-      shell_integration::DefaultWebClientObserver* observer,
-      const std::string& protocol) override;
-
-  ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver(
-      ProtocolHandlerRegistry* registry) override;
-
-  void RegisterWithOSAsDefaultClient(const std::string& protocol,
-                                     ProtocolHandlerRegistry* reg) override {
-    ProtocolHandlerRegistry::Delegate::RegisterWithOSAsDefaultClient(protocol,
-                                                                     reg);
-    ASSERT_FALSE(IsFakeRegisteredWithOS(protocol));
+  scoped_refptr<shell_integration::DefaultProtocolClientWorker>
+  CreateShellWorker(
+      const shell_integration::DefaultWebClientWorkerCallback& callback,
+      const std::string& protocol) override {
+    return new FakeProtocolClientWorker(callback, protocol, force_os_failure_);
   }
 
+  void RegisterWithOSAsDefaultClient(
+      const std::string& protocol,
+      ProtocolHandlerRegistry* registry) override;
+
   bool IsExternalHandlerRegistered(const std::string& protocol) override {
     return registered_protocols_.find(protocol) != registered_protocols_.end();
   }
@@ -193,78 +226,29 @@
   bool force_os_failure_;
 };
 
-class FakeClientObserver
-    : public ProtocolHandlerRegistry::DefaultClientObserver {
- public:
-  FakeClientObserver(ProtocolHandlerRegistry* registry,
-                     FakeDelegate* registry_delegate)
-      : ProtocolHandlerRegistry::DefaultClientObserver(registry),
-        delegate_(registry_delegate) {}
-
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override {
-    ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState(
-        state);
-    if (state == shell_integration::STATE_IS_DEFAULT) {
-      delegate_->FakeRegisterWithOS(worker_->protocol());
-    }
-    if (state != shell_integration::STATE_PROCESSING) {
-      base::MessageLoop::current()->QuitWhenIdle();
-    }
+void OnShellWorkerFinished(ProtocolHandlerRegistry* registry,
+                           FakeDelegate* delegate,
+                           const std::string& protocol,
+                           shell_integration::DefaultWebClientUIState state) {
+  registry->GetDefaultWebClientCallback(protocol).Run(state);
+  if (state == shell_integration::STATE_IS_DEFAULT) {
+    delegate->FakeRegisterWithOS(protocol);
   }
-
- private:
-  FakeDelegate* delegate_;
-};
-
-class FakeProtocolClientWorker
-    : public shell_integration::DefaultProtocolClientWorker {
- public:
-  FakeProtocolClientWorker(
-      shell_integration::DefaultWebClientObserver* observer,
-      const std::string& protocol,
-      bool force_failure)
-      : shell_integration::DefaultProtocolClientWorker(
-            observer,
-            protocol,
-            /*delete_observer*/ true),
-        force_failure_(force_failure) {}
-
- private:
-  ~FakeProtocolClientWorker() override {}
-
-  void CheckIsDefault() override {
-    shell_integration::DefaultWebClientState state =
-        shell_integration::IS_DEFAULT;
-    if (force_failure_)
-      state = shell_integration::NOT_DEFAULT;
-
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&FakeProtocolClientWorker::OnCheckIsDefaultComplete, this,
-                   state));
+  if (state != shell_integration::STATE_PROCESSING) {
+    base::MessageLoop::current()->QuitWhenIdle();
   }
-
-  void SetAsDefault() override {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&FakeProtocolClientWorker::OnSetAsDefaultAttemptComplete,
-                   this, AttemptResult::SUCCESS));
-  }
-
- private:
-  bool force_failure_;
-};
-
-ProtocolHandlerRegistry::DefaultClientObserver*
-    FakeDelegate::CreateShellObserver(ProtocolHandlerRegistry* registry) {
-  return new FakeClientObserver(registry, this);
 }
 
-shell_integration::DefaultProtocolClientWorker* FakeDelegate::CreateShellWorker(
-    shell_integration::DefaultWebClientObserver* observer,
-    const std::string& protocol) {
-  return new FakeProtocolClientWorker(observer, protocol, force_os_failure_);
+void FakeDelegate::RegisterWithOSAsDefaultClient(
+    const std::string& protocol,
+    ProtocolHandlerRegistry* registry) {
+  // The worker pointer is reference counted. While it is running, the
+  // message loops of the FILE and UI thread will hold references to it
+  // and it will be automatically freed once all its tasks have finished.
+  CreateShellWorker(base::Bind(OnShellWorkerFinished, registry, this, protocol),
+                    protocol)
+      ->StartSetAsDefault();
+  ASSERT_FALSE(IsFakeRegisteredWithOS(protocol));
 }
 
 class NotificationCounter : public content::NotificationObserver {
@@ -333,8 +317,8 @@
       case base::MessageLoop::TYPE_IO:
         return BrowserThread::CurrentlyOn(BrowserThread::IO);
 #if defined(OS_ANDROID)
-      case base::MessageLoop::TYPE_JAVA: // fall-through
-#endif // defined(OS_ANDROID)
+      case base::MessageLoop::TYPE_JAVA:  // fall-through
+#endif  // defined(OS_ANDROID)
       case base::MessageLoop::TYPE_CUSTOM:
       case base::MessageLoop::TYPE_DEFAULT:
         return !BrowserThread::CurrentlyOn(BrowserThread::UI) &&
@@ -753,7 +737,7 @@
 
 // TODO(smckay): This is much more appropriately an integration
 // test. Make that so, then update the
-// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully
+// ShellIntegretion{Delegate,Callback,Worker} test classes we use to fully
 // isolate this test from the FILE thread.
 TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) {
   ProtocolHandler ph_do1 = CreateProtocolHandler("do", "test1");
@@ -785,7 +769,7 @@
 
 // TODO(smckay): This is much more appropriately an integration
 // test. Make that so, then update the
-// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully
+// ShellIntegretion{Delegate,Callback,Worker} test classes we use to fully
 // isolate this test from the FILE thread.
 TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestOSRegistrationFailure) {
   ProtocolHandler ph_do = CreateProtocolHandler("do", "test1");
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index 5dc44af..d6451bd2 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -264,15 +264,18 @@
 int ResponseWriter::Write(net::IOBuffer* buffer,
                           int num_bytes,
                           const net::CompletionCallback& callback) {
+  std::string chunk = std::string(buffer->data(), num_bytes);
+  if (!base::IsStringUTF8(chunk))
+    return num_bytes;
+
   base::FundamentalValue* id = new base::FundamentalValue(stream_id_);
-  base::StringValue* chunk =
-      new base::StringValue(std::string(buffer->data(), num_bytes));
+  base::StringValue* chunkValue = new base::StringValue(chunk);
 
   content::BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
       base::Bind(&DevToolsUIBindings::CallClientFunction,
                  bindings_, "DevToolsAPI.streamWrite",
-                 base::Owned(id), base::Owned(chunk), nullptr));
+                 base::Owned(id), base::Owned(chunkValue), nullptr));
   return num_bytes;
 }
 
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 170def8b..96cbd399 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1352,9 +1352,11 @@
         ->ExecuteScript(
             HostID(HostID::EXTENSIONS, extension_id()),
             ScriptExecutor::JAVASCRIPT,
-            net::UnescapeURLComponent(url.GetContent(),
-                                      net::UnescapeRule::URL_SPECIAL_CHARS |
-                                          net::UnescapeRule::SPACES),
+            net::UnescapeURLComponent(
+                url.GetContent(),
+                net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
+                    net::UnescapeRule::PATH_SEPARATORS |
+                    net::UnescapeRule::SPACES),
             ScriptExecutor::SINGLE_FRAME, ExtensionApiFrameIdMap::kTopFrameId,
             ScriptExecutor::DONT_MATCH_ABOUT_BLANK, UserScript::DOCUMENT_IDLE,
             ScriptExecutor::MAIN_WORLD, ScriptExecutor::DEFAULT_PROCESS, GURL(),
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc
index ccae49f..0c9f822 100644
--- a/chrome/browser/extensions/bookmark_app_helper.cc
+++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -93,7 +93,7 @@
  private:
   // gfx::CanvasImageSource overrides:
   void Draw(gfx::Canvas* canvas) override {
-    const unsigned char kLuminanceThreshold = 190;
+    const uint8_t kLumaThreshold = 190;
     const int icon_size = output_size_ * 3 / 4;
     const int icon_inset = output_size_ / 8;
     const size_t border_radius = output_size_ / 16;
@@ -117,12 +117,12 @@
     // The text rect's size needs to be odd to center the text correctly.
     gfx::Rect text_rect(icon_inset, icon_inset, icon_size + 1, icon_size + 1);
     // Draw the letter onto the rounded rect. The letter's color depends on the
-    // luminance of |color|.
-    unsigned char luminance = color_utils::GetLuminanceForColor(color_);
+    // luma of |color|.
+    const uint8_t luma = color_utils::GetLuma(color_);
     canvas->DrawStringRectWithFlags(
         base::string16(1, std::toupper(letter_)),
         gfx::FontList(gfx::Font(font_name, font_size)),
-        luminance > kLuminanceThreshold ? SK_ColorBLACK : SK_ColorWHITE,
+        (luma > kLumaThreshold) ? SK_ColorBLACK : SK_ColorWHITE,
         text_rect,
         gfx::Canvas::TEXT_ALIGN_CENTER);
   }
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc
index e496012..233e213 100644
--- a/chrome/browser/extensions/extension_apitest.cc
+++ b/chrome/browser/extensions/extension_apitest.cc
@@ -114,11 +114,11 @@
   std::string escaped_header =
       request.relative_url.substr(query_string_pos + 1);
 
-  std::string header =
-      net::UnescapeURLComponent(escaped_header,
-                                net::UnescapeRule::NORMAL |
-                                net::UnescapeRule::SPACES |
-                                net::UnescapeRule::URL_SPECIAL_CHARS);
+  std::string header = net::UnescapeURLComponent(
+      escaped_header,
+      net::UnescapeRule::NORMAL | net::UnescapeRule::SPACES |
+          net::UnescapeRule::PATH_SEPARATORS |
+          net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
 
   size_t colon_pos = header.find(':');
   if (colon_pos == std::string::npos)
diff --git a/chrome/browser/extensions/extension_error_reporter.cc b/chrome/browser/extensions/extension_error_reporter.cc
index 8986423..72d664b 100644
--- a/chrome/browser/extensions/extension_error_reporter.cc
+++ b/chrome/browser/extensions/extension_error_reporter.cc
@@ -79,11 +79,9 @@
   LOG(WARNING) << "Extension error: " << message;
 
   if (enable_noisy_errors_ && be_noisy) {
-    chrome::ShowMessageBox(
-        NULL,
-        l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_ERROR_HEADING),
-        message,
-        chrome::MESSAGE_BOX_TYPE_WARNING);
+    chrome::ShowWarningMessageBox(
+        NULL, l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_ERROR_HEADING),
+        message);
   }
 }
 
diff --git a/chrome/browser/extensions/extension_renderer_state.cc b/chrome/browser/extensions/extension_renderer_state.cc
index c0166fe5..5227b277 100644
--- a/chrome/browser/extensions/extension_renderer_state.cc
+++ b/chrome/browser/extensions/extension_renderer_state.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "base/metrics/histogram_macros.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/tab_contents/retargeting_details.h"
@@ -214,10 +215,12 @@
   int render_view_id = info->GetRouteID();
   RenderId render_id(render_process_id, render_view_id);
   TabAndWindowIdMap::iterator iter = map_.find(render_id);
+  bool found = false;
   if (iter != map_.end()) {
     *tab_id = iter->second.first;
     *window_id = iter->second.second;
-    return true;
+    found = true;
   }
-  return false;
+  UMA_HISTOGRAM_BOOLEAN("Extensions.ExtensionRendererStateCacheHit", found);
+  return found;
 }
diff --git a/chrome/browser/extensions/isolated_app_browsertest.cc b/chrome/browser/extensions/isolated_app_browsertest.cc
index 665323b2..e387ecf7 100644
--- a/chrome/browser/extensions/isolated_app_browsertest.cc
+++ b/chrome/browser/extensions/isolated_app_browsertest.cc
@@ -72,17 +72,17 @@
     std::string escaped_value(
         query_string.substr(value_pos.begin, value_pos.len));
 
-    std::string key =
-        net::UnescapeURLComponent(escaped_key,
-                                  net::UnescapeRule::NORMAL |
-                                  net::UnescapeRule::SPACES |
-                                  net::UnescapeRule::URL_SPECIAL_CHARS);
+    std::string key = net::UnescapeURLComponent(
+        escaped_key,
+        net::UnescapeRule::NORMAL | net::UnescapeRule::SPACES |
+            net::UnescapeRule::PATH_SEPARATORS |
+            net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
 
-    std::string value =
-        net::UnescapeURLComponent(escaped_value,
-                                  net::UnescapeRule::NORMAL |
-                                  net::UnescapeRule::SPACES |
-                                  net::UnescapeRule::URL_SPECIAL_CHARS);
+    std::string value = net::UnescapeURLComponent(
+        escaped_value,
+        net::UnescapeRule::NORMAL | net::UnescapeRule::SPACES |
+            net::UnescapeRule::PATH_SEPARATORS |
+            net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
 
     if (key == "expect") {
       if (request_cookies.find(value) == std::string::npos)
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index 1a2a70b..86ee9cc1 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -595,7 +595,9 @@
     // We've found "x=<something>", now unescape <something> and look for
     // the "id=<id>&ping=<ping_value>" parameters within.
     std::string unescaped = net::UnescapeURLComponent(
-        param.second, net::UnescapeRule::URL_SPECIAL_CHARS);
+        param.second,
+        net::UnescapeRule::PATH_SEPARATORS |
+            net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
     base::StringPairs extension_params;
     base::SplitStringIntoKeyValuePairs(unescaped, '=', '&', &extension_params);
     std::multimap<std::string, std::string> param_map;
@@ -607,7 +609,9 @@
       // Pull the key=value pairs out of the ping parameter for this id and
       // put into the result.
       std::string ping = net::UnescapeURLComponent(
-          param_map.find("ping")->second, net::UnescapeRule::URL_SPECIAL_CHARS);
+          param_map.find("ping")->second,
+          net::UnescapeRule::PATH_SEPARATORS |
+              net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
       base::StringPairs ping_params;
       base::SplitStringIntoKeyValuePairs(ping, '=', '&', &ping_params);
       for (const auto& ping_param : ping_params) {
@@ -637,7 +641,9 @@
 
   EXPECT_EQ(1U, params.count("x"));
   std::string decoded = net::UnescapeURLComponent(
-      params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
+      params["x"],
+      net::UnescapeRule::PATH_SEPARATORS |
+          net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
   ExtractParameters(decoded, result);
 }
 
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc
index 5fa8ddc..66449d1 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -38,18 +38,15 @@
 namespace {
 
 // Functions enabling unit testing. Using a NULL delegate will use the default
-// behavior; if a delegate is provided it will be used instead. Also, Ownership
-// of |observer| is passed to the new worker.
-shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-    shell_integration::DefaultWebClientObserver* observer,
+// behavior; if a delegate is provided it will be used instead.
+scoped_refptr<shell_integration::DefaultProtocolClientWorker> CreateShellWorker(
+    const shell_integration::DefaultWebClientWorkerCallback& callback,
     const std::string& protocol,
     ExternalProtocolHandler::Delegate* delegate) {
-  if (!delegate)
-    return new shell_integration::DefaultProtocolClientWorker(
-        observer, protocol,
-        /*delete_observer=*/true);
+  if (delegate)
+    return delegate->CreateShellWorker(callback, protocol);
 
-  return delegate->CreateShellWorker(observer, protocol);
+  return new shell_integration::DefaultProtocolClientWorker(callback, protocol);
 }
 
 ExternalProtocolHandler::BlockState GetBlockStateWithDelegate(
@@ -92,71 +89,49 @@
   }
 }
 
-// When we are about to launch a URL with the default OS level application,
-// we check if that external application will be us. If it is we just ignore
-// the request.
-class ExternalDefaultProtocolObserver
-    : public shell_integration::DefaultWebClientObserver {
- public:
-  ExternalDefaultProtocolObserver(const GURL& escaped_url,
-                                  int render_process_host_id,
-                                  int tab_contents_id,
-                                  bool prompt_user,
-                                  ui::PageTransition page_transition,
-                                  bool has_user_gesture,
-                                  ExternalProtocolHandler::Delegate* delegate)
-      : delegate_(delegate),
-        escaped_url_(escaped_url),
-        render_process_host_id_(render_process_host_id),
-        tab_contents_id_(tab_contents_id),
-        prompt_user_(prompt_user),
-        page_transition_(page_transition),
-        has_user_gesture_(has_user_gesture) {}
+// When we are about to launch a URL with the default OS level application, we
+// check if the external application will be us. If it is we just ignore the
+// request.
+void OnDefaultProtocolClientWorkerFinished(
+    const GURL& escaped_url,
+    int render_process_host_id,
+    int tab_contents_id,
+    bool prompt_user,
+    ui::PageTransition page_transition,
+    bool has_user_gesture,
+    ExternalProtocolHandler::Delegate* delegate,
+    shell_integration::DefaultWebClientUIState state) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override {
-    DCHECK(base::MessageLoopForUI::IsCurrent());
+  // If we are still working out if we're the default, or we've found
+  // out we definately are the default, we end here.
+  if (state == shell_integration::STATE_PROCESSING)
+    return;
 
-    // If we are still working out if we're the default, or we've found
-    // out we definately are the default, we end here.
-    if (state == shell_integration::STATE_PROCESSING) {
-      return;
-    }
+  if (delegate)
+    delegate->FinishedProcessingCheck();
 
-    if (delegate_)
-      delegate_->FinishedProcessingCheck();
-
-    if (state == shell_integration::STATE_IS_DEFAULT) {
-      if (delegate_)
-        delegate_->BlockRequest();
-      return;
-    }
-
-    // If we get here, either we are not the default or we cannot work out
-    // what the default is, so we proceed.
-    if (prompt_user_) {
-      // Ask the user if they want to allow the protocol. This will call
-      // LaunchUrlWithoutSecurityCheck if the user decides to accept the
-      // protocol.
-      RunExternalProtocolDialogWithDelegate(
-          escaped_url_, render_process_host_id_, tab_contents_id_,
-          page_transition_, has_user_gesture_, delegate_);
-      return;
-    }
-
-    LaunchUrlWithoutSecurityCheckWithDelegate(
-        escaped_url_, render_process_host_id_, tab_contents_id_, delegate_);
+  if (state == shell_integration::STATE_IS_DEFAULT) {
+    if (delegate)
+      delegate->BlockRequest();
+    return;
   }
 
- private:
-  ExternalProtocolHandler::Delegate* delegate_;
-  const GURL escaped_url_;
-  const int render_process_host_id_;
-  const int tab_contents_id_;
-  const bool prompt_user_;
-  const ui::PageTransition page_transition_;
-  const bool has_user_gesture_;
-};
+  // If we get here, either we are not the default or we cannot work out
+  // what the default is, so we proceed.
+  if (prompt_user) {
+    // Ask the user if they want to allow the protocol. This will call
+    // LaunchUrlWithoutSecurityCheck if the user decides to accept the
+    // protocol.
+    RunExternalProtocolDialogWithDelegate(escaped_url, render_process_host_id,
+                                          tab_contents_id, page_transition,
+                                          has_user_gesture, delegate);
+    return;
+  }
+
+  LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url, render_process_host_id,
+                                            tab_contents_id, delegate);
+}
 
 }  // namespace
 
@@ -289,19 +264,17 @@
   g_accept_requests = false;
 
   // The worker creates tasks with references to itself and puts them into
-  // message loops. When no tasks are left it will delete the observer and
-  // eventually be deleted itself.
-  shell_integration::DefaultWebClientObserver* observer =
-      new ExternalDefaultProtocolObserver(
-          url, render_process_host_id, tab_contents_id, block_state == UNKNOWN,
-          page_transition, has_user_gesture, delegate);
-  scoped_refptr<shell_integration::DefaultProtocolClientWorker> worker =
-      CreateShellWorker(observer, escaped_url.scheme(), delegate);
+  // message loops.
+  shell_integration::DefaultWebClientWorkerCallback callback = base::Bind(
+      &OnDefaultProtocolClientWorkerFinished, url, render_process_host_id,
+      tab_contents_id, block_state == UNKNOWN, page_transition,
+      has_user_gesture, delegate);
 
   // Start the check process running. This will send tasks to the FILE thread
-  // and when the answer is known will send the result back to the observer on
-  // the UI thread.
-  worker->StartCheckIsDefault();
+  // and when the answer is known will send the result back to
+  // OnDefaultProtocolClientWorkerFinished().
+  CreateShellWorker(callback, escaped_url.scheme(), delegate)
+      ->StartCheckIsDefault();
 }
 
 // static
diff --git a/chrome/browser/external_protocol/external_protocol_handler.h b/chrome/browser/external_protocol/external_protocol_handler.h
index 47598053..692f2dd 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.h
+++ b/chrome/browser/external_protocol/external_protocol_handler.h
@@ -29,8 +29,9 @@
   // Delegate to allow unit testing to provide different behavior.
   class Delegate {
    public:
-    virtual shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-        shell_integration::DefaultWebClientObserver* observer,
+    virtual scoped_refptr<shell_integration::DefaultProtocolClientWorker>
+    CreateShellWorker(
+        const shell_integration::DefaultWebClientWorkerCallback& callback,
         const std::string& protocol) = 0;
     virtual BlockState GetBlockState(const std::string& scheme) = 0;
     virtual void BlockRequest() = 0;
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
index b631125..aa09a9f 100644
--- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -14,13 +14,10 @@
     : public shell_integration::DefaultProtocolClientWorker {
  public:
   FakeExternalProtocolHandlerWorker(
-      shell_integration::DefaultWebClientObserver* observer,
+      const shell_integration::DefaultWebClientWorkerCallback& callback,
       const std::string& protocol,
       shell_integration::DefaultWebClientState os_state)
-      : shell_integration::DefaultProtocolClientWorker(
-            observer,
-            protocol,
-            /*delete_observer=*/true),
+      : shell_integration::DefaultProtocolClientWorker(callback, protocol),
         os_state_(os_state) {}
 
  private:
@@ -54,10 +51,11 @@
         has_prompted_(false),
         has_blocked_(false) {}
 
-  shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-      shell_integration::DefaultWebClientObserver* observer,
+  scoped_refptr<shell_integration::DefaultProtocolClientWorker>
+  CreateShellWorker(
+      const shell_integration::DefaultWebClientWorkerCallback& callback,
       const std::string& protocol) override {
-    return new FakeExternalProtocolHandlerWorker(observer, protocol, os_state_);
+    return new FakeExternalProtocolHandlerWorker(callback, protocol, os_state_);
   }
 
   ExternalProtocolHandler::BlockState GetBlockState(
diff --git a/chrome/browser/hang_monitor/hung_plugin_action.cc b/chrome/browser/hang_monitor/hung_plugin_action.cc
index feff61d9..0e28687 100644
--- a/chrome/browser/hang_monitor/hung_plugin_action.cc
+++ b/chrome/browser/hang_monitor/hung_plugin_action.cc
@@ -113,8 +113,7 @@
                           HungWindowResponseCallback,
                           reinterpret_cast<ULONG_PTR>(this));
       current_hung_plugin_window_ = hung_window;
-      if (chrome::ShowMessageBox(
-              NULL, title, message, chrome::MESSAGE_BOX_TYPE_QUESTION) ==
+      if (chrome::ShowQuestionMessageBox(NULL, title, message) ==
           chrome::MESSAGE_BOX_RESULT_YES) {
         *action = HungWindowNotification::HUNG_WINDOW_TERMINATE_PROCESS;
       } else {
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index b8dda317..5d4e3b3 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -743,7 +743,7 @@
       FROM_HERE_WITH_EXPLICIT_FUNCTION(
           "466432 IOThread::InitAsync::CreateCookieStore::Start"));
   globals_->system_cookie_store =
-        content::CreateCookieStore(content::CookieStoreConfig());
+      content::CreateCookieStore(content::CookieStoreConfig());
   // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466432
   // is fixed.
   tracked_objects::ScopedTracker tracking_profile12(
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 06c3c1d..d21ce61 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -190,7 +190,7 @@
     SystemRequestContextLeakChecker system_request_context_leak_checker;
     // |system_cookie_store| and |system_channel_id_service| are shared
     // between |proxy_script_fetcher_context| and |system_request_context|.
-    scoped_refptr<net::CookieStore> system_cookie_store;
+    scoped_ptr<net::CookieStore> system_cookie_store;
 #if defined(ENABLE_EXTENSIONS)
     scoped_refptr<extensions::EventRouterForwarder>
         extension_event_router_forwarder;
diff --git a/chrome/browser/media/chrome_webrtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_browsertest.cc
index 9f7453e..5a22b015 100644
--- a/chrome/browser/media/chrome_webrtc_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_browsertest.cc
@@ -88,7 +88,7 @@
                        RunsAudioVideoWebRTCCallInTwoTabsH264) {
   // Only run test if run-time feature corresponding to |rtc_use_h264| is on.
   if (!base::FeatureList::IsEnabled(content::kWebRtcH264WithOpenH264FFmpeg)) {
-    LOG(WARNING) << "Run-time feature WebRtcH264WithOpenH264FFmpeg disabled. "
+    LOG(WARNING) << "Run-time feature WebRTC-H264WithOpenH264FFmpeg disabled. "
         "Skipping WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsH264 "
         "(test \"OK\")";
     return;
diff --git a/chrome/browser/media/chrome_webrtc_perf_browsertest.cc b/chrome/browser/media/chrome_webrtc_perf_browsertest.cc
index 25d497d2..7021e0fc 100644
--- a/chrome/browser/media/chrome_webrtc_perf_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_perf_browsertest.cc
@@ -22,6 +22,8 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/feature_h264_with_openh264_ffmpeg.h"
+#include "content/public/common/features.h"
 #include "content/public/test/browser_test_utils.h"
 #include "media/base/media_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -101,96 +103,143 @@
     return scoped_ptr<base::DictionaryValue>(
         GetWebrtcInternalsData(webrtc_internals_tab));
   }
+
+  void RunsAudioVideoCall60SecsAndLogsInternalMetrics(
+      const std::string& video_codec) {
+    ASSERT_TRUE(test::HasReferenceFilesInCheckout());
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 100)
+        << "This is a long-running test; you must specify "
+           "--ui-test-action-max-timeout to have a value of at least 100000.";
+
+    content::WebContents* left_tab =
+        OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+    content::WebContents* right_tab =
+        OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+
+    SetupPeerconnectionWithLocalStream(left_tab);
+    SetupPeerconnectionWithLocalStream(right_tab);
+
+    NegotiateCall(left_tab, right_tab, video_codec);
+
+    StartDetectingVideo(left_tab, "remote-view");
+    StartDetectingVideo(right_tab, "remote-view");
+
+    WaitForVideoToPlay(left_tab);
+    WaitForVideoToPlay(right_tab);
+
+    // Let values stabilize, bandwidth ramp up, etc.
+    test::SleepInJavascript(left_tab, 60000);
+
+    // Start measurements.
+    scoped_ptr<base::DictionaryValue> all_data =
+        MeasureWebRtcInternalsData(10000);
+    ASSERT_TRUE(all_data.get() != NULL);
+
+    const base::DictionaryValue* first_pc_dict =
+        GetDataOnPeerConnection(all_data.get(), 0);
+    ASSERT_TRUE(first_pc_dict != NULL);
+    test::PrintBweForVideoMetrics(*first_pc_dict, "", video_codec);
+    test::PrintMetricsForAllStreams(*first_pc_dict, "", video_codec);
+
+    HangUp(left_tab);
+    HangUp(right_tab);
+  }
+
+  void RunsOneWayCall60SecsAndLogsInternalMetrics(
+      const std::string& video_codec) {
+    ASSERT_TRUE(test::HasReferenceFilesInCheckout());
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 100)
+        << "This is a long-running test; you must specify "
+           "--ui-test-action-max-timeout to have a value of at least 100000.";
+
+    content::WebContents* left_tab =
+        OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+    content::WebContents* right_tab =
+        OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+
+    SetupPeerconnectionWithLocalStream(left_tab);
+    SetupPeerconnectionWithoutLocalStream(right_tab);
+
+    NegotiateCall(left_tab, right_tab, video_codec);
+
+    // Remote video will only play in one tab since the call is one-way.
+    StartDetectingVideo(right_tab, "remote-view");
+    WaitForVideoToPlay(right_tab);
+
+    // Let values stabilize, bandwidth ramp up, etc.
+    test::SleepInJavascript(left_tab, 60000);
+
+    scoped_ptr<base::DictionaryValue> all_data =
+        MeasureWebRtcInternalsData(10000);
+    ASSERT_TRUE(all_data.get() != NULL);
+
+    // This assumes the sending peer connection is always listed first in the
+    // data store, and the receiving second.
+    const base::DictionaryValue* first_pc_dict =
+        GetDataOnPeerConnection(all_data.get(), 0);
+    ASSERT_TRUE(first_pc_dict != NULL);
+    test::PrintBweForVideoMetrics(*first_pc_dict, "_sendonly", video_codec);
+    test::PrintMetricsForAllStreams(*first_pc_dict, "_sendonly", video_codec);
+
+    const base::DictionaryValue* second_pc_dict =
+        GetDataOnPeerConnection(all_data.get(), 1);
+    ASSERT_TRUE(second_pc_dict != NULL);
+    test::PrintBweForVideoMetrics(*second_pc_dict, "_recvonly", video_codec);
+    test::PrintMetricsForAllStreams(*second_pc_dict, "_recvonly", video_codec);
+
+    HangUp(left_tab);
+    HangUp(right_tab);
+  }
 };
 
 // This is manual for its long execution time.
-IN_PROC_BROWSER_TEST_F(WebRtcPerfBrowserTest,
-                       MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetrics) {
-  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
-  ASSERT_TRUE(embedded_test_server()->Start());
 
-  ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 100) <<
-      "This is a long-running test; you must specify "
-      "--ui-test-action-max-timeout to have a value of at least 100000.";
-
-  content::WebContents* left_tab =
-      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
-  content::WebContents* right_tab =
-      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
-
-  SetupPeerconnectionWithLocalStream(left_tab);
-  SetupPeerconnectionWithLocalStream(right_tab);
-
-  NegotiateCall(left_tab, right_tab);
-
-  StartDetectingVideo(left_tab, "remote-view");
-  StartDetectingVideo(right_tab, "remote-view");
-
-  WaitForVideoToPlay(left_tab);
-  WaitForVideoToPlay(right_tab);
-
-  // Let values stabilize, bandwidth ramp up, etc.
-  test::SleepInJavascript(left_tab, 60000);
-
-  // Start measurements.
-  scoped_ptr<base::DictionaryValue> all_data =
-      MeasureWebRtcInternalsData(10000);
-  ASSERT_TRUE(all_data.get() != NULL);
-
-  const base::DictionaryValue* first_pc_dict =
-      GetDataOnPeerConnection(all_data.get(), 0);
-  ASSERT_TRUE(first_pc_dict != NULL);
-  test::PrintBweForVideoMetrics(*first_pc_dict, "");
-  test::PrintMetricsForAllStreams(*first_pc_dict, "");
-
-  HangUp(left_tab);
-  HangUp(right_tab);
+// The video codec name is now appended to result bucket (e.g. 'video_tx_VP8').
+// TODO(asapersson): Keep test below using the default video codec (which do
+// not have the codec name appended ('video_tx')) until new tests have been
+// running for some time.
+IN_PROC_BROWSER_TEST_F(
+    WebRtcPerfBrowserTest,
+    MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsDefault) {
+  RunsAudioVideoCall60SecsAndLogsInternalMetrics("");
 }
 
-IN_PROC_BROWSER_TEST_F(WebRtcPerfBrowserTest,
-                       MANUAL_RunsOneWayCall60SecsAndLogsInternalMetrics) {
-  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
-  ASSERT_TRUE(embedded_test_server()->Start());
-
-  ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 100) <<
-      "This is a long-running test; you must specify "
-      "--ui-test-action-max-timeout to have a value of at least 100000.";
-
-  content::WebContents* left_tab =
-      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
-  content::WebContents* right_tab =
-      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
-
-  SetupPeerconnectionWithLocalStream(left_tab);
-  SetupPeerconnectionWithoutLocalStream(right_tab);
-
-  NegotiateCall(left_tab, right_tab);
-
-  // Remote video will only play in one tab since the call is one-way.
-  StartDetectingVideo(right_tab, "remote-view");
-  WaitForVideoToPlay(right_tab);
-
-  // Let values stabilize, bandwidth ramp up, etc.
-  test::SleepInJavascript(left_tab, 60000);
-
-  scoped_ptr<base::DictionaryValue> all_data =
-      MeasureWebRtcInternalsData(10000);
-  ASSERT_TRUE(all_data.get() != NULL);
-
-  // This assumes the sending peer connection is always listed first in the
-  // data store, and the receiving second.
-  const base::DictionaryValue* first_pc_dict =
-      GetDataOnPeerConnection(all_data.get(), 0);
-  ASSERT_TRUE(first_pc_dict != NULL);
-  test::PrintBweForVideoMetrics(*first_pc_dict, "_sendonly");
-  test::PrintMetricsForAllStreams(*first_pc_dict, "_sendonly");
-
-  const base::DictionaryValue* second_pc_dict =
-      GetDataOnPeerConnection(all_data.get(), 1);
-  ASSERT_TRUE(second_pc_dict != NULL);
-  test::PrintBweForVideoMetrics(*second_pc_dict, "_recvonly");
-  test::PrintMetricsForAllStreams(*second_pc_dict, "_recvonly");
-
-  HangUp(left_tab);
-  HangUp(right_tab);
+IN_PROC_BROWSER_TEST_F(
+    WebRtcPerfBrowserTest,
+    MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsVp8) {
+  RunsAudioVideoCall60SecsAndLogsInternalMetrics("VP8");
 }
+
+IN_PROC_BROWSER_TEST_F(
+    WebRtcPerfBrowserTest,
+    MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsVp9) {
+  RunsAudioVideoCall60SecsAndLogsInternalMetrics("VP9");
+}
+
+#if BUILDFLAG(RTC_USE_H264)
+
+IN_PROC_BROWSER_TEST_F(
+    WebRtcPerfBrowserTest,
+    MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsH264) {
+  // Only run test if run-time feature corresponding to |rtc_use_h264| is on.
+  if (!base::FeatureList::IsEnabled(content::kWebRtcH264WithOpenH264FFmpeg)) {
+    LOG(WARNING) << "Run-time feature WebRTC-H264WithOpenH264FFmpeg disabled. "
+        "Skipping WebRtcPerfBrowserTest.MANUAL_RunsAudioVideoCall60SecsAndLogs"
+        "InternalMetricsH264 (test \"OK\")";
+    return;
+  }
+  RunsAudioVideoCall60SecsAndLogsInternalMetrics("H264");
+}
+
+#endif  // BUILDFLAG(RTC_USE_H264)
+
+IN_PROC_BROWSER_TEST_F(
+    WebRtcPerfBrowserTest,
+    MANUAL_RunsOneWayCall60SecsAndLogsInternalMetricsDefault) {
+  RunsOneWayCall60SecsAndLogsInternalMetrics("");
+}
+
diff --git a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
index 6098fa34..63594572 100644
--- a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
@@ -37,6 +37,13 @@
 #include "testing/perf/perf_test.h"
 #include "ui/gl/gl_switches.h"
 
+namespace {
+std::string MakeLabel(const char* test_name, const std::string& video_codec) {
+  std::string codec_label = video_codec.empty() ? "" : "_" + video_codec;
+  return base::StringPrintf("%s%s", test_name, codec_label.c_str());
+}
+}  // namespace
+
 static const base::FilePath::CharType kFrameAnalyzerExecutable[] =
 #if defined(OS_WIN)
     FILE_PATH_LITERAL("frame_analyzer.exe");
@@ -195,7 +202,7 @@
   // |width| x |height|.
   // All measurements calculated are printed as perf parsable numbers to stdout.
   bool CompareVideosAndPrintResult(
-      const char* test_label,
+      const std::string& test_label,
       int width,
       int height,
       const base::FilePath& captured_video_filename,
@@ -236,7 +243,7 @@
     EXPECT_TRUE(GetPythonCommand(&compare_command));
 
     compare_command.AppendArgPath(path_to_compare_script);
-    compare_command.AppendArg(base::StringPrintf("--label=%s", test_label));
+    compare_command.AppendArg("--label=" + test_label);
     compare_command.AppendArg("--ref_video");
     compare_command.AppendArgPath(reference_video_filename);
     compare_command.AppendArg("--test_video");
@@ -270,12 +277,61 @@
     return true;
   }
 
+  void TestVideoQuality(const std::string& video_codec) {
+    ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 150)
+        << "This is a long-running test; you must specify "
+           "--ui-test-action-max-timeout to have a value of at least 150000.";
+    ASSERT_TRUE(test::HasReferenceFilesInCheckout());
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    content::WebContents* left_tab =
+        OpenPageAndGetUserMediaInNewTabWithConstraints(
+            embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage),
+            test_config_.constraints);
+    content::WebContents* right_tab =
+        OpenPageAndGetUserMediaInNewTabWithConstraints(
+            embedded_test_server()->GetURL(kCapturingWebrtcHtmlPage),
+            test_config_.constraints);
+
+    SetupPeerconnectionWithLocalStream(left_tab);
+    SetupPeerconnectionWithLocalStream(right_tab);
+
+    NegotiateCall(left_tab, right_tab, video_codec);
+
+    // Poll slower here to avoid flooding the log with messages: capturing and
+    // sending frames take quite a bit of time.
+    int polling_interval_msec = 1000;
+
+    EXPECT_TRUE(test::PollingWaitUntil("doneFrameCapturing()", "done-capturing",
+                                       right_tab, polling_interval_msec));
+
+    HangUp(left_tab);
+
+    WriteCapturedFramesToWorkingDir(right_tab);
+
+    // Shut everything down to avoid having the javascript race with the
+    // analysis tools. For instance, dont have console log printouts interleave
+    // with the RESULT lines from the analysis tools (crbug.com/323200).
+    chrome::CloseWebContents(browser(), left_tab, false);
+    chrome::CloseWebContents(browser(), right_tab, false);
+
+    ASSERT_TRUE(
+        RunARGBtoI420Converter(test_config_.width, test_config_.height,
+                               GetWorkingDir().Append(kCapturedYuvFileName)));
+
+    ASSERT_TRUE(CompareVideosAndPrintResult(
+        MakeLabel(test_config_.test_name, video_codec), test_config_.width,
+        test_config_.height, GetWorkingDir().Append(kCapturedYuvFileName),
+        test::GetReferenceFilesDir()
+            .Append(test_config_.reference_video)
+            .AddExtension(test::kYuvFileExtension),
+        GetWorkingDir().Append(kStatsFileName)));
+  }
+
  protected:
   VideoQualityTestConfig test_config_;
 
-  base::FilePath GetWorkingDir() {
-    return temp_working_dir_.path();
-  }
+  base::FilePath GetWorkingDir() { return temp_working_dir_.path(); }
 
  private:
   base::FilePath GetSourceDir() {
@@ -300,56 +356,21 @@
     WebRtcVideoQualityBrowserTest,
     testing::ValuesIn(kVideoConfigurations));
 
+// The video codec name is now appended to the test label (e.g. '720p_VP8').
+// TODO(asapersson): Keep test below using the default video codec (which do
+// not have the codec name appended ('720p')) until new tests have been
+// running for some time.
 IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest,
-                       MANUAL_TestVideoQuality) {
-  ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 150) <<
-      "This is a long-running test; you must specify "
-      "--ui-test-action-max-timeout to have a value of at least 150000.";
-  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
-  ASSERT_TRUE(embedded_test_server()->Start());
+                       MANUAL_TestVideoQualityDefault) {
+  TestVideoQuality("");
+}
 
-  content::WebContents* left_tab =
-      OpenPageAndGetUserMediaInNewTabWithConstraints(
-          embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage),
-          test_config_.constraints);
-  content::WebContents* right_tab =
-      OpenPageAndGetUserMediaInNewTabWithConstraints(
-          embedded_test_server()->GetURL(kCapturingWebrtcHtmlPage),
-          test_config_.constraints);
+IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest,
+                       MANUAL_TestVideoQualityVp8) {
+  TestVideoQuality("VP8");
+}
 
-  SetupPeerconnectionWithLocalStream(left_tab);
-  SetupPeerconnectionWithLocalStream(right_tab);
-
-  NegotiateCall(left_tab, right_tab);
-
-  // Poll slower here to avoid flooding the log with messages: capturing and
-  // sending frames take quite a bit of time.
-  int polling_interval_msec = 1000;
-
-  EXPECT_TRUE(test::PollingWaitUntil(
-      "doneFrameCapturing()", "done-capturing", right_tab,
-      polling_interval_msec));
-
-  HangUp(left_tab);
-
-  WriteCapturedFramesToWorkingDir(right_tab);
-
-  // Shut everything down to avoid having the javascript race with the analysis
-  // tools. For instance, dont have console log printouts interleave with the
-  // RESULT lines from the analysis tools (crbug.com/323200).
-  chrome::CloseWebContents(browser(), left_tab, false);
-  chrome::CloseWebContents(browser(), right_tab, false);
-
-  ASSERT_TRUE(RunARGBtoI420Converter(
-      test_config_.width, test_config_.height,
-      GetWorkingDir().Append(kCapturedYuvFileName)));
-  ASSERT_TRUE(CompareVideosAndPrintResult(
-      test_config_.test_name,
-      test_config_.width,
-      test_config_.height,
-      GetWorkingDir().Append(kCapturedYuvFileName),
-      test::GetReferenceFilesDir()
-          .Append(test_config_.reference_video)
-          .AddExtension(test::kYuvFileExtension),
-      GetWorkingDir().Append(kStatsFileName)));
+IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest,
+                       MANUAL_TestVideoQualityVp9) {
+  TestVideoQuality("VP9");
 }
diff --git a/chrome/browser/media/desktop_capture_access_handler.cc b/chrome/browser/media/desktop_capture_access_handler.cc
index 48a9e8d3..a9aa1bfb 100644
--- a/chrome/browser/media/desktop_capture_access_handler.cc
+++ b/chrome/browser/media/desktop_capture_access_handler.cc
@@ -209,9 +209,9 @@
   //  2. Request comes from a page with a secure origin or from an extension.
   if (screen_capture_enabled && origin_is_secure) {
     // Get title of the calling application prior to showing the message box.
-    // chrome::ShowMessageBox() starts a nested message loop which may allow
-    // |web_contents| to be destroyed on the UI thread before the message box
-    // is closed. See http://crbug.com/326690.
+    // chrome::ShowQuestionMessageBox() starts a nested message loop which may
+    // allow |web_contents| to be destroyed on the UI thread before the messag
+    // box is closed. See http://crbug.com/326690.
     base::string16 application_title =
         GetApplicationTitle(web_contents, extension);
 #if !defined(OS_ANDROID)
@@ -237,11 +237,11 @@
               ? IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT
               : IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT,
           application_name);
-      chrome::MessageBoxResult result = chrome::ShowMessageBox(
+      chrome::MessageBoxResult result = chrome::ShowQuestionMessageBox(
           parent_window,
           l10n_util::GetStringFUTF16(
               IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name),
-          confirmation_text, chrome::MESSAGE_BOX_TYPE_QUESTION);
+          confirmation_text);
       user_approved = (result == chrome::MESSAGE_BOX_RESULT_YES);
     }
 
diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc
index e215cd5e46..109dc542 100644
--- a/chrome/browser/media/media_stream_devices_controller.cc
+++ b/chrome/browser/media/media_stream_devices_controller.cc
@@ -458,8 +458,6 @@
     ContentSetting new_audio_setting,
     ContentSetting new_video_setting) const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  ContentSettingsPattern primary_pattern =
-      ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
 
   bool is_pepper_request =
       request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY;
@@ -467,19 +465,20 @@
   if (IsAskingForAudio() && new_audio_setting != CONTENT_SETTING_ASK) {
     if (ShouldPersistContentSetting(new_audio_setting, request_.security_origin,
                                     is_pepper_request)) {
-      HostContentSettingsMapFactory::GetForProfile(profile_)->SetContentSetting(
-          primary_pattern, ContentSettingsPattern::Wildcard(),
-          CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string(),
-          new_audio_setting);
+      HostContentSettingsMapFactory::GetForProfile(profile_)
+          ->SetContentSettingDefaultScope(request_.security_origin, GURL(),
+                                          CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+                                          std::string(), new_audio_setting);
     }
   }
   if (IsAskingForVideo() && new_video_setting != CONTENT_SETTING_ASK) {
     if (ShouldPersistContentSetting(new_video_setting, request_.security_origin,
                                     is_pepper_request)) {
-      HostContentSettingsMapFactory::GetForProfile(profile_)->SetContentSetting(
-          primary_pattern, ContentSettingsPattern::Wildcard(),
-          CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(),
-          new_video_setting);
+      HostContentSettingsMapFactory::GetForProfile(profile_)
+          ->SetContentSettingDefaultScope(
+              request_.security_origin, GURL(),
+              CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(),
+              new_video_setting);
     }
   }
 }
diff --git a/chrome/browser/media/media_stream_devices_controller_browsertest.cc b/chrome/browser/media/media_stream_devices_controller_browsertest.cc
index bf7018cd..1c341fb2 100644
--- a/chrome/browser/media/media_stream_devices_controller_browsertest.cc
+++ b/chrome/browser/media/media_stream_devices_controller_browsertest.cc
@@ -99,13 +99,11 @@
     HostContentSettingsMap* content_settings =
         HostContentSettingsMapFactory::GetForProfile(
             Profile::FromBrowserContext(GetWebContents()->GetBrowserContext()));
-    ContentSettingsPattern pattern =
-        ContentSettingsPattern::FromURLNoWildcard(example_url_);
-    content_settings->SetContentSetting(pattern, pattern,
-                                        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
-                                        std::string(), mic_setting);
-    content_settings->SetContentSetting(
-        pattern, pattern, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
+    content_settings->SetContentSettingDefaultScope(
+        example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+        std::string(), mic_setting);
+    content_settings->SetContentSettingDefaultScope(
+        example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
         std::string(), cam_setting);
   }
 
diff --git a/chrome/browser/media/webrtc_browsertest_perf.cc b/chrome/browser/media/webrtc_browsertest_perf.cc
index e473559..68bce5d 100644
--- a/chrome/browser/media/webrtc_browsertest_perf.cc
+++ b/chrome/browser/media/webrtc_browsertest_perf.cc
@@ -209,33 +209,39 @@
 namespace test {
 
 void PrintBweForVideoMetrics(const base::DictionaryValue& pc_dict,
-                             const std::string& modifier) {
+                             const std::string& modifier,
+                             const std::string& video_codec) {
+  std::string video_modifier =
+      video_codec.empty() ? modifier : modifier + "_" + video_codec;
   const std::string kBweStatsKey = "bweforvideo";
   std::string value;
   ASSERT_TRUE(pc_dict.GetString(
       Statistic("googAvailableSendBandwidth", kBweStatsKey), &value));
-  perf_test::PrintResult(
-      "bwe_stats", modifier, "available_send_bw", value, "bit/s", false);
+  perf_test::PrintResult("bwe_stats", video_modifier, "available_send_bw",
+                         value, "bit/s", false);
   ASSERT_TRUE(pc_dict.GetString(
       Statistic("googAvailableReceiveBandwidth", kBweStatsKey), &value));
-  perf_test::PrintResult(
-      "bwe_stats", modifier, "available_recv_bw", value, "bit/s", false);
+  perf_test::PrintResult("bwe_stats", video_modifier, "available_recv_bw",
+                         value, "bit/s", false);
   ASSERT_TRUE(pc_dict.GetString(
       Statistic("googTargetEncBitrate", kBweStatsKey), &value));
-  perf_test::PrintResult(
-      "bwe_stats", modifier, "target_enc_bitrate", value, "bit/s", false);
+  perf_test::PrintResult("bwe_stats", video_modifier, "target_enc_bitrate",
+                         value, "bit/s", false);
   ASSERT_TRUE(pc_dict.GetString(
       Statistic("googActualEncBitrate", kBweStatsKey), &value));
-  perf_test::PrintResult(
-      "bwe_stats", modifier, "actual_enc_bitrate", value, "bit/s", false);
+  perf_test::PrintResult("bwe_stats", video_modifier, "actual_enc_bitrate",
+                         value, "bit/s", false);
   ASSERT_TRUE(pc_dict.GetString(
       Statistic("googTransmitBitrate", kBweStatsKey), &value));
-  perf_test::PrintResult(
-      "bwe_stats", modifier, "transmit_bitrate", value, "bit/s",false);
+  perf_test::PrintResult("bwe_stats", video_modifier, "transmit_bitrate", value,
+                         "bit/s", false);
 }
 
 void PrintMetricsForAllStreams(const base::DictionaryValue& pc_dict,
-                               const std::string& modifier) {
+                               const std::string& modifier,
+                               const std::string& video_codec) {
+  std::string video_modifier =
+      video_codec.empty() ? modifier : modifier + "_" + video_codec;
   const base::DictionaryValue* stats_dict;
   ASSERT_TRUE(pc_dict.GetDictionary("stats", &stats_dict));
   std::set<std::string> ssrc_identifiers = FindAllSsrcIdentifiers(*stats_dict);
@@ -249,8 +255,8 @@
     bool did_recognize_stream_type =
         MaybePrintResultsForAudioReceive(ssrc, pc_dict, modifier) ||
         MaybePrintResultsForAudioSend(ssrc, pc_dict, modifier) ||
-        MaybePrintResultsForVideoReceive(ssrc, pc_dict, modifier) ||
-        MaybePrintResultsForVideoSend(ssrc, pc_dict, modifier);
+        MaybePrintResultsForVideoReceive(ssrc, pc_dict, video_modifier) ||
+        MaybePrintResultsForVideoSend(ssrc, pc_dict, video_modifier);
     ASSERT_TRUE(did_recognize_stream_type) << "Failed to figure out which "
                                               "kind of stream SSRC " << ssrc
                                            << " is. ";
diff --git a/chrome/browser/media/webrtc_browsertest_perf.h b/chrome/browser/media/webrtc_browsertest_perf.h
index b2595e3..8c9fb944c 100644
--- a/chrome/browser/media/webrtc_browsertest_perf.h
+++ b/chrome/browser/media/webrtc_browsertest_perf.h
@@ -24,10 +24,14 @@
 // stats data and a |modifier| to append to each result bucket. For instance, if
 // the modifier is '_oneway', the rtt stat will be logged as goog_rtt in
 // the video_tx_oneway bucket.
+// If |video_codec| is a non-empty string, the codec name is appended last for
+// video metrics, e.g. 'video_tx_oneway_VP9'.
 void PrintBweForVideoMetrics(const base::DictionaryValue& pc_dict,
-                             const std::string& modifier);
+                             const std::string& modifier,
+                             const std::string& video_codec);
 void PrintMetricsForAllStreams(const base::DictionaryValue& pc_dict,
-                               const std::string& modifier);
+                               const std::string& modifier,
+                               const std::string& video_codec);
 
 }  // namespace test
 
diff --git a/chrome/browser/password_manager/native_backend_gnome_x.cc b/chrome/browser/password_manager/native_backend_gnome_x.cc
index 53c671b9..a0d4f1f6 100644
--- a/chrome/browser/password_manager/native_backend_gnome_x.cc
+++ b/chrome/browser/password_manager/native_backend_gnome_x.cc
@@ -185,6 +185,10 @@
   ScopedVector<PasswordForm> forms;
   password_manager::PSLDomainMatchMetric psl_domain_match_metric =
       password_manager::PSL_DOMAIN_MATCH_NONE;
+  const bool allow_psl_match =
+      lookup_form && password_manager::ShouldPSLDomainMatchingApply(
+                         password_manager::GetRegistryControlledDomain(
+                             GURL(lookup_form->signon_realm)));
   for (GList* element = g_list_first(found); element;
        element = g_list_next(element)) {
     GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
@@ -193,15 +197,21 @@
     scoped_ptr<PasswordForm> form(FormFromAttributes(attrs));
     if (form) {
       if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
-        // This is not an exact match, we try PSL matching.
         if (lookup_form->scheme != PasswordForm::SCHEME_HTML ||
-            form->scheme != PasswordForm::SCHEME_HTML ||
-            !(password_manager::IsPublicSuffixDomainMatch(
-                lookup_form->signon_realm, form->signon_realm))) {
+            form->scheme != PasswordForm::SCHEME_HTML)
+          continue;  // Ignore non-HTML matches.
+        // This is not an exact match, we try PSL matching and federated match.
+        if (allow_psl_match &&
+            password_manager::IsPublicSuffixDomainMatch(
+                form->signon_realm, lookup_form->signon_realm)) {
+          psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
+          form->is_public_suffix_match = true;
+        } else if (!form->federation_origin.unique() &&
+                   password_manager::IsFederatedMatch(form->signon_realm,
+                                                      lookup_form->origin)) {
+        } else {
           continue;
         }
-        psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
-        form->is_public_suffix_match = true;
       }
       if (data->secret) {
         form->password_value = UTF8ToUTF16(data->secret);
@@ -214,15 +224,11 @@
     }
   }
   if (lookup_form) {
-    const GURL signon_realm(lookup_form->signon_realm);
-    std::string registered_domain =
-        password_manager::GetRegistryControlledDomain(signon_realm);
-    UMA_HISTOGRAM_ENUMERATION(
-        "PasswordManager.PslDomainMatchTriggering",
-        password_manager::ShouldPSLDomainMatchingApply(registered_domain)
-            ? psl_domain_match_metric
-            : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
-        password_manager::PSL_DOMAIN_MATCH_COUNT);
+    UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering",
+                              allow_psl_match
+                                  ? psl_domain_match_metric
+                                  : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
+                              password_manager::PSL_DOMAIN_MATCH_COUNT);
   }
   return forms;
 }
@@ -426,7 +432,9 @@
   ScopedAttributeList attrs(gnome_keyring_attribute_list_new());
   if (!password_manager::ShouldPSLDomainMatchingApply(
           password_manager::GetRegistryControlledDomain(
-              GURL(form.signon_realm)))) {
+              GURL(form.signon_realm))) &&
+      form.scheme != PasswordForm::SCHEME_HTML) {
+    // Don't retrieve the PSL matched and federated credentials.
     AppendString(&attrs, "signon_realm", form.signon_realm);
   }
   AppendString(&attrs, "application", app_string);
diff --git a/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc b/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
index 36c0a36..85e027c7 100644
--- a/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
+++ b/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
@@ -884,6 +884,14 @@
   CheckPSLUpdate(UPDATE_BY_ADDLOGIN);
 }
 
+TEST_F(NativeBackendGnomeTest, FetchFederatedCredential) {
+  other_auth_.signon_realm = "federation://www.example.com/google.com";
+  other_auth_.federation_origin = url::Origin(GURL("https://google.com/"));
+  EXPECT_TRUE(CheckCredentialAvailability(other_auth_,
+                                          GURL("http://www.example.com/"),
+                                          PasswordForm::SCHEME_HTML, nullptr));
+}
+
 TEST_F(NativeBackendGnomeTest, BasicUpdateLogin) {
   NativeBackendGnome backend(42);
   backend.Init();
diff --git a/chrome/browser/password_manager/native_backend_libsecret.cc b/chrome/browser/password_manager/native_backend_libsecret.cc
index 8c653564..9887500 100644
--- a/chrome/browser/password_manager/native_backend_libsecret.cc
+++ b/chrome/browser/password_manager/native_backend_libsecret.cc
@@ -541,7 +541,8 @@
   if (lookup_form &&
       !password_manager::ShouldPSLDomainMatchingApply(
           password_manager::GetRegistryControlledDomain(
-              GURL(lookup_form->signon_realm))))
+              GURL(lookup_form->signon_realm))) &&
+      lookup_form->scheme != PasswordForm::SCHEME_HTML)
     attrs.Append("signon_realm", lookup_form->signon_realm);
 
   GError* error = nullptr;
@@ -631,6 +632,10 @@
   password_manager::PSLDomainMatchMetric psl_domain_match_metric =
       password_manager::PSL_DOMAIN_MATCH_NONE;
   GError* error = nullptr;
+  const bool allow_psl_match =
+      lookup_form && password_manager::ShouldPSLDomainMatchingApply(
+                         password_manager::GetRegistryControlledDomain(
+                             GURL(lookup_form->signon_realm)));
   for (GList* element = g_list_first(found); element != nullptr;
        element = g_list_next(element)) {
     SecretItem* secretItem = static_cast<SecretItem*>(element->data);
@@ -646,15 +651,21 @@
     g_hash_table_unref(attrs);
     if (form) {
       if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
-        // This is not an exact match, we try PSL matching.
         if (lookup_form->scheme != PasswordForm::SCHEME_HTML ||
-            form->scheme != PasswordForm::SCHEME_HTML ||
-            !(password_manager::IsPublicSuffixDomainMatch(
-                lookup_form->signon_realm, form->signon_realm))) {
+            form->scheme != PasswordForm::SCHEME_HTML)
+          continue;
+        // This is not an exact match, we try PSL matching and federated match.
+        if (allow_psl_match &&
+            password_manager::IsPublicSuffixDomainMatch(
+                form->signon_realm, lookup_form->signon_realm)) {
+          psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
+          form->is_public_suffix_match = true;
+        } else if (!form->federation_origin.unique() &&
+                   password_manager::IsFederatedMatch(form->signon_realm,
+                                                      lookup_form->origin)) {
+        } else {
           continue;
         }
-        psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
-        form->is_public_suffix_match = true;
       }
       SecretValue* secretValue = secret_item_get_secret(secretItem);
       if (secretValue) {
@@ -670,15 +681,11 @@
   }
 
   if (lookup_form) {
-    const GURL signon_realm(lookup_form->signon_realm);
-    std::string registered_domain =
-        password_manager::GetRegistryControlledDomain(signon_realm);
-    UMA_HISTOGRAM_ENUMERATION(
-        "PasswordManager.PslDomainMatchTriggering",
-        password_manager::ShouldPSLDomainMatchingApply(registered_domain)
-            ? psl_domain_match_metric
-            : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
-        password_manager::PSL_DOMAIN_MATCH_COUNT);
+    UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering",
+                              allow_psl_match
+                                  ? psl_domain_match_metric
+                                  : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
+                              password_manager::PSL_DOMAIN_MATCH_COUNT);
   }
   g_list_free(found);
   return forms;
diff --git a/chrome/browser/password_manager/native_backend_libsecret_unittest.cc b/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
index 2fa1cf4e..d032803 100644
--- a/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
+++ b/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
@@ -694,6 +694,14 @@
   CheckPSLUpdate(UPDATE_BY_ADDLOGIN);
 }
 
+TEST_F(NativeBackendLibsecretTest, FetchFederatedCredential) {
+  other_auth_.signon_realm = "federation://www.example.com/google.com";
+  other_auth_.federation_origin = url::Origin(GURL("https://google.com/"));
+  EXPECT_TRUE(CheckCredentialAvailability(other_auth_,
+                                          GURL("http://www.example.com/"),
+                                          PasswordForm::SCHEME_HTML, nullptr));
+}
+
 TEST_F(NativeBackendLibsecretTest, BasicUpdateLogin) {
   NativeBackendLibsecret backend(42);
 
diff --git a/chrome/browser/platform_util_chromeos.cc b/chrome/browser/platform_util_chromeos.cc
index 67eb661..0964356 100644
--- a/chrome/browser/platform_util_chromeos.cc
+++ b/chrome/browser/platform_util_chromeos.cc
@@ -59,11 +59,11 @@
   }
 
   Browser* browser = chrome::FindTabbedBrowser(profile, false);
-  chrome::ShowMessageBox(
+  chrome::ShowWarningMessageBox(
       browser ? browser->window()->GetNativeWindow() : nullptr,
       l10n_util::GetStringFUTF16(IDS_FILE_BROWSER_ERROR_VIEWING_FILE_TITLE,
                                  path.BaseName().AsUTF16Unsafe()),
-      l10n_util::GetStringUTF16(message_id), chrome::MESSAGE_BOX_TYPE_WARNING);
+      l10n_util::GetStringUTF16(message_id));
 }
 
 }  // namespace
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 5e6cb29..fa527e2a 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -1068,8 +1068,9 @@
     : public ExternalProtocolHandler::Delegate {
  public:
   // ExternalProtocolHandler::Delegate implementation.
-  shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-      shell_integration::DefaultWebClientObserver* observer,
+  scoped_refptr<shell_integration::DefaultProtocolClientWorker>
+  CreateShellWorker(
+      const shell_integration::DefaultWebClientWorkerCallback& callback,
       const std::string& protocol) override {
     NOTREACHED();
     // This will crash, but it shouldn't get this far with BlockState::BLOCK
diff --git a/chrome/browser/printing/print_error_dialog.cc b/chrome/browser/printing/print_error_dialog.cc
index 39fab57ae..0510dbf 100644
--- a/chrome/browser/printing/print_error_dialog.cc
+++ b/chrome/browser/printing/print_error_dialog.cc
@@ -17,10 +17,10 @@
 
 void ShowPrintErrorDialogTask() {
   Browser* browser = chrome::FindLastActive();
-  ShowMessageBox(browser ? browser->window()->GetNativeWindow() : NULL,
-                 l10n_util::GetStringUTF16(IDS_PRINT_SPOOL_FAILED_TITLE_TEXT),
-                 l10n_util::GetStringUTF16(IDS_PRINT_SPOOL_FAILED_ERROR_TEXT),
-                 MESSAGE_BOX_TYPE_WARNING);
+  ShowWarningMessageBox(
+      browser ? browser->window()->GetNativeWindow() : NULL,
+      l10n_util::GetStringUTF16(IDS_PRINT_SPOOL_FAILED_TITLE_TEXT),
+      l10n_util::GetStringUTF16(IDS_PRINT_SPOOL_FAILED_ERROR_TEXT));
 }
 
 }  // namespace
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 83917c3..fe575081 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -55,8 +55,7 @@
   // Block opening dialog from nested task.
   base::AutoReset<bool> auto_reset(&is_dialog_shown, true);
 
-  chrome::ShowMessageBox(nullptr, base::string16(), message,
-                         chrome::MESSAGE_BOX_TYPE_WARNING);
+  chrome::ShowWarningMessageBox(nullptr, base::string16(), message);
 }
 
 }  // namespace
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index a0b6266a..3352156 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -173,10 +173,9 @@
 }
 
 bool DisplayShouldKillMessageBox() {
-  return chrome::ShowMessageBox(
+  return chrome::ShowQuestionMessageBox(
              NULL, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-             l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE),
-             chrome::MESSAGE_BOX_TYPE_QUESTION) !=
+             l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE)) !=
          chrome::MESSAGE_BOX_RESULT_NO;
 }
 
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc
index d4f59b6..89b57ac 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.cc
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -238,12 +238,10 @@
   main_context->set_channel_id_service(channel_id_service);
 
   using content::CookieStoreConfig;
-  main_context->set_cookie_store(
-      CreateCookieStore(CookieStoreConfig(
-          base::FilePath(),
-          CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
-          NULL,
-          profile_params->cookie_monster_delegate.get())));
+  main_cookie_store_ = CreateCookieStore(CookieStoreConfig(
+      base::FilePath(), CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, NULL,
+      profile_params->cookie_monster_delegate.get()));
+  main_context->set_cookie_store(main_cookie_store_.get());
 
   http_network_session_ = CreateHttpNetworkSession(*profile_params);
   main_http_factory_ = CreateMainHttpFactory(
@@ -298,9 +296,8 @@
   content::CookieStoreConfig cookie_config;
   // Enable cookies for chrome-extension URLs.
   cookie_config.cookieable_schemes.push_back(extensions::kExtensionScheme);
-  net::CookieStore* extensions_cookie_store =
-      content::CreateCookieStore(cookie_config);
-  extensions_context->set_cookie_store(extensions_cookie_store);
+  extensions_cookie_store_ = content::CreateCookieStore(cookie_config);
+  extensions_context->set_cookie_store(extensions_cookie_store_.get());
 
   scoped_ptr<net::URLRequestJobFactoryImpl> extensions_job_factory(
       new net::URLRequestJobFactoryImpl());
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h
index 87355a9..17cd658e7 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.h
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.h
@@ -19,6 +19,7 @@
 class Profile;
 
 namespace net {
+class CookieStore;
 class FtpTransactionFactory;
 class HttpNetworkSession;
 class HttpTransactionFactory;
@@ -149,6 +150,9 @@
   mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
   mutable scoped_ptr<net::FtpTransactionFactory> ftp_factory_;
 
+  mutable scoped_ptr<net::CookieStore> main_cookie_store_;
+  mutable scoped_ptr<net::CookieStore> extensions_cookie_store_;
+
   mutable scoped_ptr<net::URLRequestJobFactory> main_job_factory_;
   mutable scoped_ptr<net::URLRequestJobFactory> extensions_job_factory_;
 
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 843d1390..0e030d6 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -60,6 +60,7 @@
 #include "extensions/common/constants.h"
 #include "net/base/cache_type.h"
 #include "net/base/sdch_manager.h"
+#include "net/cookies/cookie_store.h"
 #include "net/ftp/ftp_network_layer.h"
 #include "net/http/http_cache.h"
 #include "net/http/http_network_session.h"
@@ -483,23 +484,19 @@
   main_context->set_backoff_manager(
       io_thread_globals->url_request_backoff_manager.get());
 
-  scoped_refptr<net::CookieStore> cookie_store = NULL;
-  net::ChannelIDService* channel_id_service = NULL;
+  net::ChannelIDService* channel_id_service = nullptr;
 
   // Set up cookie store.
-  if (!cookie_store.get()) {
-    DCHECK(!lazy_params_->cookie_path.empty());
+  DCHECK(!lazy_params_->cookie_path.empty());
 
-    content::CookieStoreConfig cookie_config(
-        lazy_params_->cookie_path,
-        lazy_params_->session_cookie_mode,
-        lazy_params_->special_storage_policy.get(),
-        profile_params->cookie_monster_delegate.get());
-    cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate();
-    cookie_store = content::CreateCookieStore(cookie_config);
-  }
+  content::CookieStoreConfig cookie_config(
+      lazy_params_->cookie_path, lazy_params_->session_cookie_mode,
+      lazy_params_->special_storage_policy.get(),
+      profile_params->cookie_monster_delegate.get());
+  cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate();
+  main_cookie_store_ = content::CreateCookieStore(cookie_config);
 
-  main_context->set_cookie_store(cookie_store.get());
+  main_context->set_cookie_store(main_cookie_store_.get());
 
   // Set up server bound cert service.
   if (!channel_id_service) {
@@ -591,9 +588,8 @@
   cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate();
   // Enable cookies for chrome-extension URLs.
   cookie_config.cookieable_schemes.push_back(extensions::kExtensionScheme);
-  net::CookieStore* extensions_cookie_store =
-      content::CreateCookieStore(cookie_config);
-  extensions_context->set_cookie_store(extensions_cookie_store);
+  extensions_cookie_store_ = content::CreateCookieStore(cookie_config);
+  extensions_context->set_cookie_store(extensions_cookie_store_.get());
 
   scoped_ptr<net::URLRequestJobFactoryImpl> extensions_job_factory(
       new net::URLRequestJobFactoryImpl());
@@ -644,28 +640,25 @@
   scoped_ptr<net::HttpCache> app_http_cache =
       CreateHttpFactory(http_network_session_.get(), std::move(app_backend));
 
-  scoped_refptr<net::CookieStore> cookie_store = NULL;
+  scoped_ptr<net::CookieStore> cookie_store;
   if (partition_descriptor.in_memory) {
     cookie_store = content::CreateCookieStore(content::CookieStoreConfig());
-  }
-
-  // Use an app-specific cookie store.
-  if (!cookie_store.get()) {
+  } else {
+    // Use an app-specific cookie store.
     DCHECK(!cookie_path.empty());
 
     // TODO(creis): We should have a cookie delegate for notifying the cookie
     // extensions API, but we need to update it to understand isolated apps
     // first.
     content::CookieStoreConfig cookie_config(
-        cookie_path,
-        content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
-        NULL, NULL);
+        cookie_path, content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
+        nullptr, nullptr);
     cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate();
     cookie_store = content::CreateCookieStore(cookie_config);
   }
 
   // Transfer ownership of the cookies and cache to AppRequestContext.
-  context->SetCookieStore(cookie_store.get());
+  context->SetCookieStore(std::move(cookie_store));
   context->SetHttpTransactionFactory(std::move(app_http_cache));
 
   scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h
index f21e4ea..ccdd27c0 100644
--- a/chrome/browser/profiles/profile_impl_io_data.h
+++ b/chrome/browser/profiles/profile_impl_io_data.h
@@ -31,6 +31,7 @@
 
 namespace net {
 class CookieCryptoDelegate;
+class CookieStore;
 class FtpTransactionFactory;
 class HttpNetworkSession;
 class HttpServerProperties;
@@ -223,6 +224,9 @@
   // destruction ordering.
   mutable net::HttpServerPropertiesManager* http_server_properties_manager_;
 
+  mutable scoped_ptr<net::CookieStore> main_cookie_store_;
+  mutable scoped_ptr<net::CookieStore> extensions_cookie_store_;
+
   mutable scoped_ptr<chrome_browser_net::Predictor> predictor_;
 
   mutable scoped_ptr<net::URLRequestContext> media_request_context_;
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index f34a67ba..57f2fd3 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -568,9 +568,9 @@
 }
 
 void ProfileIOData::AppRequestContext::SetCookieStore(
-    net::CookieStore* cookie_store) {
-  cookie_store_ = cookie_store;
-  set_cookie_store(cookie_store);
+    scoped_ptr<net::CookieStore> cookie_store) {
+  cookie_store_ = std::move(cookie_store);
+  set_cookie_store(cookie_store_.get());
 }
 
 void ProfileIOData::AppRequestContext::SetHttpTransactionFactory(
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index 3413ab7b..afe106a 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -267,7 +267,7 @@
    public:
     AppRequestContext();
 
-    void SetCookieStore(net::CookieStore* cookie_store);
+    void SetCookieStore(scoped_ptr<net::CookieStore> cookie_store);
     void SetHttpTransactionFactory(
         scoped_ptr<net::HttpTransactionFactory> http_factory);
     void SetJobFactory(scoped_ptr<net::URLRequestJobFactory> job_factory);
@@ -275,7 +275,7 @@
    private:
     ~AppRequestContext() override;
 
-    scoped_refptr<net::CookieStore> cookie_store_;
+    scoped_ptr<net::CookieStore> cookie_store_;
     scoped_ptr<net::HttpTransactionFactory> http_factory_;
     scoped_ptr<net::URLRequestJobFactory> job_factory_;
   };
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js
index 531a0ad..5b23294 100644
--- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js
+++ b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js
@@ -16,7 +16,7 @@
 
 /**
  * The current PDF we're processing, or null if we're not processing one.
- * @type {HTMLEmbedElement}
+ * @type {Element}
  */
 cvox.PdfProcessor.pdfEmbed = null;
 
diff --git a/chrome/browser/resources/chromeos/chromevox/common/aria_util.js b/chrome/browser/resources/chromeos/chromevox/common/aria_util.js
index 1c1d9a7..b73ab77 100644
--- a/chrome/browser/resources/chromeos/chromevox/common/aria_util.js
+++ b/chrome/browser/resources/chromeos/chromevox/common/aria_util.js
@@ -593,7 +593,7 @@
 /**
  * Recursively finds the first node(s) that match the role.
  *
- * @param {Element} current The node to start looking at.
+ * @param {Node} current The node to start looking at.
  * @param {Array<string>} role The role(s) to match.
  * @return {Array<Element>} The array of matching nodes.
  */
diff --git a/chrome/browser/resources/chromeos/chromevox/common/description_util.js b/chrome/browser/resources/chromeos/chromevox/common/description_util.js
index d7bece47..c6145fc 100644
--- a/chrome/browser/resources/chromeos/chromevox/common/description_util.js
+++ b/chrome/browser/resources/chromeos/chromevox/common/description_util.js
@@ -301,8 +301,8 @@
 /**
  * Returns the full descriptions of the child nodes that would be gotten by an
  * object walker.
- * @param {?Element} prevnode The previous element if there is one.
- * @param {!Element} node The target element.
+ * @param {?Node} prevnode The previous element if there is one.
+ * @param {!Node} node The target element.
  * @return {!Array<!cvox.NavDescription>} The descriptions.
  */
 cvox.DescriptionUtil.getFullDescriptionsFromChildren =
@@ -330,21 +330,22 @@
   if (!curSel) {
     return descriptions;
   }
-  node = cvox.DescriptionUtil.subWalker_.sync(curSel).start.node;
-  curSel = cvox.CursorSelection.fromNode(node);
+  var newNode = cvox.DescriptionUtil.subWalker_.sync(curSel).start.node;
+  curSel = cvox.CursorSelection.fromNode(newNode);
   if (!curSel) {
     return descriptions;
   }
-  while (cvox.DomUtil.isDescendantOfNode(node, originalNode)) {
+  while (newNode && cvox.DomUtil.isDescendantOfNode(newNode, originalNode)) {
     descriptions = descriptions.concat(
-        cvox.DescriptionUtil.getFullDescriptionsFromChildren(prevnode, node));
+        cvox.DescriptionUtil.getFullDescriptionsFromChildren(
+            prevnode, newNode));
     curSel = cvox.DescriptionUtil.subWalker_.next(curSel);
     if (!curSel) {
       break;
     }
     curSel = /** @type {!cvox.CursorSelection} */ (curSel);
-    prevnode = node;
-    node = curSel.start.node;
+    prevnode = newNode;
+    newNode = curSel.start.node;
   }
   return descriptions;
 };
@@ -451,10 +452,13 @@
 // TODO(sorge): Bad naming...this thing returns *multiple* descriptions.
 /**
  * Generates a description for a math node.
- * @param {!Node} node The given node.
+ * @param {Node} node The given node.
  * @return {!Array<cvox.NavDescription>} A list of Navigation descriptions.
  */
 cvox.DescriptionUtil.getMathDescription = function(node) {
+  if (!node) {
+    return [];
+  }
   // TODO (sorge) This function should evantually be removed. Descriptions
   //     should come directly from the speech rule engine, taking information on
   //     verbosity etc. into account.
diff --git a/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js b/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js
index 8927c1d..7b6c0a4e 100644
--- a/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js
+++ b/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js
@@ -60,16 +60,16 @@
 
 /**
  * The row index of the corresponding active table cell
- * @type {?number}
+ * @type {number}
  */
-ShadowTableNode.prototype.i;
+ShadowTableNode.prototype.i = -1;
 
 
 /**
  * The column index of the corresponding active table cell
- * @type {?number}
+ * @type {number}
  */
-ShadowTableNode.prototype.j;
+ShadowTableNode.prototype.j = -1;
 
 
 /**
@@ -261,10 +261,13 @@
 /**
  * Finds the cell cursor containing the specified node within the table.
  * Returns null if there is no close cell.
- * @param {!Node} node The node for which to find the cursor.
+ * @param {Node} node The node for which to find the cursor.
  * @return {Array<number>} The table index for the node.
  */
 cvox.TraverseTable.prototype.findNearestCursor = function(node) {
+  if (!node) {
+    return null;
+  }
   // TODO (stoarca): The current structure for representing the
   // shadow table is not optimal for this query, but it's not urgent
   // since this only gets executed at most once per user action.
diff --git a/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js b/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js
index 19faec6..f360aefc 100644
--- a/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js
+++ b/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js
@@ -39,7 +39,9 @@
 cvox.AbstractNodeWalker.prototype.next = function(sel) {
   var r = sel.isReversed();
   var node = sel.end.node || document.body;
-
+  if (!node) {
+    return null;
+  }
   do {
     node = cvox.DomUtil.directedNextLeafLikeNode(node, r,
         goog.bind(this.stopNodeDescent, this));
@@ -87,7 +89,7 @@
     node = node.parentNode;
   }
 
-  while (!this.stopNodeDescent(node)) {
+  while (node && !this.stopNodeDescent(node)) {
     node = cvox.DomUtil.directedFirstChild(node, r);
   }
 
diff --git a/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js b/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js
index b30dc53..351f167 100644
--- a/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js
+++ b/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js
@@ -172,11 +172,14 @@
  * Determines if node should force a line break.
  * This is used for elements with unusual semantics, such as multi-line
  * text fields, where the behaviour would otherwise be confusing.
- * @param {!Node} node Node.
+ * @param {Node} node Node.
  * @return {boolean} True if the node should appear next to a line break.
  * @private
  */
 cvox.LayoutLineWalker.prototype.wantsOwnLine_ = function(node) {
+  if (!node) {
+    return false;
+  }
   return node instanceof HTMLTextAreaElement ||
       node.parentNode instanceof HTMLTextAreaElement;
 };
diff --git a/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js b/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js
index fa629cf..8e6a0e2 100644
--- a/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js
+++ b/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js
@@ -384,6 +384,9 @@
  * @private
  */
 cvox.TableWalker.prototype.goTo_ = function(sel, f) {
+  if (!sel.end.node) {
+    return null;
+  }
   this.tt.initialize(this.getTableNode_(sel));
   var position = this.tt.findNearestCursor(sel.end.node);
   if (!position) {
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp b/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp
index 8ccbdec..57d18f6 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp
@@ -16,6 +16,7 @@
     {
       'target_name': 'passwords_section',
       'dependencies': [
+        '<(DEPTH)/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp:cr_shared_menu',
         '<(EXTERNS_GYP):passwords_private',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css
index c11ea76..185ea261 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css
@@ -7,6 +7,16 @@
   flex-direction: column;
 }
 
+.list-frame {
+  margin-top: 8px;
+}
+
+/* TODO(hcarmona): Grow menu width by 64px if content is wider */
+div.menu-item {
+  -webkit-padding-start: 24px;
+  width: 104px;
+}
+
 iron-list {
   -webkit-padding-start: 16px;
   flex: 1;
@@ -29,7 +39,3 @@
   };
   width: 150px;
 }
-
-.list-frame {
-  margin-top: 3%;
-}
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html
index 5094d9c..e638bde 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html
@@ -2,6 +2,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_shared_menu/cr_shared_menu.html">
 <link rel="import" href="chrome://md-settings/settings_shared_css.html">
 
 <dom-module id="passwords-section">
@@ -17,16 +18,23 @@
           <div class="list-item two-line">
             <div class="start">
               <div id="originUrl">[[item.loginPair.originUrl]]</div>
-              <div id="username" class="secondary">[[item.loginPair.username]]</div>
+              <div id="username"
+                  class="secondary">[[item.loginPair.username]]</div>
             </div>
-            <!--TODO(hcarmona): Update password so that it is editable.
-                #password is type password and disabled in order to match UI.-->
+            <!-- Password type and disabled in order to match mock. -->
             <paper-input id="password" type="password" disabled
                 value="[[getEmptyPassword_(item.numCharactersInPassword)]]">
             </paper-input>
+            <paper-icon-button icon="more-vert" on-tap="toggleMenu_"
+                i18n-values="alt:passwordMenu" tabindex$="[[tabIndex]]">
+            </paper-icon-button>
           </div>
         </template>
       </iron-list>
+      <cr-shared-menu id="menu">
+        <div class="list-item menu-item" i18n-content="editPassword"></div>
+        <div class="list-item menu-item" i18n-content="removePassword"></div>
+      </cr-shared-menu>
     </div>
     <div class="list-frame">
       <div class="secondary" i18n-content="passwordExceptionsHeading"></div>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
index 7f7dfd4..6459dc06 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
@@ -36,6 +36,11 @@
     },
   },
 
+  listeners: {
+    'passwordList.scroll': 'closeMenu_',
+    'tap': 'closeMenu_',
+  },
+
   /**
    * Fires an event that should delete the passwordException.
    * @param {!{model: !{item: !string}}} e The polymer event.
@@ -52,5 +57,24 @@
    * @private
    */
   getEmptyPassword_: function(length) { return ' '.repeat(length); },
+
+  /**
+   * Toggles the overflow menu.
+   * @param {Event} e
+   * @private
+   */
+  toggleMenu_: function(e) {
+    this.$.menu.toggleMenu(Polymer.dom(e).localTarget);
+    // Prevent the tap event from closing the menu.
+    e.stopPropagation();
+  },
+
+  /**
+   * Closes the overflow menu.
+   * @private
+   */
+  closeMenu_: function() {
+    this.$.menu.closeMenu();
+  },
 });
 })();
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index 0a443b2..3aa0ae8 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -129,6 +129,8 @@
 
   scoped_refptr<net::URLRequestContextGetter> system_context_getter_;
 
+  scoped_ptr<net::CookieStore> safe_browsing_cookie_store_;
+
   scoped_ptr<net::URLRequestContext> safe_browsing_request_context_;
 
   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
@@ -156,11 +158,13 @@
       safe_browsing_request_context_->CopyFrom(
           system_context_getter_->GetURLRequestContext());
     }
-    safe_browsing_request_context_->set_cookie_store(
+    safe_browsing_cookie_store_ =
         content::CreateCookieStore(content::CookieStoreConfig(
             CookieFilePath(),
             content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, nullptr,
-            nullptr)));
+            nullptr));
+    safe_browsing_request_context_->set_cookie_store(
+        safe_browsing_cookie_store_.get());
   }
 
   return safe_browsing_request_context_.get();
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc
index acbec24..72af6aa 100644
--- a/chrome/browser/sessions/session_data_deleter.cc
+++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -11,7 +11,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
-#include "chrome/browser/profiles/profile_io_data.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -21,6 +21,7 @@
 #include "net/cookies/cookie_store.h"
 #include "net/cookies/cookie_util.h"
 #include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
 #include "storage/browser/quota/special_storage_policy.h"
 
 namespace {
@@ -35,8 +36,9 @@
   SessionDataDeleter(storage::SpecialStoragePolicy* storage_policy,
                      bool delete_only_by_session_only_policy);
 
-  void Run(content::StoragePartition* storage_partition,
-           ProfileIOData* profile_io_data);
+  void Run(
+      content::StoragePartition* storage_partition,
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
 
  private:
   friend class base::RefCountedThreadSafe<SessionDataDeleter>;
@@ -52,16 +54,18 @@
   // |delete_only_by_session_only_policy_| is false. Once completed or skipped,
   // this arranges for DeleteSessionOnlyOriginCookies to be called with a list
   // of all remaining cookies.
-  void DeleteSessionCookiesOnIOThread(ProfileIOData* profile_io_data);
+  void DeleteSessionCookiesOnIOThread(
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
 
   // Called when all session-only cookies have been deleted.
-  void DeleteSessionCookiesDone(int num_deleted);
+  void DeleteSessionCookiesDone(net::CookieStore* cookie_store,
+                                int num_deleted);
 
   // Deletes the cookies in |cookies| that are for origins which are
   // session-only.
-  void DeleteSessionOnlyOriginCookies(const net::CookieList& cookies);
+  void DeleteSessionOnlyOriginCookies(net::CookieStore* cookie_store,
+                                      const net::CookieList& cookies);
 
-  scoped_refptr<net::CookieStore> cookie_store_;
   scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
   const bool delete_only_by_session_only_policy_;
 
@@ -75,8 +79,9 @@
       delete_only_by_session_only_policy_(delete_only_by_session_only_policy) {
 }
 
-void SessionDataDeleter::Run(content::StoragePartition* storage_partition,
-                             ProfileIOData* profile_io_data) {
+void SessionDataDeleter::Run(
+    content::StoragePartition* storage_partition,
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
   if (storage_policy_.get() && storage_policy_->HasSessionOnlyOrigins()) {
     storage_partition->GetDOMStorageContext()->GetLocalStorageUsage(
         base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage,
@@ -84,11 +89,9 @@
                    storage_partition));
   }
   content::BrowserThread::PostTask(
-      content::BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread,
-                 this,
-                 profile_io_data));
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread, this,
+                 url_request_context_getter));
 }
 
 SessionDataDeleter::~SessionDataDeleter() {}
@@ -107,38 +110,50 @@
 }
 
 void SessionDataDeleter::DeleteSessionCookiesOnIOThread(
-    ProfileIOData* profile_io_data) {
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   net::URLRequestContext* request_context =
-      profile_io_data->GetMainRequestContext();
-  cookie_store_ = request_context->cookie_store();
+      url_request_context_getter->GetURLRequestContext();
+  // Shouldn't happen, but best not to depend on the URLRequestContext's
+  // lifetime
+  if (!request_context)
+    return;
+  net::CookieStore* cookie_store = request_context->cookie_store();
+  // If these callbacks are invoked, |cookie_store| is guaranteed to still
+  // exist, since deleting the CookieStore will cancel pending callbacks.
   if (delete_only_by_session_only_policy_) {
-    cookie_store_->GetAllCookiesAsync(
-        base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
+    cookie_store->GetAllCookiesAsync(
+        base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this,
+                   base::Unretained(cookie_store)));
   } else {
-    cookie_store_->DeleteSessionCookiesAsync(
-        base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this));
+    cookie_store->DeleteSessionCookiesAsync(
+        base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this,
+                   base::Unretained(cookie_store)));
   }
 }
 
-void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted) {
-  cookie_store_->GetAllCookiesAsync(
-      base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
+void SessionDataDeleter::DeleteSessionCookiesDone(
+    net::CookieStore* cookie_store,
+    int num_deleted) {
+  // If these callbacks are invoked, |cookie_store| is gauranteed to still
+  // exist, since deleting the CookieStore will cancel pending callbacks.
+  cookie_store->GetAllCookiesAsync(
+      base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this,
+                 base::Unretained(cookie_store)));
 }
 
 void SessionDataDeleter::DeleteSessionOnlyOriginCookies(
+    net::CookieStore* cookie_store,
     const net::CookieList& cookies) {
   if (!storage_policy_.get() || !storage_policy_->HasSessionOnlyOrigins())
     return;
 
-  for (net::CookieList::const_iterator it = cookies.begin();
-       it != cookies.end();
-       ++it) {
+  for (const auto& cookie : cookies) {
     GURL url =
-        net::cookie_util::CookieOriginToURL(it->Domain(), it->IsSecure());
+        net::cookie_util::CookieOriginToURL(cookie.Domain(), cookie.IsSecure());
     if (!storage_policy_->IsStorageSessionOnly(url))
       continue;
-    cookie_store_->DeleteCanonicalCookieAsync(*it, base::Bind(CookieDeleted));
+    cookie_store->DeleteCanonicalCookieAsync(cookie, base::Bind(CookieDeleted));
   }
 }
 
@@ -163,7 +178,6 @@
   scoped_refptr<SessionDataDeleter> deleter(
       new SessionDataDeleter(profile->GetSpecialStoragePolicy(),
                              startup_pref_type == SessionStartupPref::LAST));
-  deleter->Run(
-      Profile::GetDefaultStoragePartition(profile),
-      ProfileIOData::FromResourceContext(profile->GetResourceContext()));
+  deleter->Run(Profile::GetDefaultStoragePartition(profile),
+               profile->GetRequestContext());
 }
diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc
index db54a75..4e49b1c 100644
--- a/chrome/browser/shell_integration.cc
+++ b/chrome/browser/shell_integration.cc
@@ -151,13 +151,11 @@
 //
 
 DefaultWebClientWorker::DefaultWebClientWorker(
-    DefaultWebClientObserver* observer,
-    bool delete_observer)
-    : observer_(observer), delete_observer_(delete_observer) {}
+    const DefaultWebClientWorkerCallback& callback)
+    : callback_(callback) {}
 
 void DefaultWebClientWorker::StartCheckIsDefault() {
-  if (observer_)
-    observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
+  RunCallback(STATE_PROCESSING);
 
   BrowserThread::PostTask(
       BrowserThread::FILE, FROM_HERE,
@@ -176,8 +174,7 @@
   }
 
   set_as_default_in_progress_ = true;
-  if (observer_)
-    observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
+  RunCallback(STATE_PROCESSING);
 
   set_as_default_initialized_ = InitializeSetAsDefault();
 
@@ -189,21 +186,6 @@
       base::Bind(&DefaultWebClientWorker::SetAsDefault, this));
 }
 
-void DefaultWebClientWorker::ObserverDestroyed() {
-  // Our associated view has gone away, so we shouldn't call back to it if
-  // our worker thread returns after the view is dead.
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  observer_ = nullptr;
-
-  if (set_as_default_initialized_) {
-    FinalizeSetAsDefault();
-    set_as_default_initialized_ = false;
-  }
-
-  if (set_as_default_in_progress_)
-    ReportAttemptResult(AttemptResult::ABANDONED);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // DefaultWebClientWorker, private:
 
@@ -221,13 +203,6 @@
                             ? AttemptResult::SUCCESS
                             : AttemptResult::NO_ERRORS_NOT_DEFAULT);
   }
-
-  // The worker has finished everything it needs to do, so free the observer
-  // if we own it.
-  if (observer_ && delete_observer_) {
-    delete observer_;
-    observer_ = nullptr;
-  }
 }
 
 void DefaultWebClientWorker::OnSetAsDefaultAttemptComplete(
@@ -253,12 +228,17 @@
     if (!check_default_should_report_success_)
       ReportAttemptResult(result);
 
-    // Start the default browser check which will notify the observer as to
-    // whether Chrome was sucessfully set as the default web client.
+    // Start the default browser check. The default state will be reported to
+    // the caller via the |callback_|.
     StartCheckIsDefault();
   }
 }
 
+void DefaultWebClientWorker::RunCallback(DefaultWebClientUIState state) {
+  if (!callback_.is_null())
+    callback_.Run(state);
+}
+
 void DefaultWebClientWorker::ReportAttemptResult(AttemptResult result) {
   const char* histogram_prefix = GetHistogramPrefix();
 
@@ -288,27 +268,24 @@
 void DefaultWebClientWorker::FinalizeSetAsDefault() {}
 
 void DefaultWebClientWorker::UpdateUI(DefaultWebClientState state) {
-  if (observer_) {
-    switch (state) {
-      case NOT_DEFAULT:
-        observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT);
-        break;
-      case IS_DEFAULT:
-        observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT);
-        break;
-      case UNKNOWN_DEFAULT:
-        observer_->SetDefaultWebClientUIState(STATE_UNKNOWN);
-        break;
-      default:
-        break;
-    }
+  switch (state) {
+    case NOT_DEFAULT:
+      RunCallback(STATE_NOT_DEFAULT);
+      break;
+    case IS_DEFAULT:
+      RunCallback(STATE_IS_DEFAULT);
+      break;
+    case UNKNOWN_DEFAULT:
+      RunCallback(STATE_UNKNOWN);
+      break;
+    case NUM_DEFAULT_STATES:
+      break;
   }
 }
 
 bool DefaultWebClientWorker::ShouldReportDurationForResult(
     AttemptResult result) {
-  return result == SUCCESS || result == FAILURE || result == ABANDONED ||
-         result == RETRY;
+  return result == SUCCESS || result == FAILURE || result == RETRY;
 }
 
 const char* DefaultWebClientWorker::AttemptResultToString(
@@ -320,8 +297,6 @@
       return "AlreadyDefault";
     case FAILURE:
       return "Failure";
-    case ABANDONED:
-      return "Abandoned";
     case LAUNCH_FAILURE:
       return "LaunchFailure";
     case OTHER_WORKER:
@@ -341,9 +316,9 @@
 // DefaultBrowserWorker
 //
 
-DefaultBrowserWorker::DefaultBrowserWorker(DefaultWebClientObserver* observer,
-                                           bool delete_observer)
-    : DefaultWebClientWorker(observer, delete_observer) {}
+DefaultBrowserWorker::DefaultBrowserWorker(
+    const DefaultWebClientWorkerCallback& callback)
+    : DefaultWebClientWorker(callback) {}
 
 DefaultBrowserWorker::~DefaultBrowserWorker() {}
 
@@ -408,10 +383,9 @@
 //
 
 DefaultProtocolClientWorker::DefaultProtocolClientWorker(
-    DefaultWebClientObserver* observer,
-    const std::string& protocol,
-    bool delete_observer)
-    : DefaultWebClientWorker(observer, delete_observer), protocol_(protocol) {}
+    const DefaultWebClientWorkerCallback& callback,
+    const std::string& protocol)
+    : DefaultWebClientWorker(callback), protocol_(protocol) {}
 
 ///////////////////////////////////////////////////////////////////////////////
 // DefaultProtocolClientWorker, private:
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h
index 556747b6..8d2b536 100644
--- a/chrome/browser/shell_integration.h
+++ b/chrome/browser/shell_integration.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -189,12 +190,10 @@
   STATE_UNKNOWN
 };
 
-class DefaultWebClientObserver {
- public:
-  virtual ~DefaultWebClientObserver() {}
-  // Updates the UI state to reflect the current default browser state.
-  virtual void SetDefaultWebClientUIState(DefaultWebClientUIState state) = 0;
-};
+// The type of callback used to communicate processing state to consumers of
+// DefaultBrowserWorker and DefaultProtocolClientWorker.
+using DefaultWebClientWorkerCallback =
+    base::Callback<void(DefaultWebClientUIState)>;
 
 //  Helper objects that handle checking if Chrome is the default browser
 //  or application for a url protocol on Windows and Linux, and also setting
@@ -208,11 +207,8 @@
 class DefaultWebClientWorker
     : public base::RefCountedThreadSafe<DefaultWebClientWorker> {
  public:
-  // Constructor. The worker will post updates to |observer|. If
-  // |delete_observer| is true, the worker owns the observer and it will be
-  // freed in the destructor.
-  DefaultWebClientWorker(DefaultWebClientObserver* observer,
-                         bool delete_observer);
+  explicit DefaultWebClientWorker(
+      const DefaultWebClientWorkerCallback& callback);
 
   // Controls whether the worker can use user interaction to set the default
   // web client. If false, the set-as-default operation will fail on OS where
@@ -221,19 +217,16 @@
     interactive_permitted_ = interactive_permitted;
   }
 
-  // Checks to see if Chrome is the default web client application. The result
-  // will be passed back to the observer via the SetDefaultWebClientUIState
-  // function. If there is no observer, this function does not do anything.
+  // Checks to see if Chrome is the default web client application. The
+  // instance's callback will be run to communicate the default state to the
+  // caller.
   void StartCheckIsDefault();
 
-  // Sets Chrome as the default web client application. If there is an
-  // observer, once the operation has completed the new default will be
-  // queried and the current status reported via SetDefaultWebClientUIState.
+  // Sets Chrome as the default web client application. Once done, it will
+  // trigger a check for the default state using StartCheckIsDefault() to return
+  // the default state to the caller.
   void StartSetAsDefault();
 
-  // Called to notify the worker that the view is gone.
-  void ObserverDestroyed();
-
  protected:
   friend class base::RefCountedThreadSafe<DefaultWebClientWorker>;
 
@@ -241,43 +234,47 @@
   // Do not modify the ordering as it is important for UMA.
   enum AttemptResult {
     // Chrome was set as the default web client.
-    SUCCESS,
+    SUCCESS = 0,
     // Chrome was already the default web client. This counts as a successful
     // attempt.
-    ALREADY_DEFAULT,
+    ALREADY_DEFAULT = 1,
     // Chrome was not set as the default web client.
-    FAILURE,
+    FAILURE = 2,
     // The attempt was abandoned because the observer was destroyed.
-    ABANDONED,
+    // Note: This result is no longer used since the removal of
+    // DefaultWebClientObserver.
+    // ABANDONED = 3,
     // Failed to launch the process to set Chrome as the default web client
     // asynchronously.
-    LAUNCH_FAILURE,
+    LAUNCH_FAILURE = 4,
     // Another worker is already in progress to make Chrome the default web
     // client.
-    OTHER_WORKER,
+    OTHER_WORKER = 5,
     // The user initiated another attempt while the asynchronous operation was
     // already in progress.
-    RETRY,
+    RETRY = 6,
     // No errors were encountered yet Chrome is still not the default web
     // client.
-    NO_ERRORS_NOT_DEFAULT,
+    NO_ERRORS_NOT_DEFAULT = 7,
     NUM_ATTEMPT_RESULT_TYPES
   };
 
   virtual ~DefaultWebClientWorker();
 
-  // Communicates the result to the observer. In contrast to
+  // Communicates the result via the |callback_|. In contrast to
   // OnSetAsDefaultAttemptComplete(), this should not be called multiple
   // times.
   void OnCheckIsDefaultComplete(DefaultWebClientState state);
 
   // Called when the set as default operation is completed. This then invokes
-  // FinalizeSetAsDefault() and, if an observer is present, starts the check
-  // is default process.
+  // FinalizeSetAsDefault() and starts the check is default process.
   // It is safe to call this multiple times. Only the first call is processed
   // after StartSetAsDefault() is invoked.
   void OnSetAsDefaultAttemptComplete(AttemptResult result);
 
+  // Runs the callback but only if it is not null.
+  void RunCallback(DefaultWebClientUIState state);
+
   // Returns true if FinalizeSetAsDefault() will be called.
   bool set_as_default_initialized() const {
     return set_as_default_initialized_;
@@ -288,7 +285,7 @@
   bool interactive_permitted_ = true;
 
   // Flag that indicates if the set-as-default operation is in progess to
-  // prevent multiple notifications to the observer.
+  // prevent multiple notifications to the |callback_|.
   bool set_as_default_in_progress_ = false;
 
  private:
@@ -328,10 +325,8 @@
   // Returns a string based on |result|. This is used for UMA reports.
   static const char* AttemptResultToString(AttemptResult result);
 
-  DefaultWebClientObserver* observer_;
-
-  // Indicates if the the observer will be automatically freed by the worker.
-  bool delete_observer_;
+  // Called with the default state after the worker is done.
+  DefaultWebClientWorkerCallback callback_;
 
   // Flag that indicates the return value of InitializeSetAsDefault(). If
   // true, FinalizeSetAsDefault() will be called to clear what was
@@ -351,11 +346,7 @@
 // Worker for checking and setting the default browser.
 class DefaultBrowserWorker : public DefaultWebClientWorker {
  public:
-  // Constructor. The worker will post updates to |observer|. If
-  // |delete_observer| is true, the worker owns the observer and it will be
-  // freed in the destructor.
-  DefaultBrowserWorker(DefaultWebClientObserver* observer,
-                       bool delete_observer);
+  explicit DefaultBrowserWorker(const DefaultWebClientWorkerCallback& callback);
 
  private:
   ~DefaultBrowserWorker() override;
@@ -395,12 +386,8 @@
 // multiple protocols you should use multiple worker objects.
 class DefaultProtocolClientWorker : public DefaultWebClientWorker {
  public:
-  // Constructor. The worker will post updates to |observer|. If
-  // |delete_observer| is true, the worker owns the observer and it will be
-  // freed in the destructor.
-  DefaultProtocolClientWorker(DefaultWebClientObserver* observer,
-                              const std::string& protocol,
-                              bool delete_observer);
+  DefaultProtocolClientWorker(const DefaultWebClientWorkerCallback& callback,
+                              const std::string& protocol);
 
   const std::string& protocol() const { return protocol_; }
 
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index 8b95570..b38b5f1 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -646,8 +646,8 @@
   //    instead call OnSetAsDefaultAttemptComplete(), passing true to indicate
   //    success.
   // 5. If Chrome is not selected, the url is opened in the selected browser.
-  //    After a certain amount of time, we notify the observer that the
-  //    process failed.
+  //    After a certain amount of time, we notify the caller via the |callback_|
+  //    that the process failed.
 
   if (!StartupBrowserCreator::SetDefaultBrowserCallback(
           base::Bind(&DefaultBrowserWorker::OnSetAsDefaultAttemptComplete, this,
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index b36cefb..2aaedad 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -81,12 +81,9 @@
 #include "net/base/load_flags.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/port_util.h"
-#include "net/cookies/cookie_monster.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
 #include "sync/engine/sync_scheduler_impl.h"
 #include "sync/protocol/sync.pb.h"
 #include "sync/test/fake_server/fake_server.h"
@@ -176,14 +173,6 @@
   std::string GetDebugMessage() const override { return "Encryption"; }
 };
 
-void SetupNetworkCallback(
-    base::WaitableEvent* done,
-    net::URLRequestContextGetter* url_request_context_getter) {
-  url_request_context_getter->GetURLRequestContext()->
-      set_cookie_store(new net::CookieMonster(NULL, NULL));
-  done->Signal();
-}
-
 scoped_ptr<KeyedService> BuildFakeServerProfileInvalidationProvider(
     content::BrowserContext* context) {
   return make_scoped_ptr(new invalidation::ProfileInvalidationProvider(
@@ -535,8 +524,6 @@
   ProfileSyncService* profile_sync_service =
       ProfileSyncServiceFactory::GetForProfile(GetProfile(index));
 
-  SetupNetwork(GetProfile(index)->GetRequestContext());
-
   if (server_type_ == IN_PROCESS_FAKE_SERVER) {
     // TODO(pvalenzuela): Run the fake server via EmbeddedTestServer.
     profile_sync_service->OverrideNetworkResourcesForTest(
@@ -1118,15 +1105,6 @@
                     GetTitle()));
 }
 
-void SyncTest::SetupNetwork(net::URLRequestContextGetter* context_getter) {
-  base::WaitableEvent done(false, false);
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&SetupNetworkCallback, &done,
-                 make_scoped_refptr(context_getter)));
-  done.Wait();
-}
-
 fake_server::FakeServer* SyncTest::GetFakeServer() const {
   return fake_server_.get();
 }
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index 537c270..c6680d87 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -343,8 +343,6 @@
   // Helper method used to check if the test server is up and running.
   bool IsTestServerRunning();
 
-  void SetupNetwork(net::URLRequestContextGetter* context);
-
   // Helper method used to set up fake responses for kClientLoginUrl,
   // kIssueAuthTokenUrl, kGetUserInfoUrl and kSearchDomainCheckUrl in order to
   // mock out calls to GAIA servers.
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index 94086789..e4d5461 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -54,6 +54,10 @@
 #include "chrome/browser/supervised_user/supervised_user_theme.h"
 #endif
 
+#if defined(OS_WIN)
+#include "ui/base/win/shell.h"
+#endif
+
 using base::UserMetricsAction;
 using content::BrowserThread;
 using extensions::Extension;
@@ -409,79 +413,6 @@
   return false;
 }
 
-SkColor ThemeService::GetDefaultColor(int id, bool incognito) const {
-  // For backward compat with older themes, some newer colors are generated from
-  // older ones if they are missing.
-  const int kNtpText = ThemeProperties::COLOR_NTP_TEXT;
-  const int kLabelBackground =
-      ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND;
-  switch (id) {
-    case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON:
-      return color_utils::HSLShift(
-          gfx::kChromeIconGrey,
-          GetTint(ThemeProperties::TINT_BUTTONS, incognito));
-    case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_INACTIVE:
-      // The active color is overridden in Gtk2UI.
-      return SkColorSetA(
-          GetColor(ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON, incognito),
-          0x33);
-    case ThemeProperties::COLOR_BACKGROUND_TAB: {
-      // The tints here serve a different purpose than TINT_BACKGROUND_TAB.
-      // That tint is used to create background tab images for custom themes by
-      // lightening the frame images.  The tints here create solid colors for
-      // background tabs by darkening the foreground tab (toolbar) color.
-      const color_utils::HSL kTint = {-1, -1, 0.4296875};
-      const color_utils::HSL kTintIncognito = {-1, -1, 0.34375};
-      return color_utils::HSLShift(
-          GetColor(ThemeProperties::COLOR_TOOLBAR, incognito),
-          incognito ? kTintIncognito : kTint);
-    }
-    case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND:
-      if (UsingDefaultTheme())
-        break;
-      return GetColor(ThemeProperties::COLOR_TOOLBAR, incognito);
-    case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR:
-      if (UsingDefaultTheme())
-        break;
-      // Use 50% of bookmark text color as separator color.
-      return SkColorSetA(
-          GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT, incognito), 128);
-    case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT:
-      return IncreaseLightness(GetColor(kNtpText, incognito), 0.30);
-    case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
-      return GetColor(kNtpText, incognito);
-    case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE:
-      return IncreaseLightness(GetColor(kNtpText, incognito), 0.70);
-    case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
-      return IncreaseLightness(GetColor(kNtpText, incognito), 0.86);
-    case ThemeProperties::COLOR_NTP_TEXT_LIGHT:
-      return IncreaseLightness(GetColor(kNtpText, incognito), 0.40);
-    case ThemeProperties::COLOR_TAB_THROBBER_SPINNING:
-    case ThemeProperties::COLOR_TAB_THROBBER_WAITING: {
-      SkColor base_color =
-          ui::GetAuraColor(id == ThemeProperties::COLOR_TAB_THROBBER_SPINNING
-                               ? ui::NativeTheme::kColorId_ThrobberSpinningColor
-                               : ui::NativeTheme::kColorId_ThrobberWaitingColor,
-                           nullptr);
-      color_utils::HSL hsl = GetTint(ThemeProperties::TINT_BUTTONS, incognito);
-      return color_utils::HSLShift(base_color, hsl);
-    }
-#if defined(ENABLE_SUPERVISED_USERS)
-    case ThemeProperties::COLOR_SUPERVISED_USER_LABEL:
-      return color_utils::GetReadableColor(
-          SK_ColorWHITE, GetColor(kLabelBackground, incognito));
-    case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND:
-      return color_utils::BlendTowardOppositeLuminance(
-          GetColor(ThemeProperties::COLOR_FRAME, incognito), 0x80);
-    case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BORDER:
-      return color_utils::AlphaBlend(GetColor(kLabelBackground, incognito),
-                                     SK_ColorBLACK, 230);
-#endif
-  }
-
-  return ThemeProperties::GetDefaultColor(id, incognito);
-}
-
 color_utils::HSL ThemeService::GetTint(int id, bool incognito) const {
   DCHECK(CalledOnValidThread());
 
@@ -582,15 +513,6 @@
 }
 #endif
 
-bool ThemeService::ShouldUseNativeFrame() const {
-  return false;
-}
-
-bool ThemeService::HasCustomImage(int id) const {
-  return BrowserThemePack::IsPersistentImageID(id) && theme_supplier_ &&
-         theme_supplier_->HasCustomImage(id);
-}
-
 gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id, bool incognito) const {
   gfx::Image image = GetImageNamed(id, incognito);
   if (image.IsEmpty())
@@ -617,7 +539,76 @@
   if (theme_supplier_ && theme_supplier_->GetColor(theme_supplier_id, &color))
     return color;
 
-  return GetDefaultColor(id, incognito);
+  // For backward compat with older themes, some newer colors are generated from
+  // older ones if they are missing.
+  const int kNtpText = ThemeProperties::COLOR_NTP_TEXT;
+  const int kLabelBackground =
+      ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND;
+  switch (id) {
+    case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON:
+      return color_utils::HSLShift(
+          gfx::kChromeIconGrey,
+          GetTint(ThemeProperties::TINT_BUTTONS, incognito));
+    case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_INACTIVE:
+      // The active color is overridden in Gtk2UI.
+      return SkColorSetA(
+          GetColor(ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON, incognito),
+          0x33);
+    case ThemeProperties::COLOR_BACKGROUND_TAB: {
+      // The tints here serve a different purpose than TINT_BACKGROUND_TAB.
+      // That tint is used to create background tab images for custom themes by
+      // lightening the frame images.  The tints here create solid colors for
+      // background tabs by darkening the foreground tab (toolbar) color.
+      const color_utils::HSL kTint = {-1, -1, 0.4296875};
+      const color_utils::HSL kTintIncognito = {-1, -1, 0.34375};
+      return color_utils::HSLShift(
+          GetColor(ThemeProperties::COLOR_TOOLBAR, incognito),
+          incognito ? kTintIncognito : kTint);
+    }
+    case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND:
+      if (UsingDefaultTheme())
+        break;
+      return GetColor(ThemeProperties::COLOR_TOOLBAR, incognito);
+    case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR:
+      if (UsingDefaultTheme())
+        break;
+      // Use 50% of bookmark text color as separator color.
+      return SkColorSetA(
+          GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT, incognito), 128);
+    case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT:
+      return IncreaseLightness(GetColor(kNtpText, incognito), 0.30);
+    case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
+      return GetColor(kNtpText, incognito);
+    case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE:
+      return IncreaseLightness(GetColor(kNtpText, incognito), 0.70);
+    case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
+      return IncreaseLightness(GetColor(kNtpText, incognito), 0.86);
+    case ThemeProperties::COLOR_NTP_TEXT_LIGHT:
+      return IncreaseLightness(GetColor(kNtpText, incognito), 0.40);
+    case ThemeProperties::COLOR_TAB_THROBBER_SPINNING:
+    case ThemeProperties::COLOR_TAB_THROBBER_WAITING: {
+      SkColor base_color =
+          ui::GetAuraColor(id == ThemeProperties::COLOR_TAB_THROBBER_SPINNING
+                               ? ui::NativeTheme::kColorId_ThrobberSpinningColor
+                               : ui::NativeTheme::kColorId_ThrobberWaitingColor,
+                           nullptr);
+      color_utils::HSL hsl = GetTint(ThemeProperties::TINT_BUTTONS, incognito);
+      return color_utils::HSLShift(base_color, hsl);
+    }
+#if defined(ENABLE_SUPERVISED_USERS)
+    case ThemeProperties::COLOR_SUPERVISED_USER_LABEL:
+      return color_utils::GetReadableColor(
+          SK_ColorWHITE, GetColor(kLabelBackground, incognito));
+    case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND:
+      return color_utils::BlendTowardOppositeLuma(
+          GetColor(ThemeProperties::COLOR_FRAME, incognito), 0x80);
+    case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BORDER:
+      return color_utils::AlphaBlend(GetColor(kLabelBackground, incognito),
+                                     SK_ColorBLACK, 230);
+#endif
+  }
+
+  return ThemeProperties::GetDefaultColor(id, incognito);
 }
 
 int ThemeService::GetDisplayProperty(int id) const {
@@ -647,6 +638,21 @@
   }
 }
 
+bool ThemeService::ShouldUseNativeFrame() const {
+  if (HasCustomImage(IDR_THEME_FRAME))
+    return false;
+#if defined(OS_WIN)
+  return ui::win::IsAeroGlassEnabled();
+#else
+  return false;
+#endif
+}
+
+bool ThemeService::HasCustomImage(int id) const {
+  return BrowserThemePack::IsPersistentImageID(id) && theme_supplier_ &&
+         theme_supplier_->HasCustomImage(id);
+}
+
 base::RefCountedMemory* ThemeService::GetRawData(
     int id,
     ui::ScaleFactor scale_factor) const {
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h
index 7f4cf1e8..9eea41a9 100644
--- a/chrome/browser/themes/theme_service.h
+++ b/chrome/browser/themes/theme_service.h
@@ -136,10 +136,6 @@
   // Returns true if the ThemeService should use the system theme on startup.
   virtual bool ShouldInitWithSystemTheme() const;
 
-  // Returns the color to use for |id| and |incognito| if the theme service does
-  // not provide an override.
-  virtual SkColor GetDefaultColor(int id, bool incognito) const;
-
   // Get the specified tint - |id| is one of the TINT_* enum values.
   color_utils::HSL GetTint(int id, bool incognito) const;
 
@@ -161,11 +157,6 @@
   // from ClearAllThemeData().
   virtual void FreePlatformCaches();
 
-  // Implementation for ui::ThemeProvider (see block of functions in private
-  // section).
-  virtual bool ShouldUseNativeFrame() const;
-  bool HasCustomImage(int id) const;
-
   Profile* profile() const { return profile_; }
 
   void set_ready() { ready_ = true; }
@@ -220,6 +211,8 @@
   gfx::ImageSkia* GetImageSkiaNamed(int id, bool incognito) const;
   SkColor GetColor(int id, bool incognito) const;
   int GetDisplayProperty(int id) const;
+  bool ShouldUseNativeFrame() const;
+  bool HasCustomImage(int id) const;
   base::RefCountedMemory* GetRawData(int id,
                                      ui::ScaleFactor scale_factor) const;
 #if defined(OS_MACOSX)
diff --git a/chrome/browser/themes/theme_service_factory.cc b/chrome/browser/themes/theme_service_factory.cc
index 3e72af0e..9f7ebbd 100644
--- a/chrome/browser/themes/theme_service_factory.cc
+++ b/chrome/browser/themes/theme_service_factory.cc
@@ -16,9 +16,7 @@
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_registry_factory.h"
 
-#if defined(OS_WIN)
-#include "chrome/browser/themes/theme_service_win.h"
-#elif defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS)
+#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS)
 #include "chrome/browser/themes/theme_service_aurax11.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #endif
@@ -57,9 +55,7 @@
 KeyedService* ThemeServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* profile) const {
   ThemeService* provider = NULL;
-#if defined(OS_WIN)
-  provider = new ThemeServiceWin;
-#elif defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS)
+#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS)
   provider = new ThemeServiceAuraX11;
 #else
   provider = new ThemeService;
diff --git a/chrome/browser/themes/theme_service_win.cc b/chrome/browser/themes/theme_service_win.cc
deleted file mode 100644
index 6573ee8..0000000
--- a/chrome/browser/themes/theme_service_win.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/themes/theme_service_win.h"
-
-#include "base/bind.h"
-#include "base/win/windows_version.h"
-#include "chrome/browser/themes/theme_properties.h"
-#include "grit/theme_resources.h"
-#include "skia/ext/skia_utils_win.h"
-#include "ui/base/win/shell.h"
-
-ThemeServiceWin::ThemeServiceWin() {
-  // This just checks for Windows 10 instead of calling ShouldUseDwmFrameColor()
-  // because we want to monitor the frame color even when a custom frame is in
-  // use, so that it will be correct if at any time the user switches to the
-  // native frame.
-  if (base::win::GetVersion() >= base::win::VERSION_WIN10) {
-    dwm_key_.reset(new base::win::RegKey(
-        HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM", KEY_READ));
-    OnDwmKeyUpdated();
-  }
-}
-
-ThemeServiceWin::~ThemeServiceWin() {
-}
-
-bool ThemeServiceWin::ShouldUseNativeFrame() const {
-  return !HasCustomImage(IDR_THEME_FRAME) && ui::win::IsAeroGlassEnabled();
-}
-
-SkColor ThemeServiceWin::GetDefaultColor(int id, bool incognito) const {
-  if (ShouldUseDwmFrameColor()) {
-    // Active native windows on Windows 10 may have a custom frame color.
-    if (id == ThemeProperties::COLOR_FRAME)
-      return dwm_frame_color_;
-
-    // Inactive native windows on Windows 10 always have a white frame.
-    if (id == ThemeProperties::COLOR_FRAME_INACTIVE)
-        return SK_ColorWHITE;
-  }
-
-  return ThemeService::GetDefaultColor(id, incognito);
-}
-
-bool ThemeServiceWin::ShouldUseDwmFrameColor() const {
-  return ShouldUseNativeFrame() &&
-         (base::win::GetVersion() >= base::win::VERSION_WIN10);
-}
-
-void ThemeServiceWin::OnDwmKeyUpdated() {
-  // Attempt to read the accent color.
-  DWORD accent_color, color_prevalence;
-  dwm_frame_color_ =
-      ((dwm_key_->ReadValueDW(L"ColorPrevalence", &color_prevalence) ==
-        ERROR_SUCCESS) &&
-       (color_prevalence == 1) &&
-       (dwm_key_->ReadValueDW(L"AccentColor", &accent_color) == ERROR_SUCCESS))
-          ? skia::COLORREFToSkColor(accent_color)
-          : SK_ColorWHITE;
-
-  // Watch for future changes.
-  if (!dwm_key_->StartWatching(base::Bind(
-          &ThemeServiceWin::OnDwmKeyUpdated, base::Unretained(this))))
-    dwm_key_.reset();
-}
diff --git a/chrome/browser/themes/theme_service_win.h b/chrome/browser/themes/theme_service_win.h
deleted file mode 100644
index 0f0473d..0000000
--- a/chrome/browser/themes/theme_service_win.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_THEMES_THEME_SERVICE_WIN_H_
-#define CHROME_BROWSER_THEMES_THEME_SERVICE_WIN_H_
-
-#include "base/win/registry.h"
-#include "chrome/browser/themes/theme_service.h"
-
-class ThemeServiceWin : public ThemeService {
- public:
-  ThemeServiceWin();
-  ~ThemeServiceWin() override;
-
- private:
-  // ThemeService:
-  bool ShouldUseNativeFrame() const override;
-  SkColor GetDefaultColor(int id, bool incognito) const override;
-
-  // Returns true if the window frame color is determined by the DWM, i.e. this
-  // is a native frame on Windows 10.
-  bool ShouldUseDwmFrameColor() const;
-
-  // Callback executed when |dwm_key_| is updated.  This re-reads the active
-  // frame color and updates |dwm_frame_color_|.
-  void OnDwmKeyUpdated();
-
-  // Registry key containing the params that determine the DWM frame color.
-  // This is only initialized on Windows 10.
-  scoped_ptr<base::win::RegKey> dwm_key_;
-
-  // The DWM frame color, if available; white otherwise.
-  SkColor dwm_frame_color_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThemeServiceWin);
-};
-
-#endif  // CHROME_BROWSER_THEMES_THEME_SERVICE_WIN_H_
diff --git a/chrome/browser/ui/android/simple_message_box_android.cc b/chrome/browser/ui/android/simple_message_box_android.cc
index 5700db7..dd5035e2 100644
--- a/chrome/browser/ui/android/simple_message_box_android.cc
+++ b/chrome/browser/ui/android/simple_message_box_android.cc
@@ -8,10 +8,15 @@
 
 namespace chrome {
 
-MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
-                                const base::string16& title,
-                                const base::string16& message,
-                                MessageBoxType type) {
+void ShowWarningMessageBox(gfx::NativeWindow parent,
+                           const base::string16& title,
+                           const base::string16& message) {
+  NOTIMPLEMENTED();
+}
+
+MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent,
+                                        const base::string16& title,
+                                        const base::string16& message) {
   NOTIMPLEMENTED();
   return MESSAGE_BOX_RESULT_NO;
 }
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc
index 7977f45e..419d1be 100644
--- a/chrome/browser/ui/apps/chrome_app_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -79,42 +79,29 @@
   return new_tab_params.target_contents;
 }
 
-// Helper class that opens a URL based on if this browser instance is the
-// default system browser. If it is the default, open the URL directly instead
-// of asking the system to open it.
-class OpenURLFromTabBasedOnBrowserDefault
-    : public shell_integration::DefaultWebClientObserver {
- public:
-  OpenURLFromTabBasedOnBrowserDefault(scoped_ptr<content::WebContents> source,
-                                      const content::OpenURLParams& params)
-      : source_(std::move(source)), params_(params) {}
-
-  // Opens a URL when called with the result of if this is the default system
-  // browser or not.
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override {
-    Profile* profile =
-        Profile::FromBrowserContext(source_->GetBrowserContext());
-    DCHECK(profile);
-    if (!profile)
-      return;
-    switch (state) {
-      case shell_integration::STATE_PROCESSING:
-        break;
-      case shell_integration::STATE_IS_DEFAULT:
-        OpenURLFromTabInternal(profile, params_);
-        break;
-      case shell_integration::STATE_NOT_DEFAULT:
-      case shell_integration::STATE_UNKNOWN:
-        platform_util::OpenExternal(profile, params_.url);
-        break;
-    }
+void OnCheckIsDefaultBrowserFinished(
+    content::WebContents* source,
+    const content::OpenURLParams& params,
+    shell_integration::DefaultWebClientUIState state) {
+  // Open a URL based on if this browser instance is the default system browser.
+  // If it is the default, open the URL directly instead of asking the system to
+  // open it.
+  Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
+  DCHECK(profile);
+  if (!profile)
+    return;
+  switch (state) {
+    case shell_integration::STATE_PROCESSING:
+      break;
+    case shell_integration::STATE_IS_DEFAULT:
+      OpenURLFromTabInternal(profile, params);
+      break;
+    case shell_integration::STATE_NOT_DEFAULT:
+    case shell_integration::STATE_UNKNOWN:
+      platform_util::OpenExternal(profile, params.url);
+      break;
   }
-
- private:
-  scoped_ptr<content::WebContents> source_;
-  const content::OpenURLParams params_;
-};
+}
 
 }  // namespace
 
@@ -147,22 +134,13 @@
     content::WebContents* source,
     const content::OpenURLParams& params) {
   if (source) {
-    // This NewWindowContentsDelegate was given ownership of the incoming
-    // WebContents by being assigned as its delegate within
-    // ChromeAppDelegate::AddNewContents, but this is the first time
-    // NewWindowContentsDelegate actually sees the WebContents.
-    // Here it is captured for deletion.
-    scoped_ptr<content::WebContents> owned_source(source);
-    scoped_refptr<shell_integration::DefaultWebClientWorker>
+    // Object lifetime notes: StartCheckIsDefault() takes lifetime ownership of
+    // check_if_default_browser_worker and will clean up after the asynchronous
+    // tasks.
+    scoped_refptr<shell_integration::DefaultBrowserWorker>
         check_if_default_browser_worker =
-            new shell_integration::DefaultBrowserWorker(
-                new OpenURLFromTabBasedOnBrowserDefault(std::move(owned_source),
-                                                        params),
-                /*delete_observer=*/true);
-    // Object lifetime notes: The OpenURLFromTabBasedOnBrowserDefault is owned
-    // by check_if_default_browser_worker. StartCheckIsDefault() takes lifetime
-    // ownership of check_if_default_browser_worker and will clean up after
-    // the asynchronous tasks.
+            new shell_integration::DefaultBrowserWorker(base::Bind(
+                &OnCheckIsDefaultBrowserFinished, base::Owned(source), params));
     check_if_default_browser_worker->StartCheckIsDefault();
   }
   return NULL;
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
index f777396..b057d7d 100644
--- a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
@@ -138,11 +138,11 @@
   if (child_count < num_bookmark_urls_before_prompting)
     return true;
 
-  return ShowMessageBox(parent,
-      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-      l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL,
-                                 base::IntToString16(child_count)),
-      MESSAGE_BOX_TYPE_QUESTION) == MESSAGE_BOX_RESULT_YES;
+  return ShowQuestionMessageBox(
+             parent, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+             l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL,
+                                        base::IntToString16(child_count))) ==
+         MESSAGE_BOX_RESULT_YES;
 }
 #endif
 
@@ -229,11 +229,11 @@
 bool ConfirmDeleteBookmarkNode(const BookmarkNode* node,
                                gfx::NativeWindow window) {
   DCHECK(node && node->is_folder() && !node->empty());
-  return ShowMessageBox(window,
-      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-      l10n_util::GetStringFUTF16Int(IDS_BOOKMARK_EDITOR_CONFIRM_DELETE,
-                                    ChildURLCountTotal(node)),
-      MESSAGE_BOX_TYPE_QUESTION) == MESSAGE_BOX_RESULT_YES;
+  return ShowQuestionMessageBox(
+             window, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+             l10n_util::GetStringFUTF16Int(IDS_BOOKMARK_EDITOR_CONFIRM_DELETE,
+                                           ChildURLCountTotal(node))) ==
+         MESSAGE_BOX_RESULT_YES;
 }
 
 void ShowBookmarkAllTabsDialog(Browser* browser) {
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h
index f2ea62d..68e3622 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h
@@ -12,6 +12,7 @@
 #include "chrome/browser/ui/autofill/save_card_bubble_view.h"
 #include "chrome/browser/ui/cocoa/base_bubble_controller.h"
 #include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/legal_message_line.h"
 
 @class BrowserWindowController;
 @class SaveCardBubbleViewCocoa;
@@ -28,13 +29,22 @@
   // Returns the title that should be displayed in the bubble.
   base::string16 GetWindowTitle() const;
 
+  // Returns the explanatory text that should be displayed in the bubble.
+  // Returns an empty string if no message should be displayed.
+  base::string16 GetExplanatoryMessage() const;
+
   // Returns the card that will be uploaded if the user accepts.
   CreditCard GetCard() const;
 
+  // Returns the legal messages that should be displayed in the footer. Result
+  // will be empty if no legal message should be shown.
+  const LegalMessageLines GetLegalMessageLines() const;
+
   // Interaction.
   void OnSaveButton();
   void OnCancelButton();
   void OnLearnMoreClicked();
+  void OnLegalMessageLinkClicked(const GURL& url);
   void OnBubbleClosed();
 
   // SaveCardBubbleView implementation:
@@ -44,6 +54,7 @@
   FRIEND_TEST_ALL_PREFIXES(SaveCardBubbleViewTest, SaveShouldClose);
   FRIEND_TEST_ALL_PREFIXES(SaveCardBubbleViewTest, CancelShouldClose);
   FRIEND_TEST_ALL_PREFIXES(SaveCardBubbleViewTest, LearnMoreShouldNotClose);
+  FRIEND_TEST_ALL_PREFIXES(SaveCardBubbleViewTest, LegalMessageShouldNotClose);
   FRIEND_TEST_ALL_PREFIXES(SaveCardBubbleViewTest, ReturnInvokesDefaultAction);
   FRIEND_TEST_ALL_PREFIXES(SaveCardBubbleViewTest, EscapeCloses);
 
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
index 6915f44..f7b215f 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
@@ -9,6 +9,7 @@
 #include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #include "chrome/browser/ui/chrome_style.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/info_bubble_view.h"
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "grit/components_strings.h"
@@ -21,11 +22,16 @@
 namespace {
 
 const CGFloat kDesiredBubbleWidth = 370;
+const CGFloat kDividerHeight = 1;
 const CGFloat kFramePadding = 16;
 const CGFloat kRelatedControlHorizontalPadding = 2;
+const CGFloat kRelatedControlVerticalPadding = 5;
 const CGFloat kUnrelatedControlVerticalPadding = 15;
 
-const SkColor kIconBorderColor = 0x10000000;  // SkColorSetARGB(10, 0, 0, 0);
+const SkColor kDividerColor = 0xFFE9E9E9;  // SkColorSetRGB(0xE9, 0xE9, 0xE9);
+const SkColor kFooterColor = 0xFFF5F5F5;   // SkColorSetRGB(0xF5, 0xF5, 0xF5);
+const SkColor kIconBorderColor = 0x10000000;  // SkColorSetARGB(0x10, 0, 0, 0);
+
 }
 
 namespace autofill {
@@ -49,10 +55,19 @@
   return controller_ ? controller_->GetWindowTitle() : base::string16();
 }
 
+base::string16 SaveCardBubbleViewBridge::GetExplanatoryMessage() const {
+  return controller_ ? controller_->GetExplanatoryMessage() : base::string16();
+}
+
 CreditCard SaveCardBubbleViewBridge::GetCard() const {
   return controller_ ? controller_->GetCard() : CreditCard();
 }
 
+const LegalMessageLines SaveCardBubbleViewBridge::GetLegalMessageLines() const {
+  return controller_ ? controller_->GetLegalMessageLines()
+                     : LegalMessageLines();
+}
+
 void SaveCardBubbleViewBridge::OnSaveButton() {
   if (controller_)
     controller_->OnSaveButton();
@@ -70,6 +85,11 @@
     controller_->OnLearnMoreClicked();
 }
 
+void SaveCardBubbleViewBridge::OnLegalMessageLinkClicked(const GURL& url) {
+  if (controller_)
+    controller_->OnLegalMessageLinkClicked(url);
+}
+
 void SaveCardBubbleViewBridge::OnBubbleClosed() {
   if (controller_)
     controller_->OnBubbleClosed();
@@ -91,31 +111,75 @@
 #pragma mark SaveCardBubbleViewCocoa
 
 @interface SaveCardBubbleViewCocoa ()
-+ (base::scoped_nsobject<NSTextField>)makeTextField;
-+ (base::scoped_nsobject<NSButton>)makeButton;
++ (base::scoped_nsobject<NSTextField>)makeLabel:(NSString*)text;
++ (base::scoped_nsobject<NSTextView>)makeWrappingLabel:(NSString*)text
+                                          withFontSize:(CGFloat)fontSize;
++ (base::scoped_nsobject<HyperlinkTextView>)makeHyperlinkText:(NSString*)text;
++ (base::scoped_nsobject<NSButton>)makeButton:(NSString*)text;
 @end
 
 @implementation SaveCardBubbleViewCocoa {
   autofill::SaveCardBubbleViewBridge* bridge_;  // Weak.
 }
 
-+ (base::scoped_nsobject<NSTextField>)makeTextField {
++ (base::scoped_nsobject<NSTextField>)makeLabel:(NSString*)text {
   base::scoped_nsobject<NSTextField> textField(
       [[NSTextField alloc] initWithFrame:NSZeroRect]);
   [textField setEditable:NO];
   [textField setSelectable:NO];
   [textField setDrawsBackground:NO];
   [textField setBezeled:NO];
+  [textField setStringValue:text];
+  [textField sizeToFit];
 
   return textField;
 }
 
-+ (base::scoped_nsobject<NSButton>)makeButton {
++ (base::scoped_nsobject<NSTextView>)makeWrappingLabel:(NSString*)text
+                                          withFontSize:(CGFloat)fontSize {
+  base::scoped_nsobject<NSTextView> textView(
+      [[NSTextView alloc] initWithFrame:NSZeroRect]);
+  NSDictionary* attributes =
+      @{NSFontAttributeName : [NSFont systemFontOfSize:fontSize]};
+  base::scoped_nsobject<NSAttributedString> attributedMessage(
+      [[NSAttributedString alloc] initWithString:text attributes:attributes]);
+  [[textView textStorage] setAttributedString:attributedMessage];
+  [[textView textContainer] setLineFragmentPadding:0.0f];
+  [textView setEditable:NO];
+  [textView setSelectable:NO];
+  [textView setDrawsBackground:NO];
+  [textView setVerticallyResizable:YES];
+  [textView setFrameSize:NSMakeSize(kDesiredBubbleWidth - (2 * kFramePadding),
+                                    MAXFLOAT)];
+  [textView sizeToFit];
+
+  return textView;
+}
+
++ (base::scoped_nsobject<HyperlinkTextView>)makeHyperlinkText:(NSString*)text {
+  base::scoped_nsobject<HyperlinkTextView> lineView(
+      [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]);
+  [lineView setMessage:text
+              withFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]
+          messageColor:[NSColor blackColor]];
+
+  [[lineView textContainer] setLineFragmentPadding:0.0f];
+  [lineView setVerticallyResizable:YES];
+  [lineView setFrameSize:NSMakeSize(kDesiredBubbleWidth - 2 * kFramePadding,
+                                    MAXFLOAT)];
+  [lineView sizeToFit];
+
+  return lineView;
+}
+
++ (base::scoped_nsobject<NSButton>)makeButton:(NSString*)text {
   base::scoped_nsobject<NSButton> button(
       [[NSButton alloc] initWithFrame:NSZeroRect]);
   [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
   [button setBezelStyle:NSRoundedBezelStyle];
   [[button cell] setControlSize:NSSmallControlSize];
+  [button setTitle:text];
+  [button sizeToFit];
 
   return button;
 }
@@ -160,24 +224,10 @@
 }
 
 - (void)loadView {
-  // Title is an NSTextView instead of an NSTextField to allow it to wrap.
+  // Title.
+  NSString* title = SysUTF16ToNSString(bridge_->GetWindowTitle());
   base::scoped_nsobject<NSTextView> titleLabel(
-      [[NSTextView alloc] initWithFrame:NSZeroRect]);
-  NSDictionary* attributes =
-      @{NSFontAttributeName : [NSFont systemFontOfSize:15.0]};
-  base::scoped_nsobject<NSAttributedString> attributedMessage(
-      [[NSAttributedString alloc]
-          initWithString:base::SysUTF16ToNSString(bridge_->GetWindowTitle())
-              attributes:attributes]);
-  [[titleLabel textStorage] setAttributedString:attributedMessage];
-  [[titleLabel textContainer] setLineFragmentPadding:0.0f];
-  [titleLabel setEditable:NO];
-  [titleLabel setSelectable:NO];
-  [titleLabel setDrawsBackground:NO];
-  [titleLabel setVerticallyResizable:YES];
-  [titleLabel setFrameSize:NSMakeSize(kDesiredBubbleWidth - (2 * kFramePadding),
-                                      MAXFLOAT)];
-  [titleLabel sizeToFit];
+      [SaveCardBubbleViewCocoa makeWrappingLabel:title withFontSize:15.0]);
 
   // Credit card info.
   autofill::CreditCard card = bridge_->GetCard();
@@ -196,85 +246,128 @@
                          .AsNSImage()];
   [cardIcon setFrameSize:[[cardIcon image] size]];
 
-  base::scoped_nsobject<NSTextField> lastFourLabel(
-      [SaveCardBubbleViewCocoa makeTextField]);
   // Midline horizontal ellipsis follwed by last four digits.
-  [lastFourLabel setStringValue:base::SysUTF16ToNSString(
-                                    base::UTF8ToUTF16("\xE2\x8B\xAF") +
-                                    card.LastFourDigits())];
-  [lastFourLabel sizeToFit];
+  base::scoped_nsobject<NSTextField> lastFourLabel([SaveCardBubbleViewCocoa
+      makeLabel:SysUTF16ToNSString(base::UTF8ToUTF16("\xE2\x8B\xAF") +
+                                   card.LastFourDigits())]);
 
   base::scoped_nsobject<NSTextField> expirationDateLabel(
-      [SaveCardBubbleViewCocoa makeTextField]);
-  [expirationDateLabel
-      setStringValue:base::SysUTF16ToNSString(
-                         card.AbbreviatedExpirationDateForDisplay())];
-  [expirationDateLabel sizeToFit];
+      [SaveCardBubbleViewCocoa
+          makeLabel:base::SysUTF16ToNSString(
+                        card.AbbreviatedExpirationDateForDisplay())]);
+
+  // Explanatory text (only shown for upload).
+  base::scoped_nsobject<NSTextView> explanationLabel(
+      [[NSTextView alloc] initWithFrame:NSZeroRect]);
+  base::string16 explanation = bridge_->GetExplanatoryMessage();
+  if (!explanation.empty()) {
+    explanationLabel.reset([SaveCardBubbleViewCocoa
+                               makeWrappingLabel:SysUTF16ToNSString(explanation)
+                                    withFontSize:[NSFont systemFontSize]]
+                               .release());
+  }
 
   // "Learn more" link.
-  base::scoped_nsobject<HyperlinkTextView> learnMoreLink(
-      [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]);
   NSString* learnMoreString = l10n_util::GetNSString(IDS_LEARN_MORE);
-  [learnMoreLink
-        setMessage:learnMoreString
-          withFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]
-      messageColor:[NSColor blackColor]];
+  base::scoped_nsobject<HyperlinkTextView> learnMoreLink(
+      [SaveCardBubbleViewCocoa makeHyperlinkText:learnMoreString]);
   [learnMoreLink setDelegate:self];
+
   NSColor* linkColor =
       skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor());
-  [learnMoreLink addLinkRange:NSMakeRange(0, [learnMoreString length])
-                      withURL:nil
-                    linkColor:linkColor];
-  NSTextStorage* text = [learnMoreLink textStorage];
-  [text addAttribute:NSUnderlineStyleAttributeName
-               value:[NSNumber numberWithInt:NSUnderlineStyleNone]
-               range:NSMakeRange(0, [learnMoreString length])];
-  [[learnMoreLink textContainer] setLineFragmentPadding:0.0f];
-  [learnMoreLink setVerticallyResizable:YES];
-  [learnMoreLink
-      setFrameSize:NSMakeSize(kDesiredBubbleWidth - 2 * kFramePadding,
-                              MAXFLOAT)];
-  [learnMoreLink sizeToFit];
+  NSRange range = NSMakeRange(0, [learnMoreString length]);
+  [learnMoreLink addLinkRange:range withURL:nil linkColor:linkColor];
+  [[learnMoreLink textStorage] addAttribute:NSUnderlineStyleAttributeName
+                                      value:@(NSUnderlineStyleNone)
+                                      range:range];
 
   // Cancel button.
-  base::scoped_nsobject<NSButton> cancelButton(
-      [SaveCardBubbleViewCocoa makeButton]);
-  [cancelButton
-      setTitle:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY)];
-  [cancelButton sizeToFit];
+  base::scoped_nsobject<NSButton> cancelButton([SaveCardBubbleViewCocoa
+      makeButton:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY)]);
   [cancelButton setTarget:self];
   [cancelButton setAction:@selector(onCancelButton:)];
   [cancelButton setKeyEquivalent:@"\e"];
 
   // Save button.
-  base::scoped_nsobject<NSButton> saveButton(
-      [SaveCardBubbleViewCocoa makeButton]);
-  [saveButton
-      setTitle:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT)];
-  [saveButton sizeToFit];
+  base::scoped_nsobject<NSButton> saveButton([SaveCardBubbleViewCocoa
+      makeButton:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT)]);
   [saveButton setTarget:self];
   [saveButton setAction:@selector(onSaveButton:)];
   [saveButton setKeyEquivalent:@"\r"];
 
+  // Footer with legal text (only shown for upload).
+  base::scoped_nsobject<NSBox> divider(
+      [[NSBox alloc] initWithFrame:NSZeroRect]);
+  base::scoped_nsobject<NSView> footerView(
+      [[NSView alloc] initWithFrame:NSZeroRect]);
+  const autofill::LegalMessageLines& lines = bridge_->GetLegalMessageLines();
+  if (!lines.empty()) {
+    [divider setBoxType:NSBoxCustom];
+    [divider setBorderType:NSLineBorder];
+    [divider setBorderColor:skia::SkColorToCalibratedNSColor(kDividerColor)];
+    [divider setFrameSize:NSMakeSize(kDesiredBubbleWidth, kDividerHeight)];
+
+    [footerView setWantsLayer:YES];
+    [[footerView layer]
+        setBackgroundColor:skia::CGColorCreateFromSkColor(kFooterColor)];
+
+    CGFloat linesHeight = kFramePadding;
+    for (auto lineIter = lines.rbegin(); lineIter != lines.rend(); ++lineIter) {
+      // Create the legal message line view.
+      base::scoped_nsobject<HyperlinkTextView> lineView([SaveCardBubbleViewCocoa
+          makeHyperlinkText:SysUTF16ToNSString(lineIter->text())]);
+      [lineView setDelegate:self];
+
+      // Add the links.
+      for (const autofill::LegalMessageLine::Link& link : lineIter->links()) {
+        NSRange range = NSMakeRange(link.range.start(), link.range.length());
+        [lineView addLinkRange:range withURL:nil linkColor:linkColor];
+        [[lineView textStorage] addAttribute:NSUnderlineStyleAttributeName
+                                       value:@(NSUnderlineStyleNone)
+                                       range:range];
+      }
+
+      // Add the line to the footer view.
+      [footerView addSubview:lineView];
+      [lineView setFrameOrigin:NSMakePoint(kFramePadding, linesHeight)];
+      linesHeight +=
+          [lineView frame].size.height + kRelatedControlVerticalPadding;
+    }
+    [footerView setFrameSize:NSMakeSize(kDesiredBubbleWidth,
+                                        linesHeight + kFramePadding)];
+  }
+
   // Layout.
+  [footerView setFrameOrigin:NSZeroPoint];
+
+  [divider setFrameOrigin:NSMakePoint(0, NSMaxY([footerView frame]))];
+
   [saveButton setFrameOrigin:
       NSMakePoint(kDesiredBubbleWidth - kFramePadding -
                       NSWidth([saveButton frame]),
-                  kFramePadding)];
+                  NSMaxY([divider frame]) + kFramePadding)];
   [cancelButton setFrameOrigin:
       NSMakePoint(NSMinX([saveButton frame]) -
                       kRelatedControlHorizontalPadding -
                       NSWidth([cancelButton frame]),
-                  kFramePadding)];
+                  NSMaxY([divider frame]) + kFramePadding)];
   [learnMoreLink setFrameOrigin:
       NSMakePoint(kFramePadding,
                   NSMidY([saveButton frame]) -
                       (NSHeight([learnMoreLink frame]) / 2.0))];
 
-  [cardIcon setFrameOrigin:
+  [explanationLabel setFrameOrigin:
       NSMakePoint(kFramePadding,
                   NSMaxY([saveButton frame]) +
                       kUnrelatedControlVerticalPadding)];
+
+  NSView* viewBelowIcon =
+      ([explanationLabel frame].size.height > 0) ? explanationLabel.get()
+                                                 : saveButton.get();
+  [cardIcon setFrameOrigin:
+      NSMakePoint(kFramePadding,
+                  NSMaxY([viewBelowIcon frame]) +
+                      kUnrelatedControlVerticalPadding)];
   [lastFourLabel setFrameOrigin:
       NSMakePoint(NSMaxX([cardIcon frame]) + kRelatedControlHorizontalPadding,
                   NSMidY([cardIcon frame]) -
@@ -290,13 +383,14 @@
                   NSMaxY([cardIcon frame]) + kUnrelatedControlVerticalPadding)];
 
   [[[self window] contentView] setSubviews:@[
-    titleLabel, cardIcon, lastFourLabel, expirationDateLabel, learnMoreLink,
-    cancelButton, saveButton
+    titleLabel, cardIcon, lastFourLabel, expirationDateLabel, explanationLabel,
+    learnMoreLink, cancelButton, saveButton, divider, footerView
   ]];
 
   // Update window frame.
   NSRect windowFrame = [[self window] frame];
-  windowFrame.size.height = NSMaxY([titleLabel frame]) + kFramePadding;
+  windowFrame.size.height = NSMaxY([titleLabel frame]) + kFramePadding +
+                            info_bubble::kBubbleArrowHeight;
   windowFrame.size.width = kDesiredBubbleWidth;
   [[self window] setFrame:windowFrame display:NO];
 }
@@ -315,6 +409,24 @@
     clickedOnLink:(id)link
           atIndex:(NSUInteger)charIndex {
   DCHECK(bridge_);
+
+  // Check each of the links in each of the legal message lines ot see if they
+  // are the source of the click.
+  const autofill::LegalMessageLines& lines = bridge_->GetLegalMessageLines();
+  for (const autofill::LegalMessageLine& line : lines) {
+    if (line.text() ==
+        base::SysNSStringToUTF16([[textView textStorage] string])) {
+      for (const autofill::LegalMessageLine::Link& link : line.links()) {
+        if (link.range.start() <= charIndex && charIndex < link.range.end()) {
+          bridge_->OnLegalMessageLinkClicked(link.url);
+          return YES;
+        }
+      }
+    }
+  }
+
+  // If none of the legal message links are the source of the click, the source
+  // must be the learn more link.
   bridge_->OnLearnMoreClicked();
   return YES;
 }
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
index 497c7a7..c9f0a83 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/json/json_reader.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/values.h"
 #include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
@@ -20,11 +22,12 @@
 class TestSaveCardBubbleController : public SaveCardBubbleController {
  public:
   TestSaveCardBubbleController() {
-    lines_.reset(new LegalMessageLines());
+    ParseLegalMessageJson();
 
     on_save_button_was_called_ = false;
     on_cancel_button_was_called_ = false;
     on_learn_more_was_called_ = false;
+    on_legal_message_was_called_ = false;
     on_bubble_closed_was_called_ = false;
   }
 
@@ -42,25 +45,67 @@
   void OnSaveButton() override { on_save_button_was_called_ = true; }
   void OnCancelButton() override { on_cancel_button_was_called_ = true; }
   void OnLearnMoreClicked() override { on_learn_more_was_called_ = true; }
-  void OnLegalMessageLinkClicked(const GURL& url) override {}
+  void OnLegalMessageLinkClicked(const GURL& url) override {
+    on_legal_message_was_called_ = true;
+    legal_message_url_ = url.spec();
+  }
   void OnBubbleClosed() override { on_bubble_closed_was_called_ = true; }
 
   const LegalMessageLines& GetLegalMessageLines() const override {
-    return *lines_;
+    return lines_;
   }
 
   // Testing state.
   bool on_save_button_was_called() { return on_save_button_was_called_; }
   bool on_cancel_button_was_called() { return on_cancel_button_was_called_; }
   bool on_learn_more_was_called() { return on_learn_more_was_called_; }
+  bool on_legal_message_was_called() { return on_legal_message_was_called_; }
+  std::string legal_message_url() { return legal_message_url_; }
   bool on_bubble_closed_was_called() { return on_bubble_closed_was_called_; }
 
  private:
-  scoped_ptr<LegalMessageLines> lines_;
+  void ParseLegalMessageJson() {
+    std::string message_json =
+        "{"
+        "  \"line\" : ["
+        "    {"
+        "      \"template\": \"Please check out our {0}.\","
+        "      \"template_parameter\": ["
+        "        {"
+        "          \"display_text\": \"terms of service\","
+        "          \"url\": \"http://help.example.com/legal_message\""
+        "        }"
+        "      ]"
+        "    },"
+        "    {"
+        "      \"template\": \"We also have a {0} and {1}.\","
+        "      \"template_parameter\": ["
+        "        {"
+        "          \"display_text\": \"mission statement\","
+        "          \"url\": \"http://www.example.com/our_mission\""
+        "        },"
+        "        {"
+        "          \"display_text\": \"privacy policy\","
+        "          \"url\": \"http://help.example.com/privacy_policy\""
+        "        }"
+        "      ]"
+        "    }"
+        "  ]"
+        "}";
+    scoped_ptr<base::Value> value(base::JSONReader::Read(message_json));
+    ASSERT_TRUE(value);
+    base::DictionaryValue* dictionary = nullptr;
+    ASSERT_TRUE(value->GetAsDictionary(&dictionary));
+    LegalMessageLine::Parse(*dictionary, &lines_);
+  }
+
+  LegalMessageLines lines_;
 
   bool on_save_button_was_called_;
   bool on_cancel_button_was_called_;
   bool on_learn_more_was_called_;
+  bool on_legal_message_was_called_;
+  std::string legal_message_url_;
   bool on_bubble_closed_was_called_;
 };
 
@@ -100,6 +145,7 @@
   EXPECT_TRUE(bubble_controller_->on_save_button_was_called());
   EXPECT_FALSE(bubble_controller_->on_cancel_button_was_called());
   EXPECT_FALSE(bubble_controller_->on_learn_more_was_called());
+  EXPECT_FALSE(bubble_controller_->on_legal_message_was_called());
 
   EXPECT_TRUE(bubble_controller_->on_bubble_closed_was_called());
 }
@@ -110,6 +156,7 @@
   EXPECT_FALSE(bubble_controller_->on_save_button_was_called());
   EXPECT_TRUE(bubble_controller_->on_cancel_button_was_called());
   EXPECT_FALSE(bubble_controller_->on_learn_more_was_called());
+  EXPECT_FALSE(bubble_controller_->on_legal_message_was_called());
 
   EXPECT_TRUE(bubble_controller_->on_bubble_closed_was_called());
 }
@@ -122,6 +169,29 @@
   EXPECT_FALSE(bubble_controller_->on_save_button_was_called());
   EXPECT_FALSE(bubble_controller_->on_cancel_button_was_called());
   EXPECT_TRUE(bubble_controller_->on_learn_more_was_called());
+  EXPECT_FALSE(bubble_controller_->on_legal_message_was_called());
+
+  EXPECT_FALSE(bubble_controller_->on_bubble_closed_was_called());
+}
+
+TEST_F(SaveCardBubbleViewTest, LegalMessageShouldNotClose) {
+  NSString* legalText = @"We also have a mission statement and privacy policy.";
+  base::scoped_nsobject<NSTextView> textView(
+      [[NSTextView alloc] initWithFrame:NSZeroRect]);
+  base::scoped_nsobject<NSAttributedString> attributedMessage(
+      [[NSAttributedString alloc] initWithString:legalText attributes:@{}]);
+  [[textView textStorage] setAttributedString:attributedMessage];
+
+  NSObject* link = nil;
+  [bridge_->view_controller_ textView:textView clickedOnLink:link atIndex:40];
+
+  EXPECT_FALSE(bubble_controller_->on_save_button_was_called());
+  EXPECT_FALSE(bubble_controller_->on_cancel_button_was_called());
+  EXPECT_FALSE(bubble_controller_->on_learn_more_was_called());
+  EXPECT_TRUE(bubble_controller_->on_legal_message_was_called());
+
+  std::string url("http://help.example.com/privacy_policy");
+  EXPECT_EQ(url, bubble_controller_->legal_message_url());
 
   EXPECT_FALSE(bubble_controller_->on_bubble_closed_was_called());
 }
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
index c3d9761..29c0ac3 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -198,6 +198,7 @@
   command_updater()->UpdateCommandEnabled(IDC_SAVE_CREDIT_CARD_FOR_PAGE,
                                           enabled);
   save_credit_card_decoration_->SetVisible(enabled);
+  OnDecorationsChanged();
 }
 
 void LocationBarViewMac::UpdatePageActions() {
diff --git a/chrome/browser/ui/cocoa/simple_message_box_mac.mm b/chrome/browser/ui/cocoa/simple_message_box_mac.mm
index dcc2045..84865c07 100644
--- a/chrome/browser/ui/cocoa/simple_message_box_mac.mm
+++ b/chrome/browser/ui/cocoa/simple_message_box_mac.mm
@@ -15,13 +15,12 @@
 
 namespace chrome {
 
+namespace {
+
 MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
                                 const base::string16& title,
                                 const base::string16& message,
                                 MessageBoxType type) {
-  if (type == MESSAGE_BOX_TYPE_OK_CANCEL)
-    NOTIMPLEMENTED();
-
   startup_metric_utils::SetNonBrowserUIDisplayed();
   if (internal::g_should_skip_message_box_for_test)
     return MESSAGE_BOX_RESULT_YES;
@@ -29,9 +28,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)];
-  NSAlertStyle style = (type == MESSAGE_BOX_TYPE_INFORMATION) ?
-      NSInformationalAlertStyle : NSWarningAlertStyle;
-  [alert setAlertStyle:style];
+  [alert setAlertStyle:NSWarningAlertStyle];
   if (type == MESSAGE_BOX_TYPE_QUESTION) {
     [alert addButtonWithTitle:
         l10n_util::GetNSString(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL)];
@@ -45,4 +42,18 @@
       MESSAGE_BOX_RESULT_NO : MESSAGE_BOX_RESULT_YES;
 }
 
+}  // namespace
+
+void ShowWarningMessageBox(gfx::NativeWindow parent,
+                           const base::string16& title,
+                           const base::string16& message) {
+  ShowMessageBox(parent, title, message, MESSAGE_BOX_TYPE_WARNING);
+}
+
+MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent,
+                                        const base::string16& title,
+                                        const base::string16& message) {
+  return ShowMessageBox(parent, title, message, MESSAGE_BOX_TYPE_QUESTION);
+}
+
 }  // namespace chrome
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
index a858f2b..10cae39b 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -876,18 +876,14 @@
     // side effects on other tests.
   }
 
-  shell_integration::DefaultProtocolClientWorker* CreateShellWorker(
-      shell_integration::DefaultWebClientObserver* observer,
+  scoped_refptr<shell_integration::DefaultProtocolClientWorker>
+  CreateShellWorker(
+      const shell_integration::DefaultWebClientWorkerCallback& callback,
       const std::string& protocol) override {
     VLOG(1) << "CreateShellWorker";
     return NULL;
   }
 
-  ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver(
-      ProtocolHandlerRegistry* registry) override {
-    return NULL;
-  }
-
   void RegisterWithOSAsDefaultClient(
       const std::string& protocol,
       ProtocolHandlerRegistry* registry) override {
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
index c461bce7..c622c4c 100644
--- a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
+++ b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
@@ -173,3 +173,8 @@
     OverrideForTesting override) {
   g_override_for_testing = override;
 }
+
+// static
+bool ExtensionMessageBubbleFactory::is_enabled_for_testing() {
+  return g_override_for_testing == OVERRIDE_ENABLED;
+}
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_factory.h b/chrome/browser/ui/extensions/extension_message_bubble_factory.h
index af724e2..8804ff0c 100644
--- a/chrome/browser/ui/extensions/extension_message_bubble_factory.h
+++ b/chrome/browser/ui/extensions/extension_message_bubble_factory.h
@@ -34,6 +34,7 @@
 
   // Overrides the default behavior for testing.
   static void set_override_for_tests(OverrideForTesting override);
+  static bool is_enabled_for_testing();
 
  private:
   Browser* browser_;
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
index f25d8a9..e22761f 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -903,7 +903,7 @@
 
   if (ui::MaterialDesignController::IsModeMaterial()) {
     colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
-        color_utils::BlendTowardOppositeLuminance(label_color, 50);
+        color_utils::BlendTowardOppositeLuma(label_color, 50);
   } else {
     // The inactive frame color never occurs naturally in the theme, as it is a
     // tinted version of |frame_color|. We generate another color based on the
diff --git a/chrome/browser/ui/profile_error_dialog.cc b/chrome/browser/ui/profile_error_dialog.cc
index 166b63e4..39eb774 100644
--- a/chrome/browser/ui/profile_error_dialog.cc
+++ b/chrome/browser/ui/profile_error_dialog.cc
@@ -25,10 +25,9 @@
   static bool is_showing_profile_error_dialog = false;
   if (!is_showing_profile_error_dialog) {
     base::AutoReset<bool> resetter(&is_showing_profile_error_dialog, true);
-    chrome::ShowMessageBox(NULL,
-                           l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-                           l10n_util::GetStringUTF16(message_id),
-                           chrome::MESSAGE_BOX_TYPE_WARNING);
+    chrome::ShowWarningMessageBox(NULL,
+                                  l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+                                  l10n_util::GetStringUTF16(message_id));
   }
 #endif
 }
diff --git a/chrome/browser/ui/simple_message_box.h b/chrome/browser/ui/simple_message_box.h
index 2546d47c..d6f57db 100644
--- a/chrome/browser/ui/simple_message_box.h
+++ b/chrome/browser/ui/simple_message_box.h
@@ -16,10 +16,8 @@
 };
 
 enum MessageBoxType {
-  MESSAGE_BOX_TYPE_INFORMATION,  // Shows an OK button.
   MESSAGE_BOX_TYPE_WARNING,      // Shows an OK button.
   MESSAGE_BOX_TYPE_QUESTION,     // Shows YES and NO buttons.
-  MESSAGE_BOX_TYPE_OK_CANCEL,    // Shows OK and CANCEL buttons (Aura only).
 };
 
 // Shows a dialog box with the given |title| and |message|. If |parent| is
@@ -29,10 +27,15 @@
 // NOTE: In general, you should avoid this since it's usually poor UI.
 // We have a variety of other surfaces such as app menu notifications and
 // infobars; consult the UI leads for a recommendation.
-MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
-                                const base::string16& title,
-                                const base::string16& message,
-                                MessageBoxType type);
+void ShowWarningMessageBox(gfx::NativeWindow parent,
+                           const base::string16& title,
+                           const base::string16& message);
+
+// As above, but two buttons are displayed and the return value indicates which
+// is chosen.
+MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent,
+                                        const base::string16& title,
+                                        const base::string16& message);
 
 // Shows a dialog box with the given |title| and |message|, and with two buttons
 // labeled with |yes_text| and |no_text|. If |parent| is non-NULL, the box will
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc
index 52eb2f5..9464a50 100644
--- a/chrome/browser/ui/startup/bad_flags_prompt.cc
+++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -141,7 +141,7 @@
     ResourceBundle::CleanupSharedInstance();
 
   // More complex dialogs cannot be shown before the earliest calls here.
-  ShowMessageBox(NULL, title, message, chrome::MESSAGE_BOX_TYPE_WARNING);
+  ShowWarningMessageBox(NULL, title, message);
 }
 
 }  // namespace chrome
diff --git a/chrome/browser/ui/startup/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt.cc
index 4249abe..268c76f 100644
--- a/chrome/browser/ui/startup/default_browser_prompt.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt.cc
@@ -180,8 +180,8 @@
   // message loops of the FILE and UI thread will hold references to it
   // and it will be automatically freed once all its tasks have finished.
   scoped_refptr<shell_integration::DefaultBrowserWorker>(
-      new shell_integration::DefaultBrowserWorker(nullptr,
-                                                  /*delete_observer=*/false))
+      new shell_integration::DefaultBrowserWorker(
+          shell_integration::DefaultWebClientWorkerCallback()))
       ->StartSetAsDefault();
   return true;
 }
@@ -198,61 +198,14 @@
   return true;
 }
 
-// A shell_integration::DefaultWebClientObserver that handles the check to
-// determine whether or not to show the default browser prompt. If Chrome is the
-// default browser, then the kCheckDefaultBrowser pref is reset.  Otherwise, the
-// prompt is shown.
-class CheckDefaultBrowserObserver
-    : public shell_integration::DefaultWebClientObserver {
- public:
-  CheckDefaultBrowserObserver(const base::FilePath& profile_path,
-                              bool show_prompt);
-  ~CheckDefaultBrowserObserver() override;
-
- private:
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override;
-
-  void ResetCheckDefaultBrowserPref();
-  void ShowPrompt();
-
-  // The path to the profile for which the prompt is to be shown.
-  base::FilePath profile_path_;
-
-  // True if the prompt is to be shown if Chrome is not the default browser.
-  bool show_prompt_;
-
-  DISALLOW_COPY_AND_ASSIGN(CheckDefaultBrowserObserver);
-};
-
-CheckDefaultBrowserObserver::CheckDefaultBrowserObserver(
-    const base::FilePath& profile_path,
-    bool show_prompt)
-    : profile_path_(profile_path), show_prompt_(show_prompt) {}
-
-CheckDefaultBrowserObserver::~CheckDefaultBrowserObserver() {}
-
-void CheckDefaultBrowserObserver::SetDefaultWebClientUIState(
-    shell_integration::DefaultWebClientUIState state) {
-  if (state == shell_integration::STATE_IS_DEFAULT) {
-    // Notify the user in the future if Chrome ceases to be the user's chosen
-    // default browser.
-    ResetCheckDefaultBrowserPref();
-  } else if (show_prompt_ && state == shell_integration::STATE_NOT_DEFAULT &&
-             shell_integration::CanSetAsDefaultBrowser() !=
-                 shell_integration::SET_DEFAULT_NOT_ALLOWED) {
-    ShowPrompt();
-  }
-}
-
-void CheckDefaultBrowserObserver::ResetCheckDefaultBrowserPref() {
+void ResetCheckDefaultBrowserPref(const base::FilePath& profile_path) {
   Profile* profile =
-      g_browser_process->profile_manager()->GetProfileByPath(profile_path_);
+      g_browser_process->profile_manager()->GetProfileByPath(profile_path);
   if (profile)
     profile->GetPrefs()->SetBoolean(prefs::kCheckDefaultBrowser, true);
 }
 
-void CheckDefaultBrowserObserver::ShowPrompt() {
+void ShowPrompt() {
   Browser* browser = chrome::FindLastActive();
   if (!browser)
     return;  // Reached during ui tests.
@@ -270,6 +223,21 @@
           ->GetPrefs());
 }
 
+void OnCheckIsDefaultBrowserFinished(
+    const base::FilePath& profile_path,
+    bool show_prompt,
+    shell_integration::DefaultWebClientUIState state) {
+  if (state == shell_integration::STATE_IS_DEFAULT) {
+    // Notify the user in the future if Chrome ceases to be the user's chosen
+    // default browser.
+    ResetCheckDefaultBrowserPref(profile_path);
+  } else if (show_prompt && state == shell_integration::STATE_NOT_DEFAULT &&
+             shell_integration::CanSetAsDefaultBrowser() !=
+                 shell_integration::SET_DEFAULT_NOT_ALLOWED) {
+    ShowPrompt();
+  }
+}
+
 }  // namespace
 
 namespace chrome {
@@ -314,9 +282,8 @@
   }
 
   scoped_refptr<shell_integration::DefaultBrowserWorker>(
-      new shell_integration::DefaultBrowserWorker(
-          new CheckDefaultBrowserObserver(profile->GetPath(), show_prompt),
-          /*delete_observer=*/true))
+      new shell_integration::DefaultBrowserWorker(base::Bind(
+          &OnCheckIsDefaultBrowserFinished, profile->GetPath(), show_prompt)))
       ->StartCheckIsDefault();
 }
 
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper.cc
index 33adf23..8d3818b 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper.cc
@@ -48,7 +48,7 @@
                                             SkAlpha alpha) {
   static const SkColor kBackgroundColor =
       theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);
-  return color_utils::BlendTowardOppositeLuminance(kBackgroundColor, alpha);
+  return color_utils::BlendTowardOppositeLuma(kBackgroundColor, alpha);
 }
 
 bool HasBeenShutdown(Profile* profile) {
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
index 30f30aa0..dac90372 100644
--- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
+++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
@@ -273,6 +273,8 @@
 }
 
 void RecentTabsSubMenuModel::ExecuteCommand(int command_id, int event_flags) {
+  UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction",
+                             menu_opened_timer_.Elapsed());
   if (command_id == IDC_SHOW_HISTORY) {
     UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", SHOW_MORE,
                               LIMIT_RECENT_TAB_ACTION);
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
index 9a36f1aa..d03261a3 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
@@ -105,8 +105,7 @@
   base::string16 message = l10n_util::GetStringFUTF16(
       IDS_REFUSE_TO_RUN_AS_ROOT_2, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
 
-  chrome::ShowMessageBox(NULL, title, message,
-                         chrome::MESSAGE_BOX_TYPE_WARNING);
+  chrome::ShowWarningMessageBox(NULL, title, message);
 
   // Avoids gpu_process_transport_factory.cc(153)] Check failed:
   // per_compositor_data_.empty() when quit is chosen.
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index c14f2b9..37e1d3f 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -61,45 +61,44 @@
 using content::DownloadItem;
 using extensions::ExperienceSamplingEvent;
 
+namespace {
+
 // TODO(paulg): These may need to be adjusted when download progress
 //              animation is added, and also possibly to take into account
 //              different screen resolutions.
-static const int kTextWidth = 140;            // Pixels
-static const int kDangerousTextWidth = 200;   // Pixels
-static const int kVerticalPadding = 3;        // Pixels
-static const int kVerticalTextPadding = 2;    // Pixels
-static const int kTooltipMaxWidth = 800;      // Pixels
+const int kTextWidth = 140;            // Pixels
+const int kDangerousTextWidth = 200;   // Pixels
+const int kVerticalPadding = 3;        // Pixels
+const int kVerticalTextPadding = 2;    // Pixels
+const int kTooltipMaxWidth = 800;      // Pixels
 
 // Padding around progress indicator, on all sides.
-static const int kProgressPadding = 7;
+const int kProgressPadding = 7;
 
 // We add some padding before the left image so that the progress animation icon
 // hides the corners of the left image.
-static const int kLeftPadding = 0;  // Pixels.
+const int kLeftPadding = 0;  // Pixels.
 
 // The space between the Save and Discard buttons when prompting for a dangerous
 // download.
-static const int kButtonPadding = 5;  // Pixels.
+const int kButtonPadding = 5;  // Pixels.
 
 // The space on the left and right side of the dangerous download label.
-static const int kLabelPadding = 4;  // Pixels.
+const int kLabelPadding = 4;  // Pixels.
 
-static const SkColor kFileNameDisabledColor = SkColorSetRGB(171, 192, 212);
+const SkColor kFileNameDisabledColor = SkColorSetRGB(171, 192, 212);
 
 // How long the 'download complete' animation should last for.
-static const int kCompleteAnimationDurationMs = 2500;
+const int kCompleteAnimationDurationMs = 2500;
 
 // How long the 'download interrupted' animation should last for.
-static const int kInterruptedAnimationDurationMs = 2500;
+const int kInterruptedAnimationDurationMs = 2500;
 
 // How long we keep the item disabled after the user clicked it to open the
 // downloaded item.
-static const int kDisabledOnOpenDuration = 3000;
+const int kDisabledOnOpenDuration = 3000;
 
-// Darken light-on-dark download status text by 20% before drawing, thus
-// creating a "muted" version of title text for both dark-on-light and
-// light-on-dark themes.
-static const double kDownloadItemLuminanceMod = 0.8;
+}  // namespace
 
 DownloadItemView::DownloadItemView(DownloadItem* download_item,
     DownloadShelfView* parent)
@@ -699,16 +698,12 @@
               kVerticalTextPadding;
       SkColor file_name_color = GetThemeProvider()->GetColor(
           ThemeProperties::COLOR_BOOKMARK_TEXT);
-      // If text is light-on-dark, lightening it alone will do nothing.
-      // Therefore we mute luminance a wee bit before drawing in this case.
-      if (color_utils::RelativeLuminance(file_name_color) > 0.5)
-          file_name_color = SkColorSetRGB(
-              static_cast<int>(kDownloadItemLuminanceMod *
-                               SkColorGetR(file_name_color)),
-              static_cast<int>(kDownloadItemLuminanceMod *
-                               SkColorGetG(file_name_color)),
-              static_cast<int>(kDownloadItemLuminanceMod *
-                               SkColorGetB(file_name_color)));
+      // If text is light-on-dark, lightening it alone will do nothing.  In this
+      // case we multiply color components by 80% before drawing.
+      if (!color_utils::IsDark(file_name_color)) {
+        file_name_color =
+            color_utils::AlphaBlend(SK_ColorBLACK, file_name_color, 255 / 5);
+      }
       canvas->DrawStringRect(status_text_, font_list_, file_name_color,
                              gfx::Rect(mirrored_x, y, kTextWidth,
                                        font_list_.GetHeight()));
diff --git a/chrome/browser/ui/views/dropdown_bar_host.cc b/chrome/browser/ui/views/dropdown_bar_host.cc
index 9d5ca25..6489874e 100644
--- a/chrome/browser/ui/views/dropdown_bar_host.cc
+++ b/chrome/browser/ui/views/dropdown_bar_host.cc
@@ -45,7 +45,7 @@
   // Views which also paint to a Layer. See http://crbug.com/589497
   scoped_ptr<views::View> clip_view(new views::View());
   clip_view->SetPaintToLayer(true);
-  clip_view->SetFillsBoundsOpaquely(false);
+  clip_view->layer()->SetFillsBoundsOpaquely(false);
   clip_view->layer()->SetMasksToBounds(true);
   clip_view->AddChildView(view_);
 
diff --git a/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc
index 5b2f920..a3c156d 100644
--- a/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc
@@ -40,6 +40,9 @@
 
 namespace extensions {
 
+ExtensionMessageBubbleView*
+    ExtensionMessageBubbleView::active_bubble_for_testing_ = nullptr;
+
 ExtensionMessageBubbleView::ExtensionMessageBubbleView(
     views::View* anchor_view,
     views::BubbleBorder::Arrow arrow_location,
@@ -77,6 +80,8 @@
 }
 
 void ExtensionMessageBubbleView::OnWidgetDestroying(views::Widget* widget) {
+  if (active_bubble_for_testing_ == this)
+    active_bubble_for_testing_ = nullptr;
   // To catch Esc, we monitor destroy message. Unless the link has been clicked,
   // we assume Dismiss was the action taken.
   if (!link_clicked_ && !action_taken_) {
@@ -96,6 +101,7 @@
 ExtensionMessageBubbleView::~ExtensionMessageBubbleView() {}
 
 void ExtensionMessageBubbleView::ShowBubble() {
+  active_bubble_for_testing_ = this;
   // Since we delay in showing the bubble, the applicable extension(s) may
   // have been removed.
   if (controller_->ShouldShow()) {
diff --git a/chrome/browser/ui/views/extensions/extension_message_bubble_view.h b/chrome/browser/ui/views/extensions/extension_message_bubble_view.h
index e984189..9e3ee7d 100644
--- a/chrome/browser/ui/views/extensions/extension_message_bubble_view.h
+++ b/chrome/browser/ui/views/extensions/extension_message_bubble_view.h
@@ -20,8 +20,8 @@
 }
 
 namespace extensions {
-
 class ExtensionMessageBubbleController;
+class ExtensionMessageBubbleViewBrowserTest;
 
 // This is a class that implements the UI for the bubble showing which
 // extensions look suspicious and have therefore been automatically disabled.
@@ -43,6 +43,8 @@
   static void set_bubble_appearance_wait_time_for_testing(int time_in_seconds);
 
  private:
+  friend class ExtensionMessageBubbleViewBrowserTest;
+
   ~ExtensionMessageBubbleView() override;
 
   void ShowBubble();
@@ -80,6 +82,8 @@
 
   base::WeakPtrFactory<ExtensionMessageBubbleView> weak_factory_;
 
+  static ExtensionMessageBubbleView* active_bubble_for_testing_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleView);
 };
 
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 3cfbe16..2e7b635 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
@@ -3,12 +3,18 @@
 // found in the LICENSE file.
 
 #include "base/macros.h"
+#include "chrome/browser/extensions/ntp_overridden_bubble_delegate.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/app_menu_button.h"
 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "extensions/browser/extension_registry.h"
+#include "ui/events/event_utils.h"
+
+namespace extensions {
 
 namespace {
 
@@ -53,12 +59,31 @@
     : public ExtensionMessageBubbleBrowserTest {
  protected:
   ExtensionMessageBubbleViewBrowserTest() {
-    extensions::ExtensionMessageBubbleView::
-        set_bubble_appearance_wait_time_for_testing(0);
+    ExtensionMessageBubbleView::set_bubble_appearance_wait_time_for_testing(0);
   }
   ~ExtensionMessageBubbleViewBrowserTest() override {}
 
+  // Loads and returns an extension that overrides the new tab page.
+  const Extension* LoadNewTabExtension();
+
+  // Clicks on the |bubble|'s dismiss button.
+  void ClickDismissButton(ExtensionMessageBubbleView* bubble) {
+    ClickMessageBubbleButton(bubble, bubble->dismiss_button_);
+  }
+
+  // Clicks on the |bubble|'s action button.
+  void ClickActionButton(ExtensionMessageBubbleView* bubble) {
+    ClickMessageBubbleButton(bubble, bubble->action_button_);
+  }
+
+  ExtensionMessageBubbleView* active_message_bubble() {
+    return ExtensionMessageBubbleView::active_bubble_for_testing_;
+  }
+
  private:
+  void ClickMessageBubbleButton(ExtensionMessageBubbleView* bubble,
+                                views::Button* button);
+
   // ExtensionMessageBubbleBrowserTest:
   void CheckBubble(Browser* browser, AnchorPosition anchor) override;
   void CloseBubble(Browser* browser) override;
@@ -67,6 +92,24 @@
   DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleViewBrowserTest);
 };
 
+const Extension* ExtensionMessageBubbleViewBrowserTest::LoadNewTabExtension() {
+  base::FilePath crx_path = PackExtension(test_data_dir_.AppendASCII("api_test")
+                                              .AppendASCII("override")
+                                              .AppendASCII("newtab"));
+  EXPECT_FALSE(crx_path.empty());
+  const Extension* extension = InstallExtensionFromWebstore(crx_path, 1);
+  return extension;
+}
+
+void ExtensionMessageBubbleViewBrowserTest::ClickMessageBubbleButton(
+    ExtensionMessageBubbleView* bubble,
+    views::Button* button) {
+  gfx::Point p(button->x(), button->y());
+  ui::MouseEvent event(ui::ET_MOUSE_RELEASED, p, p, ui::EventTimeForNow(),
+                       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
+  bubble->ButtonPressed(button, event);
+}
+
 void ExtensionMessageBubbleViewBrowserTest::CheckBubble(Browser* browser,
                                                         AnchorPosition anchor) {
   ToolbarView* toolbar_view = GetToolbarViewForBrowser(browser);
@@ -129,3 +172,97 @@
                        TestUninstallDangerousExtension) {
   TestUninstallDangerousExtension();
 }
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
+                       TestClickingDismissButton) {
+  const Extension* extension = LoadNewTabExtension();
+  ASSERT_TRUE(extension);
+  const std::string extension_id = extension->id();
+
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), GURL("chrome://newtab/"), NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+
+  NtpOverriddenBubbleDelegate bubble_delegate(profile());
+  EXPECT_FALSE(bubble_delegate.HasBubbleInfoBeenAcknowledged(extension->id()));
+
+  // Check the bubble is showing.
+  base::RunLoop().RunUntilIdle();
+  ExtensionMessageBubbleView* bubble = active_message_bubble();
+  views::View* anchor_view =
+      GetToolbarViewForBrowser(browser())->app_menu_button();
+  CheckBubbleAndReferenceView(bubble, anchor_view);
+
+  // Click the dismiss button. The bubble should close, and the extension should
+  // be acknowledged (and still installed).
+  ClickDismissButton(bubble);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(active_message_bubble());
+  EXPECT_TRUE(bubble_delegate.HasBubbleInfoBeenAcknowledged(extension->id()));
+  EXPECT_TRUE(ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(
+      extension_id));
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
+                       TestClickingActionButton) {
+  const Extension* extension = LoadNewTabExtension();
+  ASSERT_TRUE(extension);
+  const std::string extension_id = extension->id();
+
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), GURL("chrome://newtab/"), NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+
+  NtpOverriddenBubbleDelegate bubble_delegate(profile());
+  EXPECT_FALSE(bubble_delegate.HasBubbleInfoBeenAcknowledged(extension->id()));
+
+  // Check the bubble is showing.
+  base::RunLoop().RunUntilIdle();
+  ExtensionMessageBubbleView* bubble = active_message_bubble();
+  views::View* anchor_view =
+      GetToolbarViewForBrowser(browser())->app_menu_button();
+  CheckBubbleAndReferenceView(bubble, anchor_view);
+
+  // Click the action button. The bubble should close, and the extension should
+  // not be acknowledged. Instead, the extension should be disabled.
+  ClickActionButton(bubble);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(active_message_bubble());
+  EXPECT_FALSE(bubble_delegate.HasBubbleInfoBeenAcknowledged(extension->id()));
+  EXPECT_FALSE(ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(
+      extension_id));
+  EXPECT_TRUE(ExtensionRegistry::Get(profile())->disabled_extensions().GetByID(
+      extension_id));
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionMessageBubbleViewBrowserTest,
+                       TestBubbleFocusLoss) {
+  const Extension* extension = LoadNewTabExtension();
+  ASSERT_TRUE(extension);
+  const std::string extension_id = extension->id();
+
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), GURL("chrome://newtab/"), NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+
+  NtpOverriddenBubbleDelegate bubble_delegate(profile());
+  EXPECT_FALSE(bubble_delegate.HasBubbleInfoBeenAcknowledged(extension->id()));
+
+  // Check the bubble is showing.
+  base::RunLoop().RunUntilIdle();
+  ExtensionMessageBubbleView* bubble = active_message_bubble();
+  views::View* anchor_view =
+      GetToolbarViewForBrowser(browser())->app_menu_button();
+  CheckBubbleAndReferenceView(bubble, anchor_view);
+
+  // Deactivate the bubble's widget (e.g. due to focus loss). This causes the
+  // bubble to close, but the extension should not be acknowledged or removed.
+  bubble->GetWidget()->Deactivate();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(active_message_bubble());
+  EXPECT_FALSE(bubble_delegate.HasBubbleInfoBeenAcknowledged(extension->id()));
+  EXPECT_TRUE(ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(
+      extension_id));
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 14b1d2e..df0119dc 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -184,7 +184,7 @@
 void ImmersiveModeControllerAsh::OnImmersiveRevealStarted() {
   visible_fraction_ = 0;
   browser_view_->top_container()->SetPaintToLayer(true);
-  browser_view_->top_container()->SetFillsBoundsOpaquely(false);
+  browser_view_->top_container()->layer()->SetFillsBoundsOpaquely(false);
   UpdateTabIndicators();
   LayoutBrowserRootView();
   FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted());
diff --git a/chrome/browser/ui/views/infobars/infobar_container_view.cc b/chrome/browser/ui/views/infobars/infobar_container_view.cc
index b50662f..450d69f5 100644
--- a/chrome/browser/ui/views/infobars/infobar_container_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_container_view.cc
@@ -19,7 +19,7 @@
   set_id(VIEW_ID_INFO_BAR_CONTAINER);
   SetEventTargeter(make_scoped_ptr(new views::ViewTargeter(this)));
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 InfoBarContainerView::~InfoBarContainerView() {
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 2e97656..3c66ce4 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
@@ -120,7 +120,7 @@
 
 void BubbleIconView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
   image_->SetPaintToLayer(true);
-  image_->SetFillsBoundsOpaquely(false);
+  image_->layer()->SetFillsBoundsOpaquely(false);
   views::InkDropHostView::AddInkDropLayer(ink_drop_layer);
 }
 
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
index f58d846..f51e30a 100644
--- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -151,7 +151,7 @@
 
 void IconLabelBubbleView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
   image()->SetPaintToLayer(true);
-  image()->SetFillsBoundsOpaquely(false);
+  image()->layer()->SetFillsBoundsOpaquely(false);
   InkDropHostView::AddInkDropLayer(ink_drop_layer);
 }
 
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index c4426aa..46469a6 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -182,7 +182,7 @@
   if (ui::MaterialDesignController::IsModeMaterial()) {
     // Make sure children with layers are clipped. See http://crbug.com/589497
     SetPaintToLayer(true);
-    SetFillsBoundsOpaquely(false);
+    layer()->SetFillsBoundsOpaquely(false);
     layer()->SetMasksToBounds(true);
   } else if (is_popup_mode_) {
     const int kOmniboxPopupBorderImages[] =
diff --git a/chrome/browser/ui/views/settings_api_bubble_helper_views.cc b/chrome/browser/ui/views/settings_api_bubble_helper_views.cc
index be6ff12e..ad5acdc 100644
--- a/chrome/browser/ui/views/settings_api_bubble_helper_views.cc
+++ b/chrome/browser/ui/views/settings_api_bubble_helper_views.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/extensions/settings_api_bubble_delegate.h"
 #include "chrome/browser/extensions/settings_api_helpers.h"
 #include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/extensions/extension_message_bubble_factory.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -46,7 +47,8 @@
 
 void MaybeShowExtensionControlledHomeNotification(Browser* browser) {
 #if !defined(OS_WIN)
-  return;
+  if (!ExtensionMessageBubbleFactory::is_enabled_for_testing())
+    return;
 #endif
 
   // The bubble will try to anchor itself against the home button
@@ -63,7 +65,8 @@
     content::WebContents* web_contents,
     AutocompleteMatch::Type match_type) {
 #if !defined(OS_WIN)
-  return;
+  if (!ExtensionMessageBubbleFactory::is_enabled_for_testing())
+    return;
 #endif
 
   if (AutocompleteMatch::IsSearchType(match_type) &&
@@ -80,7 +83,8 @@
 void MaybeShowExtensionControlledNewTabPage(
     Browser* browser, content::WebContents* web_contents) {
 #if !defined(OS_WIN)
-  return;
+  if (!ExtensionMessageBubbleFactory::is_enabled_for_testing())
+    return;
 #endif
 
   content::NavigationEntry* entry =
diff --git a/chrome/browser/ui/views/simple_message_box_views.cc b/chrome/browser/ui/views/simple_message_box_views.cc
index 3f3973c..fc3f026 100644
--- a/chrome/browser/ui/views/simple_message_box_views.cc
+++ b/chrome/browser/ui/views/simple_message_box_views.cc
@@ -90,22 +90,14 @@
       message_box_view_(new views::MessageBoxView(
           views::MessageBoxView::InitParams(message))) {
   if (yes_text_.empty()) {
-    if (type_ == MESSAGE_BOX_TYPE_QUESTION)
-      yes_text_ =
-          l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
-    else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
-      yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
-    else
-      yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
+    yes_text_ =
+        type_ == MESSAGE_BOX_TYPE_QUESTION
+            ? l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL)
+            : l10n_util::GetStringUTF16(IDS_OK);
   }
 
-  if (no_text_.empty()) {
-    if (type_ == MESSAGE_BOX_TYPE_QUESTION)
-      no_text_ =
-          l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
-    else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
-      no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL);
-  }
+  if (no_text_.empty() && type_ == MESSAGE_BOX_TYPE_QUESTION)
+    no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL);
 }
 
 SimpleMessageBoxViews::~SimpleMessageBoxViews() {
@@ -125,10 +117,8 @@
 }
 
 int SimpleMessageBoxViews::GetDialogButtons() const {
-  if (type_ == MESSAGE_BOX_TYPE_QUESTION ||
-      type_ == MESSAGE_BOX_TYPE_OK_CANCEL) {
+  if (type_ == MESSAGE_BOX_TYPE_QUESTION)
     return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
-  }
 
   return ui::DIALOG_BUTTON_OK;
 }
@@ -188,14 +178,10 @@
 UINT GetMessageBoxFlagsFromType(MessageBoxType type) {
   UINT flags = MB_SETFOREGROUND;
   switch (type) {
-    case MESSAGE_BOX_TYPE_INFORMATION:
-      return flags | MB_OK | MB_ICONINFORMATION;
     case MESSAGE_BOX_TYPE_WARNING:
       return flags | MB_OK | MB_ICONWARNING;
     case MESSAGE_BOX_TYPE_QUESTION:
       return flags | MB_YESNO | MB_ICONQUESTION;
-    case MESSAGE_BOX_TYPE_OK_CANCEL:
-      return flags | MB_OKCANCEL | MB_ICONWARNING;
   }
   NOTREACHED();
   return flags | MB_OK | MB_ICONWARNING;
@@ -250,12 +236,18 @@
 
 }  // namespace
 
-MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
-                                const base::string16& title,
-                                const base::string16& message,
-                                MessageBoxType type) {
-  return ShowMessageBoxImpl(
-      parent, title, message, type, base::string16(), base::string16());
+void ShowWarningMessageBox(gfx::NativeWindow parent,
+                           const base::string16& title,
+                           const base::string16& message) {
+  ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_WARNING,
+                     base::string16(), base::string16());
+}
+
+MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent,
+                                        const base::string16& title,
+                                        const base::string16& message) {
+  return ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_QUESTION,
+                            base::string16(), base::string16());
 }
 
 MessageBoxResult ShowMessageBoxWithButtonText(gfx::NativeWindow parent,
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index d679f6a..3b5e36f5 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -1538,9 +1538,10 @@
   const bool paint_to_layer = controller_->CanPaintThrobberToLayer();
   if (paint_to_layer != !!throbber_->layer()) {
     throbber_->SetPaintToLayer(paint_to_layer);
-    throbber_->SetFillsBoundsOpaquely(false);
-    if (paint_to_layer)
+    if (paint_to_layer) {
+      throbber_->layer()->SetFillsBoundsOpaquely(false);
       ScheduleIconPaint();  // Ensure the non-layered throbber goes away.
+    }
   }
   if (!throbber_->visible()) {
     ScheduleIconPaint();  // Repaint the icon area to hide the favicon.
diff --git a/chrome/browser/ui/views/toolbar/app_menu_button.cc b/chrome/browser/ui/views/toolbar/app_menu_button.cc
index 12c0e38..473d423 100644
--- a/chrome/browser/ui/views/toolbar/app_menu_button.cc
+++ b/chrome/browser/ui/views/toolbar/app_menu_button.cc
@@ -188,17 +188,6 @@
   InvalidateLayout();
 }
 
-gfx::Point AppMenuButton::GetInkDropCenter() const {
-  // ToolbarView extends the bounds of the app button to the right in maximized
-  // mode. So instead of using the center point of local bounds, we use the
-  // center point (adjusted for RTL layouts) of the preferred size, which
-  // doesn't change in maximized mode.
-  const int visible_width = GetPreferredSize().width();
-  return gfx::Point(
-      (GetMirroredXWithWidthInView(0, visible_width) + visible_width) / 2,
-      height() / 2);
-}
-
 const char* AppMenuButton::GetClassName() const {
   return "AppMenuButton";
 }
diff --git a/chrome/browser/ui/views/toolbar/app_menu_button.h b/chrome/browser/ui/views/toolbar/app_menu_button.h
index 06ae521..c0c4cc7 100644
--- a/chrome/browser/ui/views/toolbar/app_menu_button.h
+++ b/chrome/browser/ui/views/toolbar/app_menu_button.h
@@ -70,9 +70,6 @@
 
  private:
   // views::MenuButton:
-  gfx::Point GetInkDropCenter() const override;
-
-  // views::MenuButton:
   const char* GetClassName() const override;
   scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const override;
   gfx::Rect GetThemePaintRect() const override;
diff --git a/chrome/browser/ui/views/toolbar/back_button.cc b/chrome/browser/ui/views/toolbar/back_button.cc
index 05618a9..6e99ded 100644
--- a/chrome/browser/ui/views/toolbar/back_button.cc
+++ b/chrome/browser/ui/views/toolbar/back_button.cc
@@ -29,14 +29,6 @@
   InvalidateLayout();
 }
 
-gfx::Point BackButton::GetInkDropCenter() const {
-  int visible_width = GetPreferredSize().width();
-  return gfx::Point(
-      GetMirroredXWithWidthInView(margin_leading_, visible_width) +
-          visible_width / 2,
-      height() / 2);
-}
-
 const char* BackButton::GetClassName() const {
   return "BackButton";
 }
diff --git a/chrome/browser/ui/views/toolbar/back_button.h b/chrome/browser/ui/views/toolbar/back_button.h
index 0f11c344..25c27aa 100644
--- a/chrome/browser/ui/views/toolbar/back_button.h
+++ b/chrome/browser/ui/views/toolbar/back_button.h
@@ -39,7 +39,6 @@
   const char* GetClassName() const override;
   scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const override;
   gfx::Rect GetThemePaintRect() const override;
-  gfx::Point GetInkDropCenter() const override;
 
   // Any leading margin to be applied. Used when the back button is in
   // a maximized state to extend to the full window width.
diff --git a/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc
index 6c8d964..6ebd799 100644
--- a/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc
@@ -142,10 +142,9 @@
     return;
   }
 
-  *out_close_dialog = chrome::ShowMessageBox(dialog_window_,
-      l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE),
-      l10n_util::GetStringUTF16(IDS_MOBILE_CANCEL_ACTIVATION),
-      chrome::MESSAGE_BOX_TYPE_QUESTION);
+  *out_close_dialog = chrome::ShowQuestionMessageBox(
+      dialog_window_, l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE),
+      l10n_util::GetStringUTF16(IDS_MOBILE_CANCEL_ACTIVATION));
 }
 
 bool MobileSetupDialogDelegate::ShouldShowDialogTitle() const {
diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
index bf57e82..ebf57fde 100644
--- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
@@ -41,12 +41,8 @@
 using ui::WebDialogDelegate;
 
 namespace {
-#if defined(OS_MACOSX)
-const int kFixedHeight = 350;
-#else
 const int kMaxHeight = 2000;
 const int kMinHeight = 80;
-#endif
 const int kWidth = 340;
 }
 
@@ -114,15 +110,10 @@
 
 void MediaRouterDialogDelegate::GetDialogSize(gfx::Size* size) const {
   DCHECK(size);
-  // TODO(apacible): Remove after autoresizing is implemented for OSX.
-#if defined(OS_MACOSX)
-  *size = gfx::Size(kWidth, kFixedHeight);
-#else
   // GetDialogSize() is called when the browser window resizes. We may want to
   // update the maximum height of the dialog and scale the WebUI to the new
   // height. |size| is not set because the dialog is auto-resizeable.
   controller_->UpdateMaxDialogSize();
-#endif
 }
 
 }  // namespace
@@ -243,29 +234,21 @@
       Profile::FromBrowserContext(initiator()->GetBrowserContext());
   DCHECK(profile);
 
-  WebDialogDelegate* web_dialog_delegate =
-      new MediaRouterDialogDelegate(action_, weak_ptr_factory_.GetWeakPtr());
   // |web_dialog_delegate|'s owner is |constrained_delegate|.
   // |constrained_delegate| is owned by the parent |views::View|.
-  // TODO(apacible): Remove after autoresizing is implemented for OSX.
-#if defined(OS_MACOSX)
-  ConstrainedWebDialogDelegate* constrained_delegate =
-      ShowConstrainedWebDialog(profile, web_dialog_delegate, initiator());
-#else
-  // TODO(apacible): Adjust min and max sizes based on new WebUI design.
-  gfx::Size min_size = gfx::Size(kWidth, kMinHeight);
-  gfx::Size max_size = gfx::Size(kWidth, kMaxHeight);
+  WebDialogDelegate* web_dialog_delegate =
+      new MediaRouterDialogDelegate(action_, weak_ptr_factory_.GetWeakPtr());
 
   // |ShowConstrainedWebDialogWithAutoResize()| will end up creating
   // ConstrainedWebDialogDelegateViewViews containing a WebContents containing
   // the MediaRouterUI, using the provided |web_dialog_delegate|. Then, the
   // view is shown as a modal dialog constrained to the |initiator| WebContents.
-  // The dialog will resize between the |min_size| and |max_size| bounds based
-  // on the currently rendered contents.
+  // The dialog will resize between the given minimum and maximum size bounds
+  // based on the currently rendered contents.
   ConstrainedWebDialogDelegate* constrained_delegate =
       ShowConstrainedWebDialogWithAutoResize(
-          profile, web_dialog_delegate, initiator(), min_size, max_size);
-#endif
+          profile, web_dialog_delegate, initiator(),
+              gfx::Size(kWidth, kMinHeight), gfx::Size(kWidth, kMaxHeight));
 
   WebContents* media_router_dialog = constrained_delegate->GetWebContents();
   TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("media_router", "UI", initiator(),
diff --git a/chrome/browser/ui/webui/ntp/core_app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/core_app_launcher_handler.cc
index 05349b99..4257360 100644
--- a/chrome/browser/ui/webui/ntp/core_app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/core_app_launcher_handler.cc
@@ -18,7 +18,8 @@
 
 namespace {
 const net::UnescapeRule::Type kUnescapeRules =
-    net::UnescapeRule::NORMAL | net::UnescapeRule::URL_SPECIAL_CHARS;
+    net::UnescapeRule::NORMAL | net::UnescapeRule::PATH_SEPARATORS |
+    net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS;
 }
 
 CoreAppLauncherHandler::CoreAppLauncherHandler() {}
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 1e56c52..fbf5f2d 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -7,8 +7,6 @@
 #include <stddef.h>
 
 #include <set>
-#include <string>
-#include <vector>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -197,8 +195,9 @@
   // message loops of the FILE and UI thread will hold references to it
   // and it will be automatically freed once all its tasks have finished.
   default_browser_worker_ = new shell_integration::DefaultBrowserWorker(
-      this, /*delete_observer=*/false);
-#endif
+      base::Bind(&BrowserOptionsHandler::OnDefaultBrowserWorkerFinished,
+                 weak_ptr_factory_.GetWeakPtr()));
+#endif  // !defined(OS_CHROMEOS)
 
 #if defined(ENABLE_SERVICE_DISCOVERY)
   cloud_print_mdns_ui_enabled_ = true;
@@ -211,10 +210,6 @@
   if (sync_service)
     sync_service->RemoveObserver(this);
 
-#if !defined(OS_CHROMEOS)
-  if (default_browser_worker_.get())
-    default_browser_worker_->ObserverDestroyed();
-#endif
   if (template_url_service_)
     template_url_service_->RemoveObserver(this);
   // There may be pending file dialogs, we need to tell them that we've gone
@@ -1106,6 +1101,7 @@
 }
 
 #if !defined(OS_CHROMEOS)
+
 void BrowserOptionsHandler::UpdateDefaultBrowserState() {
   default_browser_worker_->StartCheckIsDefault();
 }
@@ -1128,7 +1124,7 @@
   prefs->SetBoolean(prefs::kCheckDefaultBrowser, true);
 }
 
-void BrowserOptionsHandler::SetDefaultWebClientUIState(
+void BrowserOptionsHandler::OnDefaultBrowserWorkerFinished(
     shell_integration::DefaultWebClientUIState state) {
   int status_string_id;
 
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.h b/chrome/browser/ui/webui/options/browser_options_handler.h
index edeced0..465e503 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.h
+++ b/chrome/browser/ui/webui/options/browser_options_handler.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_BROWSER_OPTIONS_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_OPTIONS_BROWSER_OPTIONS_HANDLER_H_
 
+#include <string>
 #include <vector>
 
 #include "base/compiler_specific.h"
@@ -61,9 +62,6 @@
       public sync_driver::SyncServiceObserver,
       public SigninManagerBase::Observer,
       public ui::SelectFileDialog::Listener,
-#if !defined(OS_CHROMEOS)
-      public shell_integration::DefaultWebClientObserver,
-#endif
 #if defined(OS_CHROMEOS)
       public chromeos::system::PointerDeviceObserver::Observer,
       public policy::ConsumerManagementService::Observer,
@@ -177,9 +175,9 @@
   // Makes this the default browser. Called from WebUI.
   void BecomeDefaultBrowser(const base::ListValue* args);
 
-  // shell_integration::DefaultWebClientObserver implementation.
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override;
+  // Receives the default browser state when the worker is done.
+  void OnDefaultBrowserWorkerFinished(
+      shell_integration::DefaultWebClientUIState state);
 
   // Updates the UI with the given state for the default browser.
   void SetDefaultBrowserUIString(int status_string_id);
diff --git a/chrome/browser/ui/webui/set_as_default_browser_ui.cc b/chrome/browser/ui/webui/set_as_default_browser_ui.cc
index 6938596d..2aeb4d88 100644
--- a/chrome/browser/ui/webui/set_as_default_browser_ui.cc
+++ b/chrome/browser/ui/webui/set_as_default_browser_ui.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/ui/webui/set_as_default_browser_ui.h"
 
+#include <string>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
@@ -93,22 +96,14 @@
 // Event handler for SetAsDefaultBrowserUI. Capable of setting Chrome as the
 // default browser on button click, closing itself and triggering Chrome
 // restart.
-class SetAsDefaultBrowserHandler
-    : public WebUIMessageHandler,
-      public base::SupportsWeakPtr<SetAsDefaultBrowserHandler>,
-      public shell_integration::DefaultWebClientObserver {
+class SetAsDefaultBrowserHandler : public WebUIMessageHandler {
  public:
   explicit SetAsDefaultBrowserHandler(
       const base::WeakPtr<ResponseDelegate>& response_delegate);
-  ~SetAsDefaultBrowserHandler() override;
 
   // WebUIMessageHandler implementation.
   void RegisterMessages() override;
 
-  // shell_integration::DefaultWebClientObserver implementation.
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override;
-
  private:
   // Handler for the 'Next' (or 'make Chrome the Metro browser') button.
   void HandleLaunchSetDefaultBrowserFlow(const base::ListValue* args);
@@ -116,6 +111,9 @@
   // Close this web ui.
   void ConcludeInteraction(MakeChromeDefaultResult interaction_result);
 
+  void OnDefaultBrowserWorkerFinished(
+      shell_integration::DefaultWebClientUIState state);
+
   // The worker pointer is reference counted. While it is running, the
   // message loops of the FILE and UI thread will hold references to it
   // and it will be automatically freed once all its tasks have finished.
@@ -123,18 +121,18 @@
       default_browser_worker_;
   base::WeakPtr<ResponseDelegate> response_delegate_;
 
+  // Used to invalidate the DefaultBrowserWorker callback.
+  base::WeakPtrFactory<SetAsDefaultBrowserHandler> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(SetAsDefaultBrowserHandler);
 };
 
 SetAsDefaultBrowserHandler::SetAsDefaultBrowserHandler(
     const base::WeakPtr<ResponseDelegate>& response_delegate)
-    : default_browser_worker_(new shell_integration::DefaultBrowserWorker(
-          this,
-          /*delete_observer=*/false)),
-      response_delegate_(response_delegate) {}
-
-SetAsDefaultBrowserHandler::~SetAsDefaultBrowserHandler() {
-  default_browser_worker_->ObserverDestroyed();
+    : response_delegate_(response_delegate), weak_ptr_factory_(this) {
+  default_browser_worker_ = new shell_integration::DefaultBrowserWorker(
+      base::Bind(&SetAsDefaultBrowserHandler::OnDefaultBrowserWorkerFinished,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void SetAsDefaultBrowserHandler::RegisterMessages() {
@@ -144,22 +142,6 @@
                  base::Unretained(this)));
 }
 
-void SetAsDefaultBrowserHandler::SetDefaultWebClientUIState(
-    shell_integration::DefaultWebClientUIState state) {
-  // The callback is expected to be invoked once the procedure has completed.
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (state == shell_integration::STATE_NOT_DEFAULT) {
-    // The operation concluded, but Chrome is still not the default. This
-    // suggests the user has decided not to make Chrome the default.
-    ConcludeInteraction(MAKE_CHROME_DEFAULT_REGRETTED);
-  } else if (state == shell_integration::STATE_IS_DEFAULT) {
-    ConcludeInteraction(MAKE_CHROME_DEFAULT_ACCEPTED);
-  }
-
-  // Otherwise, keep the dialog open since the user probably didn't make a
-  // choice.
-}
-
 void SetAsDefaultBrowserHandler::HandleLaunchSetDefaultBrowserFlow(
     const base::ListValue* args) {
   default_browser_worker_->StartSetAsDefault();
@@ -181,6 +163,22 @@
   }
 }
 
+void SetAsDefaultBrowserHandler::OnDefaultBrowserWorkerFinished(
+    shell_integration::DefaultWebClientUIState state) {
+  // The callback is expected to be invoked once the procedure has completed.
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (state == shell_integration::STATE_NOT_DEFAULT) {
+    // The operation concluded, but Chrome is still not the default. This
+    // suggests the user has decided not to make Chrome the default.
+    ConcludeInteraction(MAKE_CHROME_DEFAULT_REGRETTED);
+  } else if (state == shell_integration::STATE_IS_DEFAULT) {
+    ConcludeInteraction(MAKE_CHROME_DEFAULT_ACCEPTED);
+  }
+
+  // Otherwise, keep the dialog open since the user probably didn't make a
+  // choice.
+}
+
 // A web dialog delegate implementation for when 'Make Chrome Metro' UI
 // is displayed on a dialog.
 class SetAsDefaultBrowserDialogImpl : public ui::WebDialogDelegate,
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 76870e7..a64c015 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -573,6 +573,10 @@
                                   IDS_SETTINGS_PASSWORDS_EXCEPTIONS_HEADING);
   html_source->AddLocalizedString("deletePasswordException",
                                   IDS_SETTINGS_PASSWORDS_DELETE_EXCEPTION);
+  html_source->AddLocalizedString("passwordMenu", IDS_SETTINGS_PASSWORDS_MENU);
+  html_source->AddLocalizedString("editPassword", IDS_SETTINGS_PASSWORDS_EDIT);
+  html_source->AddLocalizedString("removePassword",
+                                  IDS_SETTINGS_PASSWORDS_REMOVE);
 }
 
 void AddPeopleStrings(content::WebUIDataSource* html_source) {
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
index fa60315ce..881be4d 100644
--- a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
@@ -21,18 +21,17 @@
 }  // namespace
 
 DefaultBrowserHandler::DefaultBrowserHandler(content::WebUI* webui)
-    : default_browser_worker_(new shell_integration::DefaultBrowserWorker(
-          this,
-          /*delete_observer=*/false)) {
+    : weak_ptr_factory_(this) {
+  default_browser_worker_ = new shell_integration::DefaultBrowserWorker(
+      base::Bind(&DefaultBrowserHandler::OnDefaultBrowserWorkerFinished,
+                 weak_ptr_factory_.GetWeakPtr()));
   default_browser_policy_.Init(
       prefs::kDefaultBrowserSettingEnabled, g_browser_process->local_state(),
       base::Bind(&DefaultBrowserHandler::RequestDefaultBrowserState,
                  base::Unretained(this), nullptr));
 }
 
-DefaultBrowserHandler::~DefaultBrowserHandler() {
-  default_browser_worker_->ObserverDestroyed();
-}
+DefaultBrowserHandler::~DefaultBrowserHandler() {}
 
 void DefaultBrowserHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback(
@@ -45,7 +44,23 @@
                  base::Unretained(this)));
 }
 
-void DefaultBrowserHandler::SetDefaultWebClientUIState(
+void DefaultBrowserHandler::RequestDefaultBrowserState(
+    const base::ListValue* /*args*/) {
+  default_browser_worker_->StartCheckIsDefault();
+}
+
+void DefaultBrowserHandler::SetAsDefaultBrowser(const base::ListValue* args) {
+  CHECK(!IsDisabledByPolicy(default_browser_policy_));
+
+  default_browser_worker_->StartSetAsDefault();
+
+  // If the user attempted to make Chrome the default browser, notify
+  // them when this changes.
+  Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean(
+      prefs::kCheckDefaultBrowser, true);
+}
+
+void DefaultBrowserHandler::OnDefaultBrowserWorkerFinished(
     shell_integration::DefaultWebClientUIState state) {
   if (state == shell_integration::STATE_PROCESSING)
     return;
@@ -69,20 +84,4 @@
                                    is_default, can_be_default);
 }
 
-void DefaultBrowserHandler::RequestDefaultBrowserState(
-    const base::ListValue* /*args*/) {
-  default_browser_worker_->StartCheckIsDefault();
-}
-
-void DefaultBrowserHandler::SetAsDefaultBrowser(const base::ListValue* args) {
-  CHECK(!IsDisabledByPolicy(default_browser_policy_));
-
-  default_browser_worker_->StartSetAsDefault();
-
-  // If the user attempted to make Chrome the default browser, notify
-  // them when this changes.
-  Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean(
-      prefs::kCheckDefaultBrowser, true);
-}
-
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.h b/chrome/browser/ui/webui/settings/settings_default_browser_handler.h
index 9aa4dfe..25c63a6 100644
--- a/chrome/browser/ui/webui/settings/settings_default_browser_handler.h
+++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_DEFAULT_BROWSER_HANDLER_H_
 
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/ui/webui/settings/md_settings_ui.h"
@@ -24,9 +25,7 @@
 // The application used by the OS to open web documents (e.g. *.html)
 // is the "default browser".  This class is an API for the JavaScript
 // settings code to change the default browser settings.
-class DefaultBrowserHandler
-    : public SettingsPageUIHandler,
-      public shell_integration::DefaultWebClientObserver {
+class DefaultBrowserHandler : public SettingsPageUIHandler {
  public:
   explicit DefaultBrowserHandler(content::WebUI* webui);
   ~DefaultBrowserHandler() override;
@@ -34,10 +33,6 @@
   // SettingsPageUIHandler implementation.
   void RegisterMessages() override;
 
-  // shell_integration::DefaultWebClientObserver implementation.
-  void SetDefaultWebClientUIState(
-      shell_integration::DefaultWebClientUIState state) override;
-
  private:
   // Called from WebUI to request the current state.
   void RequestDefaultBrowserState(const base::ListValue* args);
@@ -45,6 +40,11 @@
   // Makes this the default browser. Called from WebUI.
   void SetAsDefaultBrowser(const base::ListValue* args);
 
+  // Called with the default browser state when the DefaultBrowserWorker is
+  // done.
+  void OnDefaultBrowserWorkerFinished(
+      shell_integration::DefaultWebClientUIState state);
+
   // Reference to a background worker that handles default browser settings.
   scoped_refptr<shell_integration::DefaultBrowserWorker>
       default_browser_worker_;
@@ -52,6 +52,9 @@
   // Policy setting to determine if default browser setting is managed.
   BooleanPrefMember default_browser_policy_;
 
+  // Used to invalidate the DefaultBrowserWorker callback.
+  base::WeakPtrFactory<DefaultBrowserHandler> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(DefaultBrowserHandler);
 };
 
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 01b4820..81e4906 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1402,8 +1402,6 @@
       'browser/hang_monitor/hung_window_detector.h',
       'browser/password_manager/password_manager_util_win.cc',
       'browser/password_manager/password_manager_util_win.h',
-      'browser/themes/theme_service_win.cc',
-      'browser/themes/theme_service_win.h',
     ],
     'chrome_browser_non_win_sources': [
       'browser/profile_resetter/triggered_profile_resetter_stub.cc',
diff --git a/chrome/chrome_nibs.gypi b/chrome/chrome_nibs.gypi
index 58a2ef5..bae67f4f 100644
--- a/chrome/chrome_nibs.gypi
+++ b/chrome/chrome_nibs.gypi
@@ -50,7 +50,6 @@
       'app/nibs/Toolbar.xib',
     ],  # mac_translated_xibs
     'mac_untranslated_xibs': [
-      'app/nibs/ActionBoxMenuItem.xib',
       'app/nibs/BookmarkBarFolderWindow.xib',
       'app/nibs/DevicePermissionsPrompt.xib',
       'app/nibs/ExtensionInstalledBubbleBundle.xib',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 6c50c3a..825418d 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2443,9 +2443,15 @@
           'sources!': [
             'browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc',
             'browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc',
+            'browser/media/chrome_webrtc_apprtc_browsertest.cc',
+            'browser/media/chrome_webrtc_audio_quality_browsertest.cc',
             'browser/media/chrome_webrtc_browsertest.cc',
             'browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc',
             'browser/media/chrome_webrtc_getmediadevices_browsertest.cc',
+            'browser/media/chrome_webrtc_perf_browsertest.cc',
+            'browser/media/chrome_webrtc_simulcast_browsertest.cc',
+            'browser/media/chrome_webrtc_video_quality_browsertest.cc',
+            'browser/media/chrome_webrtc_webcam_browsertest.cc',
          ],
         }],
         ['OS=="win"', {
diff --git a/chrome/common/chrome_paths_win.cc b/chrome/common/chrome_paths_win.cc
index 37a262c..4713a0a6 100644
--- a/chrome/common/chrome_paths_win.cc
+++ b/chrome/common/chrome_paths_win.cc
@@ -11,6 +11,7 @@
 #include <shobjidl.h>
 
 #include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/win/scoped_co_mem.h"
 #include "chrome/common/chrome_constants.h"
@@ -124,6 +125,10 @@
   // Windows. See https://crbug.com/564398.
   if (!GetDefaultUserDataDirectory(crash_dir))
     return false;
+  // We have to make sure the user data dir exists on first run. See
+  // http://crbug.com/591504.
+  if (!PathExists(*crash_dir) && !CreateDirectory(*crash_dir))
+    return false;
   *crash_dir = crash_dir->Append(FILE_PATH_LITERAL("Crashpad"));
   return true;
 }
diff --git a/chrome/common/extensions/api/page_action.json b/chrome/common/extensions/api/page_action.json
index bd0bd0ff..a53c02e 100644
--- a/chrome/common/extensions/api/page_action.json
+++ b/chrome/common/extensions/api/page_action.json
@@ -5,7 +5,7 @@
 [
   {
     "namespace": "pageAction",
-    "description": "Use the <code>chrome.pageAction</code> API to put icons inside the address bar. Page actions represent actions that can be taken on the current page, but that aren't applicable to all pages.",
+    "description": "Use the <code>chrome.pageAction</code> API to put icons in the main Google Chrome toolbar, to the right of the address bar. Page actions represent actions that can be taken on the current page, but that aren't applicable to all pages. Page actions appear grayed out when inactive.",
     "types": [
       {
         "id": "ImageDataType",
@@ -27,7 +27,7 @@
       {
         "name": "hide",
         "type": "function",
-        "description": "Hides the page action.",
+        "description": "Hides the page action. Hidden page actions still appear in the Chrome toolbar, but are grayed out.",
         "parameters": [
           {"type": "integer", "name": "tabId", "minimum": 0, "description": "The id of the tab for which you want to modify the page action."}
         ]
diff --git a/chrome/common/extensions/docs/static/images/overview/arch-1.gif b/chrome/common/extensions/docs/static/images/overview/arch-1.gif
deleted file mode 100644
index 16d4a84f..0000000
--- a/chrome/common/extensions/docs/static/images/overview/arch-1.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/overview/browser-action-with-popup.png b/chrome/common/extensions/docs/static/images/overview/browser-action-with-popup.png
deleted file mode 100644
index 7339a7c1..0000000
--- a/chrome/common/extensions/docs/static/images/overview/browser-action-with-popup.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/overview/browser-action.png b/chrome/common/extensions/docs/static/images/overview/browser-action.png
deleted file mode 100644
index 4390b8f..0000000
--- a/chrome/common/extensions/docs/static/images/overview/browser-action.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/overview/browser_arrow.png b/chrome/common/extensions/docs/static/images/overview/browser_arrow.png
new file mode 100644
index 0000000..cf00dba5
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/overview/browser_arrow.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/overview/mappy.png b/chrome/common/extensions/docs/static/images/overview/mappy.png
new file mode 100644
index 0000000..255a273a
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/overview/mappy.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/overview/page-action.png b/chrome/common/extensions/docs/static/images/overview/page-action.png
deleted file mode 100644
index 2f6269b098..0000000
--- a/chrome/common/extensions/docs/static/images/overview/page-action.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/overview/page_color.png b/chrome/common/extensions/docs/static/images/overview/page_color.png
new file mode 100644
index 0000000..52645cd1
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/overview/page_color.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/page-action.png b/chrome/common/extensions/docs/static/images/page-action.png
deleted file mode 100644
index 618eec85..0000000
--- a/chrome/common/extensions/docs/static/images/page-action.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/page_action.png b/chrome/common/extensions/docs/static/images/page_action.png
new file mode 100644
index 0000000..1cd80d4
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/page_action.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/page_action_grey.png b/chrome/common/extensions/docs/static/images/page_action_grey.png
new file mode 100644
index 0000000..900f44bd
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/page_action_grey.png
Binary files differ
diff --git a/chrome/common/extensions/docs/templates/articles/overview.html b/chrome/common/extensions/docs/templates/articles/overview.html
index e8eb982..dade067a 100644
--- a/chrome/common/extensions/docs/templates/articles/overview.html
+++ b/chrome/common/extensions/docs/templates/articles/overview.html
@@ -40,25 +40,25 @@
 Each extension can have at most one browser action or page action.
 Choose a <b>browser action</b> when the extension is relevant to most pages.
 Choose a <b>page action</b> when the extension's icon
-should appear or disappear,
+should be active or inactive (and grayed out),
 depending on the page.
 </p>
 
 <table class="simple">
 <tr>
   <td width="33%">
-    <img src="{{static}}/images/overview/browser-action.png"
-      width="147" height="100"
+    <img src="{{static}}/images/overview/browser_arrow.png"
+      width="102" height="90"
       alt="screenshot" />
   </td>
   <td width="33%">
-    <img src="{{static}}/images/overview/page-action.png"
-      width="147" height="100"
+    <img src="{{static}}/images/overview/mappy.png"
+      width="79" height="90"
       alt="screenshot" />
   </td>
   <td>
-    <img src="{{static}}/images/overview/browser-action-with-popup.png"
-      width="147" height="100"
+    <img src="{{static}}/images/overview/page_color.png"
+      width="107" height="90"
       alt="screenshot" />
   </td>
 </tr>
@@ -66,18 +66,16 @@
 <tr>
   <td>
     This <a href="samples#google-mail-checker">Google Mail Checker extension</a>
-    uses a <em>browser action</em>
-    (icon in the toolbar).
+    uses a <em>browser action</em>.
   </td>
   <td>
     This <a href="samples#mappy">Mappy extension</a>
     uses a <em>page action</em>
-    (icon in the address bar)
     and <em>content script</em>
     (code injected into a web page).
   </td>
   <td>
-    This <a href="samples#news-reader">News Reader extension</a>
+    This <a href="samples#set_page_color">Set Page Color extension</a>
     features a browser action that,
     when clicked,
     shows a <em>popup</em>.
@@ -236,23 +234,9 @@
 <h3 id="background_page">The background page</h3>
 
 <p>
-The following figure shows a browser
-that has at least two extensions installed:
-a browser action (yellow icon)
-and a page action (blue icon).
-Both the browser action and the page action
-have background pages.
-This figure shows the browser action's background page,
-which is defined by <code>background.html</code>
-and has JavaScript code that controls
-the behavior of the browser action in both windows.
-</p>
-
-<img src="{{static}}/images/overview/arch-1.gif"
- width="232" height="168"
- alt="Two windows and a box representing a background page (background.html). One window has a yellow icon; the other has both a yellow icon and a blue icon. The yellow icons are connected to the background page." />
-
-<p>
+Background pages defined by <code>background.html</code>
+can include JavaScript code that controls
+the behavior of the extension.
 There are two types of background pages:
 <a href="background_pages">persistent background pages</a>,
 and <a href="event_pages">event pages</a>. Persistent
diff --git a/chrome/common/extensions/docs/templates/intros/pageAction.html b/chrome/common/extensions/docs/templates/intros/pageAction.html
index d547e21..dcd241a 100644
--- a/chrome/common/extensions/docs/templates/intros/pageAction.html
+++ b/chrome/common/extensions/docs/templates/intros/pageAction.html
@@ -13,12 +13,22 @@
 the RSS feed for the current page.
 </p>
 
-<img src="{{static}}/images/page-action.png"
-  width="361" height="79" />
+<img src="{{static}}/images/page_action.png"
+  width="600" height="43" />
 
 <p>
-If you want the extension's icon to always be visible,
-use a <a href="browserAction">browser action</a> instead.
+Hidden page actions appear grayed out.
+For example,
+the RSS feed below is grayed out,
+as you can't subscribe to the feed for the current page:
+</p>
+
+<img src="{{static}}/images/page_action_grey.png"
+  width="600" height="43" />
+
+<p>
+Please consider using a  <a href="browserAction">browser action</a> instead,
+so that users can always interact with your extension.
 </p>
 
 <h2 id="manifest">Manifest</h2>
@@ -70,17 +80,17 @@
 page actions can have an icon,
 a tooltip, and popup;
 they can't have badges, however.
-In addition, page actions can appear and disappear.
+In addition, page actions can be grayed out.
 You can find information about icons, tooltips, and popups
 by reading about the
 <a href="browserAction#ui">browser action UI</a>.
 </p>
 
 <p>
-You make a page action appear and disappear using the
+You make a page action appear and be grayed out using the
 $(ref:pageAction.show) and
 $(ref:pageAction.hide) methods, respectively.
-By default, a page action is hidden.
+By default, a page action appears grayed out.
 When you show it, you specify the tab
 in which the icon should appear.
 The icon remains visible
@@ -89,9 +99,6 @@
 (because the user clicks a link, for example).
 </p>
 
-
-
-
 <h2 id="tips">Tips</h2>
 
 <p>For the best visual impact,
diff --git a/chrome/common/instant_types.cc b/chrome/common/instant_types.cc
index d28091a8..5555221 100644
--- a/chrome/common/instant_types.cc
+++ b/chrome/common/instant_types.cc
@@ -105,7 +105,8 @@
 
   const net::UnescapeRule::Type unescape_rules =
       net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS |
-      net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
+      net::UnescapeRule::SPACES | net::UnescapeRule::PATH_SEPARATORS |
+      net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
       net::UnescapeRule::NORMAL | net::UnescapeRule::REPLACE_PLUS_WITH_SPACE;
 
   while (url::ExtractQueryKeyValue(url_params.c_str(), &query, &key, &value)) {
diff --git a/chrome/common/variations/variations_util.cc b/chrome/common/variations/variations_util.cc
index 423b792..cd5062d6 100644
--- a/chrome/common/variations/variations_util.cc
+++ b/chrome/common/variations/variations_util.cc
@@ -22,7 +22,9 @@
 namespace {
 
 std::string EscapeValue(const std::string& value) {
-  return net::UnescapeURLComponent(value, net::UnescapeRule::URL_SPECIAL_CHARS);
+  return net::UnescapeURLComponent(
+      value, net::UnescapeRule::PATH_SEPARATORS |
+                 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
 }
 
 } // namespace
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index a55ef6b..c57b98c 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1094,9 +1094,15 @@
       sources -= [
         "../browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc",
         "../browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc",
+        "../browser/media/chrome_webrtc_apprtc_browsertest.cc",
+        "../browser/media/chrome_webrtc_audio_quality_browsertest.cc",
         "../browser/media/chrome_webrtc_browsertest.cc",
         "../browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc",
         "../browser/media/chrome_webrtc_getmediadevices_browsertest.cc",
+        "../browser/media/chrome_webrtc_perf_browsertest.cc",
+        "../browser/media/chrome_webrtc_simulcast_browsertest.cc",
+        "../browser/media/chrome_webrtc_video_quality_browsertest.cc",
+        "../browser/media/chrome_webrtc_webcam_browsertest.cc",
       ]
     }
     if (enable_media_router) {
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 74c7d01..9c64443 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -83,6 +83,7 @@
 #include "content/public/test/mock_resource_context.h"
 #include "content/public/test/test_utils.h"
 #include "extensions/common/constants.h"
+#include "net/cookies/cookie_store.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_test_util.h"
@@ -162,9 +163,12 @@
   TestExtensionURLRequestContext() {
     content::CookieStoreConfig cookie_config;
     cookie_config.cookieable_schemes.push_back(extensions::kExtensionScheme);
-    set_cookie_store(content::CreateCookieStore(cookie_config));
+    cookie_store_ = content::CreateCookieStore(cookie_config);
+    set_cookie_store(cookie_store_.get());
   }
 
+  scoped_ptr<net::CookieStore> cookie_store_;
+
   ~TestExtensionURLRequestContext() override { AssertNoURLRequests(); }
 };
 
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc
index 9f52f06..392ff45b 100644
--- a/chrome/test/base/v8_unit_test.cc
+++ b/chrome/test/base/v8_unit_test.cc
@@ -11,6 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "chrome/common/chrome_paths.h"
 #include "third_party/WebKit/public/web/WebKit.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 
 namespace {
 
@@ -95,6 +96,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Value> function_property =
       context->Global()->Get(v8::String::NewFromUtf8(isolate, "runTest"));
@@ -209,6 +211,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
   v8::Local<v8::String> source =
       v8::String::NewFromUtf8(isolate,
                               script_source.data(),
@@ -257,6 +260,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Value> function_property = context->Global()->Get(
       v8::String::NewFromUtf8(isolate, function_name.c_str()));
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc
index d178fd8..ce29f03 100644
--- a/chrome/test/chromedriver/chrome_launcher.cc
+++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -471,6 +471,8 @@
     switches.SetUnparsedSwitch(common_switch);
   for (auto android_switch : kAndroidSwitches)
     switches.SetUnparsedSwitch(android_switch);
+  for (auto excluded_switch : capabilities.exclude_switches)
+    switches.RemoveSwitch(excluded_switch);
   status = device->SetUp(capabilities.android_package,
                          capabilities.android_activity,
                          capabilities.android_process,
diff --git a/chrome/utility/importer/bookmark_html_reader.cc b/chrome/utility/importer/bookmark_html_reader.cc
index 11e07500..a9edfeb 100644
--- a/chrome/utility/importer/bookmark_html_reader.cc
+++ b/chrome/utility/importer/bookmark_html_reader.cc
@@ -267,8 +267,8 @@
   if (url_spec.empty())
     return false;
 
-  url_spec = net::UnescapeURLComponent(url_spec,
-                                       net::UnescapeRule::URL_SPECIAL_CHARS);
+  url_spec = net::UnescapeURLComponent(
+      url_spec, net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
 
   // Replace replacement terms ("%s") in |url_spec| with {searchTerms}.
   url_spec =
diff --git a/chromecast/app/BUILD.gn b/chromecast/app/BUILD.gn
index 4d5b8b3..77cd668 100644
--- a/chromecast/app/BUILD.gn
+++ b/chromecast/app/BUILD.gn
@@ -18,6 +18,7 @@
     "//chromecast/browser",
     "//chromecast/common",
     "//chromecast/renderer",
+    "//chromecast/utility",
     "//components/crash/content/app:lib",
     "//content/public/app:both",
     "//content/public/browser",
diff --git a/chromecast/app/cast_main_delegate.cc b/chromecast/app/cast_main_delegate.cc
index b2f9884..7460175 100644
--- a/chromecast/app/cast_main_delegate.cc
+++ b/chromecast/app/cast_main_delegate.cc
@@ -23,6 +23,7 @@
 #include "chromecast/common/cast_resource_delegate.h"
 #include "chromecast/common/global_descriptors.h"
 #include "chromecast/renderer/cast_content_renderer_client.h"
+#include "chromecast/utility/cast_content_utility_client.h"
 #include "components/crash/content/app/crash_reporter_client.h"
 #include "content/public/browser/browser_main_runner.h"
 #include "content/public/common/content_switches.h"
@@ -234,5 +235,10 @@
   return renderer_client_.get();
 }
 
+content::ContentUtilityClient* CastMainDelegate::CreateContentUtilityClient() {
+  utility_client_ = CastContentUtilityClient::Create();
+  return utility_client_.get();
+}
+
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/app/cast_main_delegate.h b/chromecast/app/cast_main_delegate.h
index 010f28f..19cdfa3 100644
--- a/chromecast/app/cast_main_delegate.h
+++ b/chromecast/app/cast_main_delegate.h
@@ -23,6 +23,7 @@
 
 class CastContentBrowserClient;
 class CastContentRendererClient;
+class CastContentUtilityClient;
 
 class CastMainDelegate : public content::ContentMainDelegate {
  public:
@@ -41,12 +42,14 @@
 #endif  // !defined(OS_ANDROID)
   content::ContentBrowserClient* CreateContentBrowserClient() override;
   content::ContentRendererClient* CreateContentRendererClient() override;
+  content::ContentUtilityClient* CreateContentUtilityClient() override;
 
  private:
   void InitializeResourceBundle();
 
   scoped_ptr<CastContentBrowserClient> browser_client_;
   scoped_ptr<CastContentRendererClient> renderer_client_;
+  scoped_ptr<CastContentUtilityClient> utility_client_;
   scoped_ptr<CastResourceDelegate> resource_delegate_;
   CastContentClient content_client_;
 
diff --git a/chromecast/browser/url_request_context_factory.cc b/chromecast/browser/url_request_context_factory.cc
index f935c23..808ccba 100644
--- a/chromecast/browser/url_request_context_factory.cc
+++ b/chromecast/browser/url_request_context_factory.cc
@@ -301,6 +301,8 @@
   system_transaction_factory_.reset(new net::HttpNetworkLayer(
       new net::HttpNetworkSession(system_params)));
   system_job_factory_.reset(new net::URLRequestJobFactoryImpl());
+  system_cookie_store_ =
+      content::CreateCookieStore(content::CookieStoreConfig());
 
   net::URLRequestContext* system_context = new net::URLRequestContext();
   system_context->set_host_resolver(host_resolver_.get());
@@ -319,8 +321,7 @@
   system_context->set_http_user_agent_settings(
       http_user_agent_settings_.get());
   system_context->set_job_factory(system_job_factory_.get());
-  system_context->set_cookie_store(
-      content::CreateCookieStore(content::CookieStoreConfig()));
+  system_context->set_cookie_store(system_cookie_store_.get());
   system_context->set_network_delegate(system_network_delegate_.get());
   system_context->set_net_log(net_log_);
   return system_context;
@@ -368,12 +369,8 @@
 
   content::CookieStoreConfig cookie_config(
       browser_context->GetPath().Append(kCookieStoreFile),
-      content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
-      NULL, NULL);
-  cookie_config.background_task_runner =
-      scoped_refptr<base::SequencedTaskRunner>();
-  scoped_refptr<net::CookieStore> cookie_store =
-      content::CreateCookieStore(cookie_config);
+      content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, nullptr, nullptr);
+  main_cookie_store_ = content::CreateCookieStore(cookie_config);
 
   net::URLRequestContext* main_context = new net::URLRequestContext();
   main_context->set_host_resolver(host_resolver_.get());
@@ -386,7 +383,7 @@
       http_auth_handler_factory_.get());
   main_context->set_http_server_properties(
       http_server_properties_->GetWeakPtr());
-  main_context->set_cookie_store(cookie_store.get());
+  main_context->set_cookie_store(main_cookie_store_.get());
   main_context->set_http_user_agent_settings(
       http_user_agent_settings_.get());
 
diff --git a/chromecast/browser/url_request_context_factory.h b/chromecast/browser/url_request_context_factory.h
index c0d881d..31bbf14 100644
--- a/chromecast/browser/url_request_context_factory.h
+++ b/chromecast/browser/url_request_context_factory.h
@@ -9,6 +9,7 @@
 #include "net/http/http_network_session.h"
 
 namespace net {
+class CookieStore;
 class HttpTransactionFactory;
 class HttpUserAgentSettings;
 class NetLog;
@@ -106,10 +107,12 @@
   scoped_ptr<net::HttpServerProperties> http_server_properties_;
   scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings_;
   scoped_ptr<net::HttpTransactionFactory> system_transaction_factory_;
+  scoped_ptr<net::CookieStore> system_cookie_store_;
   scoped_ptr<net::URLRequestJobFactory> system_job_factory_;
 
   bool main_dependencies_initialized_;
   scoped_ptr<net::HttpTransactionFactory> main_transaction_factory_;
+  scoped_ptr<net::CookieStore> main_cookie_store_;
   scoped_ptr<net::URLRequestJobFactory> main_job_factory_;
 
   bool media_dependencies_initialized_;
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp
index 4fb27ce6..daab117a 100644
--- a/chromecast/chromecast.gyp
+++ b/chromecast/chromecast.gyp
@@ -422,6 +422,7 @@
         'renderer/media/capabilities_message_filter.h',
         'service/cast_service.cc',
         'service/cast_service.h',
+        'utility/cast_content_utility_client.h',
       ],
       'conditions': [
         ['chromecast_branding!="public"', {
@@ -435,6 +436,7 @@
             'browser/pref_service_helper_simple.cc',
             'common/platform_client_auth_simple.cc',
             'renderer/cast_content_renderer_client_simple.cc',
+            'utility/cast_content_utility_client_simple.cc',
           ],
         }],
         # ExternalMetrics not necessary on Android and (as of this writing) uses
diff --git a/chromecast/utility/BUILD.gn b/chromecast/utility/BUILD.gn
new file mode 100644
index 0000000..04152df
--- /dev/null
+++ b/chromecast/utility/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chromecast/chromecast.gni")
+
+source_set("utility") {
+  sources = [
+    "cast_content_utility_client.h",
+  ]
+
+  deps = [
+    "//base",
+    "//content/public/utility",
+  ]
+
+  if (chromecast_branding == "public") {
+    sources += [ "cast_content_utility_client_simple.cc" ]
+  }
+}
diff --git a/chromecast/utility/DEPS b/chromecast/utility/DEPS
new file mode 100644
index 0000000..2c2d79f
--- /dev/null
+++ b/chromecast/utility/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+chromecast/utility",
+  "+content/public/utility",
+]
diff --git a/chromecast/utility/cast_content_utility_client.h b/chromecast/utility/cast_content_utility_client.h
new file mode 100644
index 0000000..bd5e0fd9
--- /dev/null
+++ b/chromecast/utility/cast_content_utility_client.h
@@ -0,0 +1,28 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_UTILITY_CAST_CONTENT_UTILITY_CLIENT_H_
+#define CHROMECAST_UTILITY_CAST_CONTENT_UTILITY_CLIENT_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/utility/content_utility_client.h"
+
+namespace chromecast {
+namespace shell {
+
+class CastContentUtilityClient : public content::ContentUtilityClient {
+ public:
+  static scoped_ptr<CastContentUtilityClient> Create();
+
+  CastContentUtilityClient() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CastContentUtilityClient);
+};
+
+}  // namespace shell
+}  // namespace chromecast
+
+#endif  // CHROMECAST_UTILITY_CAST_CONTENT_UTILITY_CLIENT_H_
diff --git a/chromecast/utility/cast_content_utility_client_simple.cc b/chromecast/utility/cast_content_utility_client_simple.cc
new file mode 100644
index 0000000..01a5dfc8
--- /dev/null
+++ b/chromecast/utility/cast_content_utility_client_simple.cc
@@ -0,0 +1,16 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/utility/cast_content_utility_client.h"
+
+namespace chromecast {
+namespace shell {
+
+// static
+scoped_ptr<CastContentUtilityClient> CastContentUtilityClient::Create() {
+  return scoped_ptr<CastContentUtilityClient>();
+}
+
+}  // namespace shell
+}  // namespace chromecast
diff --git a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
index a686a57..5719ecd 100644
--- a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
+++ b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
@@ -9,13 +9,11 @@
 import android.net.Uri;
 import android.os.ConditionVariable;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.FlakyTest;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.widget.TextView;
 
-import org.chromium.base.test.util.Feature;
-
 /**
  * Base test class for all CronetSample based tests.
  */
@@ -29,8 +27,12 @@
         super(CronetSampleActivity.class);
     }
 
+    /*
     @SmallTest
     @Feature({"Cronet"})
+    https://crbug.com/592444
+    */
+    @FlakyTest
     public void testLoadUrl() throws Exception {
         CronetSampleActivity activity = launchCronetSampleWithUrl(URL);
 
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
index 9e0c8b4..ba3ffa3 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -11,6 +11,7 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.Looper;
+import android.test.FlakyTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import org.chromium.base.PathUtils;
@@ -320,9 +321,13 @@
         mTestFramework.mCronetEngine.shutdown();
     }
 
+    /*
     @SmallTest
     @Feature({"Cronet"})
     @SuppressWarnings("deprecation")
+    https://crbug.com/592444
+    */
+    @FlakyTest
     public void testRequestFinishedListenerFailedRequest() throws Exception {
         String connectionRefusedUrl = "http://127.0.0.1:3";
         mTestFramework = startCronetTestFramework();
@@ -528,8 +533,12 @@
         }
     }
 
+    /*
     @SmallTest
     @Feature({"Cronet"})
+    https://crbug.com/592444
+    */
+    @FlakyTest
     public void testShutdownAfterError() throws Exception {
         mTestFramework = startCronetTestFramework();
         TestUrlRequestCallback callback = new ShutdownTestUrlRequestCallback();
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 b2429b7..c19b3b6 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
@@ -5,6 +5,7 @@
 package org.chromium.net;
 
 import android.os.ConditionVariable;
+import android.test.FlakyTest;
 import android.test.MoreAsserts;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
@@ -1448,8 +1449,12 @@
                 callback.mOnCanceledCalled);
     }
 
+    /*
     @SmallTest
     @Feature({"Cronet"})
+    https://crbug.com/592444
+    */
+    @FlakyTest
     public void testFailures() throws Exception {
         throwOrCancel(FailureType.CANCEL_SYNC, ResponseStep.ON_RECEIVED_REDIRECT,
                 false, false);
diff --git a/components/favicon_base/fallback_icon_style.cc b/components/favicon_base/fallback_icon_style.cc
index 83305f71..66ee5997 100644
--- a/components/favicon_base/fallback_icon_style.cc
+++ b/components/favicon_base/fallback_icon_style.cc
@@ -13,14 +13,14 @@
 
 namespace {
 
-// Luminance threshold for background color determine whether to use dark or
-// light text color.
-const int kDarkTextLuminanceThreshold = 190;
+// Luma threshold for background color determine whether to use dark or light
+// text color.
+const uint8_t kDarkTextLumaThreshold = 190;
 
-// The maximum luminance of the background color to ensure light text is
+// The maximum lightness of the background color to ensure light text is
 // readable.
-const double kMaxBackgroundColorLuminance = 0.67;
-const double kMinBackgroundColorLuminance = 0.15;
+const double kMaxBackgroundColorLightness = 0.67;
+const double kMinBackgroundColorLightness = 0.15;
 
 // Default values for FallbackIconStyle.
 const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78);
@@ -51,9 +51,9 @@
 
 void MatchFallbackIconTextColorAgainstBackgroundColor(
     FallbackIconStyle* style) {
-  int luminance = color_utils::GetLuminanceForColor(style->background_color);
-  style->text_color = (luminance >= kDarkTextLuminanceThreshold ?
-      kDefaultTextColorDark : kDefaultTextColorLight);
+  const uint8_t luma = color_utils::GetLuma(style->background_color);
+  style->text_color = (luma >= kDarkTextLumaThreshold) ?
+      kDefaultTextColorDark : kDefaultTextColorLight;
 }
 
 bool ValidateFallbackIconStyle(const FallbackIconStyle& style) {
@@ -64,20 +64,20 @@
 void SetDominantColorAsBackground(
     const scoped_refptr<base::RefCountedMemory>& bitmap_data,
     FallbackIconStyle* style) {
-  // Try to ensure color's luminance isn't too large so that light text is
+  // Try to ensure color's lightness isn't too large so that light text is
   // visible. Set an upper bound for the dominant color.
-  const color_utils::HSL lower_bound{-1.0, -1.0, kMinBackgroundColorLuminance};
-  const color_utils::HSL upper_bound{-1.0, -1.0, kMaxBackgroundColorLuminance};
+  const color_utils::HSL lower_bound{-1.0, -1.0, kMinBackgroundColorLightness};
+  const color_utils::HSL upper_bound{-1.0, -1.0, kMaxBackgroundColorLightness};
   color_utils::GridSampler sampler;
   SkColor dominant_color = color_utils::CalculateKMeanColorOfPNG(
       bitmap_data, lower_bound, upper_bound, &sampler);
   // |CalculateKMeanColorOfPNG| will try to return a color that lies within the
   // specified bounds if one exists in the image. If there's no such color, it
   // will return the dominant color which may be lighter than our upper bound.
-  // Clamp luminance down to a reasonable maximum value so text is readable.
+  // Clamp lightness 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);
+  color_hsl.l = std::min(color_hsl.l, kMaxBackgroundColorLightness);
   style->background_color =
       color_utils::HSLToSkColor(color_hsl, SK_AlphaOPAQUE);
 }
diff --git a/components/mus/mus_app.cc b/components/mus/mus_app.cc
index f9ec70ad..f04ac9bc 100644
--- a/components/mus/mus_app.cc
+++ b/components/mus/mus_app.cc
@@ -15,6 +15,8 @@
 #include "components/mus/ws/connection_manager.h"
 #include "components/mus/ws/display.h"
 #include "components/mus/ws/display_binding.h"
+#include "components/mus/ws/display_manager.h"
+#include "components/mus/ws/user_display_manager.h"
 #include "components/mus/ws/window_tree.h"
 #include "components/mus/ws/window_tree_binding.h"
 #include "components/mus/ws/window_tree_factory.h"
@@ -157,7 +159,7 @@
   }
 }
 
-void MandolineUIServicesApp::OnNoMoreRootConnections() {
+void MandolineUIServicesApp::OnNoMoreDisplays() {
   base::MessageLoop::current()->QuitWhenIdle();
 }
 
@@ -180,14 +182,10 @@
 
 void MandolineUIServicesApp::Create(mojo::Connection* connection,
                                     mojom::DisplayManagerRequest request) {
-  if (!connection_manager_->has_displays()) {
-    scoped_ptr<PendingRequest> pending_request(new PendingRequest);
-    pending_request->dm_request.reset(
-        new mojo::InterfaceRequest<mojom::DisplayManager>(std::move(request)));
-    pending_requests_.push_back(std::move(pending_request));
-    return;
-  }
-  connection_manager_->AddDisplayManagerBinding(std::move(request));
+  // TODO(sky): validate id.
+  connection_manager_->display_manager()
+      ->GetUserDisplayManager(connection->GetRemoteUserID())
+      ->AddDisplayManagerBinding(std::move(request));
 }
 
 void MandolineUIServicesApp::Create(
@@ -199,7 +197,7 @@
 
 void MandolineUIServicesApp::Create(Connection* connection,
                                     mojom::WindowTreeFactoryRequest request) {
-  if (!connection_manager_->has_displays()) {
+  if (!connection_manager_->display_manager()->has_displays()) {
     scoped_ptr<PendingRequest> pending_request(new PendingRequest);
     pending_request->wtf_request.reset(
         new mojo::InterfaceRequest<mojom::WindowTreeFactory>(
diff --git a/components/mus/mus_app.h b/components/mus/mus_app.h
index f471723c..b94ea536 100644
--- a/components/mus/mus_app.h
+++ b/components/mus/mus_app.h
@@ -69,7 +69,7 @@
 
   // ConnectionManagerDelegate:
   void OnFirstDisplayReady() override;
-  void OnNoMoreRootConnections() override;
+  void OnNoMoreDisplays() override;
   scoped_ptr<ws::WindowTreeBinding> CreateWindowTreeBindingForEmbedAtWindow(
       ws::ConnectionManager* connection_manager,
       ws::WindowTree* tree,
diff --git a/components/mus/public/interfaces/input_event_constants.mojom b/components/mus/public/interfaces/input_event_constants.mojom
index 03bd80bd..3c2d6d6 100644
--- a/components/mus/public/interfaces/input_event_constants.mojom
+++ b/components/mus/public/interfaces/input_event_constants.mojom
@@ -4,6 +4,15 @@
 
 module mus.mojom;
 
+// Denotes during which phase of event targeting that an accelerator will be
+// notified of an event. PRE_TARGET will be notified instead of the target
+// window. POST_TARGET will be notified after the target window, and only if the
+// event was not consumed by the target.
+enum AcceleratorPhase {
+  PRE_TARGET,
+  POST_TARGET,
+};
+
 enum EventType {
   UNKNOWN,
   KEY_PRESSED,
diff --git a/components/mus/public/interfaces/input_event_matcher.mojom b/components/mus/public/interfaces/input_event_matcher.mojom
index 3e0929da..f2c89fa4a 100644
--- a/components/mus/public/interfaces/input_event_matcher.mojom
+++ b/components/mus/public/interfaces/input_event_matcher.mojom
@@ -42,6 +42,7 @@
 // A matcher to match any key-press event would be:
 // - |type_matcher.type| = mus::mojom::EventType::KEY_PRESSED
 struct EventMatcher {
+  AcceleratorPhase accelerator_phase;
   EventTypeMatcher? type_matcher;
   EventFlagsMatcher? flags_matcher;
   // These flags will be stripped from incoming events' flags when comparing
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn
index 4c6eadb..8543f976 100644
--- a/components/mus/ws/BUILD.gn
+++ b/components/mus/ws/BUILD.gn
@@ -21,6 +21,9 @@
     "display.h",
     "display_binding.cc",
     "display_binding.h",
+    "display_manager.cc",
+    "display_manager.h",
+    "display_manager_delegate.h",
     "event_dispatcher.cc",
     "event_dispatcher.h",
     "event_dispatcher_delegate.h",
@@ -46,6 +49,8 @@
     "server_window_surface_manager.cc",
     "server_window_surface_manager.h",
     "server_window_tracker.h",
+    "user_display_manager.cc",
+    "user_display_manager.h",
     "user_id.h",
     "user_id_tracker.cc",
     "user_id_tracker.h",
@@ -149,6 +154,7 @@
     "test_utils.cc",
     "test_utils.h",
     "transient_windows_unittest.cc",
+    "user_display_manager_unittest.cc",
     "window_coordinate_conversions_unittest.cc",
     "window_finder_unittest.cc",
     "window_tree_unittest.cc",
diff --git a/components/mus/ws/connection_manager.cc b/components/mus/ws/connection_manager.cc
index 0bd3a35..a710d9f 100644
--- a/components/mus/ws/connection_manager.cc
+++ b/components/mus/ws/connection_manager.cc
@@ -7,7 +7,9 @@
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "components/mus/ws/connection_manager_delegate.h"
+#include "components/mus/ws/display.h"
 #include "components/mus/ws/display_binding.h"
+#include "components/mus/ws/display_manager.h"
 #include "components/mus/ws/operation.h"
 #include "components/mus/ws/server_window.h"
 #include "components/mus/ws/window_coordinate_conversions.h"
@@ -30,48 +32,24 @@
     : delegate_(delegate),
       surfaces_state_(surfaces_state),
       next_connection_id_(1),
-      next_root_id_(0),
+      display_manager_(new DisplayManager(this)),
       current_operation_(nullptr),
       in_destructor_(false),
       next_wm_change_id_(0),
-      got_valid_frame_decorations_(false),
       window_manager_factory_registry_(this, &user_id_tracker_) {}
 
 ConnectionManager::~ConnectionManager() {
   in_destructor_ = true;
 
-  while (!pending_displays_.empty())
-    DestroyDisplay(*pending_displays_.begin());
-  DCHECK(pending_displays_.empty());
+  // Destroys the window trees results in querying for the display. Tear down
+  // the displays first so that the trees are notified of the display going
+  // away while the display is still valid.
+  display_manager_->DestroyAllDisplays();
 
-  // DestroyDisplay() removes from |displays_| and deletes the Display.
-  while (!displays_.empty())
-    DestroyDisplay(*displays_.begin());
-  DCHECK(displays_.empty());
+  while (!tree_map_.empty())
+    DestroyTree(tree_map_.begin()->second.get());
 
-  tree_map_.clear();
-}
-
-void ConnectionManager::AddDisplay(Display* display) {
-  DCHECK_EQ(0u, pending_displays_.count(display));
-  pending_displays_.insert(display);
-}
-
-void ConnectionManager::DestroyDisplay(Display* display) {
-  for (auto& pair : tree_map_)
-    pair.second->OnWillDestroyDisplay(display);
-
-  if (pending_displays_.count(display)) {
-    pending_displays_.erase(display);
-  } else {
-    DCHECK(displays_.count(display));
-    displays_.erase(display);
-  }
-  delete display;
-
-  // If we have no more roots left, let the app know so it can terminate.
-  if (!displays_.size() && !pending_displays_.size())
-    delegate_->OnNoMoreRootConnections();
+  display_manager_.reset();
 }
 
 ServerWindow* ConnectionManager::CreateServerWindow(
@@ -88,19 +66,11 @@
   return id;
 }
 
-uint16_t ConnectionManager::GetAndAdvanceNextRootId() {
-  // TODO(sky): handle wrapping!
-  const uint16_t id = next_root_id_++;
-  DCHECK_LT(id, next_root_id_);
-  return id;
-}
-
 WindowTree* ConnectionManager::EmbedAtWindow(
     ServerWindow* root,
     uint32_t policy_bitmask,
     mojom::WindowTreeClientPtr client) {
-  scoped_ptr<WindowTree> tree_ptr(
-      new ws::WindowTree(this, root, policy_bitmask));
+  scoped_ptr<WindowTree> tree_ptr(new WindowTree(this, root, policy_bitmask));
   WindowTree* tree = tree_ptr.get();
 
   mojom::WindowTreePtr window_tree_ptr;
@@ -127,15 +97,14 @@
     Display* display,
     mojom::WindowManagerFactory* factory,
     ServerWindow* root) {
-  mojom::DisplayPtr display_ptr = DisplayToMojomDisplay(display);
+  mojom::DisplayPtr display_ptr = display->ToMojomDisplay();
   mojom::WindowTreeClientPtr tree_client;
   factory->CreateWindowManager(std::move(display_ptr), GetProxy(&tree_client));
-  scoped_ptr<ws::WindowTree> tree_ptr(new ws::WindowTree(
-      this, root, mojom::WindowTree::kAccessPolicyEmbedRoot));
-  ws::WindowTree* tree = tree_ptr.get();
-  scoped_ptr<ws::DefaultWindowTreeBinding> binding(
-      new ws::DefaultWindowTreeBinding(tree_ptr.get(), this,
-                                       std::move(tree_client)));
+  scoped_ptr<WindowTree> tree_ptr(
+      new WindowTree(this, root, mojom::WindowTree::kAccessPolicyEmbedRoot));
+  WindowTree* tree = tree_ptr.get();
+  scoped_ptr<DefaultWindowTreeBinding> binding(new DefaultWindowTreeBinding(
+      tree_ptr.get(), this, std::move(tree_client)));
   mojom::WindowTreePtr window_tree_ptr = binding->CreateInterfacePtrAndBind();
   AddTree(std::move(tree_ptr), std::move(binding), std::move(window_tree_ptr));
   tree->ConfigureWindowManager();
@@ -158,9 +127,13 @@
   // Notify the hosts, taking care to only notify each host once.
   std::set<Display*> displays_notified;
   for (auto* root : tree->roots()) {
-    Display* display = GetDisplayContaining(root);
+    // WindowTree holds its roots as a const, which is right as WindowTree
+    // doesn't need to modify the window. OTOH we do. We could look up the
+    // window using the id to get non-const version, but instead we cast.
+    Display* display =
+        display_manager_->GetDisplayContaining(const_cast<ServerWindow*>(root));
     if (display && displays_notified.count(display) == 0) {
-      display->OnWindowTreeConnectionError(tree);
+      display->OnWillDestroyTree(tree);
       displays_notified.insert(display);
     }
   }
@@ -185,7 +158,7 @@
 ServerWindow* ConnectionManager::GetWindow(const WindowId& id) {
   // kInvalidConnectionId is used for Display and WindowManager nodes.
   if (id.connection_id == kInvalidConnectionId) {
-    for (Display* display : displays_) {
+    for (Display* display : display_manager_->displays()) {
       ServerWindow* window = display->GetRootWithId(id);
       if (window)
         return window;
@@ -195,22 +168,11 @@
   return tree ? tree->GetWindow(id) : nullptr;
 }
 
-void ConnectionManager::SchedulePaint(const ServerWindow* window,
+void ConnectionManager::SchedulePaint(ServerWindow* window,
                                       const gfx::Rect& bounds) {
-  for (Display* display : displays_) {
-    if (display->SchedulePaintIfInViewport(window, bounds))
-      return;
-  }
-}
-
-void ConnectionManager::OnDisplayAcceleratedWidgetAvailable(Display* display) {
-  DCHECK_NE(0u, pending_displays_.count(display));
-  DCHECK_EQ(0u, displays_.count(display));
-  const bool is_first_display = displays_.empty();
-  displays_.insert(display);
-  pending_displays_.erase(display);
-  if (is_first_display)
-    delegate_->OnFirstDisplayReady();
+  Display* display = display_manager_->GetDisplayContaining(window);
+  if (display)
+    display->SchedulePaint(window, bounds);
 }
 
 void ConnectionManager::OnTreeMessagedClient(ConnectionSpecificId id) {
@@ -224,12 +186,14 @@
 
 mojom::ViewportMetricsPtr ConnectionManager::GetViewportMetricsForWindow(
     const ServerWindow* window) {
-  Display* display = GetDisplayContaining(window);
+  const Display* display = display_manager_->GetDisplayContaining(window);
   if (display)
     return display->GetViewportMetrics().Clone();
 
-  if (!displays_.empty())
-    return (*displays_.begin())->GetViewportMetrics().Clone();
+  if (!display_manager_->displays().empty())
+    return (*display_manager_->displays().begin())
+        ->GetViewportMetrics()
+        .Clone();
 
   mojom::ViewportMetricsPtr metrics = mojom::ViewportMetrics::New();
   metrics->size_in_pixels = mojo::Size::New();
@@ -247,66 +211,8 @@
   return nullptr;
 }
 
-WindowManagerAndDisplayConst ConnectionManager::GetWindowManagerAndDisplay(
-    const ServerWindow* window) const {
-  const ServerWindow* last = window;
-  while (window && window->parent()) {
-    last = window;
-    window = window->parent();
-  }
-  for (Display* display : displays_) {
-    if (window == display->root_window()) {
-      WindowManagerAndDisplayConst result;
-      result.display = display;
-      result.window_manager_state =
-          display->GetWindowManagerStateWithRoot(last);
-      return result;
-    }
-  }
-  return WindowManagerAndDisplayConst();
-}
-
-WindowManagerAndDisplay ConnectionManager::GetWindowManagerAndDisplay(
-    const ServerWindow* window) {
-  WindowManagerAndDisplayConst result_const =
-      const_cast<const ConnectionManager*>(this)->GetWindowManagerAndDisplay(
-          window);
-  WindowManagerAndDisplay result;
-  result.display = const_cast<Display*>(result_const.display);
-  result.window_manager_state =
-      const_cast<WindowManagerState*>(result_const.window_manager_state);
-  return result;
-}
-
-Display* ConnectionManager::GetDisplayContaining(const ServerWindow* window) {
-  return const_cast<Display*>(
-      static_cast<const ConnectionManager*>(this)->GetDisplayContaining(
-          window));
-}
-
-const Display* ConnectionManager::GetDisplayContaining(
-    const ServerWindow* window) const {
-  while (window && window->parent())
-    window = window->parent();
-  for (Display* display : displays_) {
-    if (window == display->root_window())
-      return display;
-  }
-  return nullptr;
-}
-
-Display* ConnectionManager::GetActiveDisplay() {
-  // TODO(sky): this isn't active, but first. Make it active.
-  return displays_.size() ? *displays_.begin() : nullptr;
-}
-
-void ConnectionManager::AddDisplayManagerBinding(
-    mojo::InterfaceRequest<mojom::DisplayManager> request) {
-  display_manager_bindings_.AddBinding(this, std::move(request));
-}
-
 void ConnectionManager::OnFirstWindowManagerFactorySet() {
-  if (!displays_.empty() || !pending_displays_.empty())
+  if (display_manager_->has_active_or_pending_displays())
     return;
 
   // We've been supplied a WindowManagerFactory and no displays have been
@@ -364,40 +270,6 @@
                                              change.client_change_id, window);
 }
 
-mojom::DisplayPtr ConnectionManager::DisplayToMojomDisplay(Display* display) {
-  size_t i = 0;
-  int next_x = 0;
-  for (Display* display2 : displays_) {
-    const ServerWindow* root = display->root_window();
-    if (display == display2) {
-      mojom::DisplayPtr display_ptr = mojom::Display::New();
-      display_ptr = mojom::Display::New();
-      display_ptr->id = display->id();
-      display_ptr->bounds = mojo::Rect::New();
-      display_ptr->bounds->x = next_x;
-      display_ptr->bounds->y = 0;
-      display_ptr->bounds->width = root->bounds().size().width();
-      display_ptr->bounds->height = root->bounds().size().height();
-      // TODO(sky): window manager needs an API to set the work area.
-      display_ptr->work_area = display_ptr->bounds.Clone();
-      display_ptr->device_pixel_ratio =
-          display->GetViewportMetrics().device_pixel_ratio;
-      display_ptr->rotation = display->GetRotation();
-      // TODO(sky): make this real.
-      display_ptr->is_primary = i == 0;
-      // TODO(sky): make this real.
-      display_ptr->touch_support = mojom::TouchSupport::UNKNOWN;
-      display_ptr->frame_decoration_values =
-          display->frame_decoration_values().Clone();
-      return display_ptr;
-    }
-    next_x += root->bounds().size().width();
-    ++i;
-  }
-  NOTREACHED();
-  return mojom::Display::New();
-}
-
 void ConnectionManager::ProcessWindowBoundsChanged(
     const ServerWindow* window,
     const gfx::Rect& old_bounds,
@@ -462,9 +334,8 @@
 }
 
 void ConnectionManager::ProcessWindowDeleted(const ServerWindow* window) {
-  for (auto& pair : tree_map_) {
+  for (auto& pair : tree_map_)
     pair.second->ProcessWindowDeleted(window, IsOperationSource(pair.first));
-  }
 }
 
 void ConnectionManager::ProcessWillChangeWindowPredefinedCursor(
@@ -476,7 +347,7 @@
   }
 
   // Pass the cursor change to the native window.
-  Display* display = GetDisplayContaining(window);
+  Display* display = display_manager_->GetDisplayContaining(window);
   if (display)
     display->OnCursorUpdated(window);
 }
@@ -489,23 +360,6 @@
     pair.second->ProcessViewportMetricsChanged(
         display, old_metrics, new_metrics, IsOperationSource(pair.first));
   }
-
-  if (!got_valid_frame_decorations_)
-    return;
-}
-
-void ConnectionManager::ProcessFrameDecorationValuesChanged(Display* display) {
-  if (!got_valid_frame_decorations_) {
-    got_valid_frame_decorations_ = true;
-    display_manager_observers_.ForAllPtrs([this](
-        mojom::DisplayManagerObserver* observer) { CallOnDisplays(observer); });
-    return;
-  }
-
-  display_manager_observers_.ForAllPtrs(
-      [this, &display](mojom::DisplayManagerObserver* observer) {
-        CallOnDisplayChanged(observer, display);
-      });
 }
 
 bool ConnectionManager::GetAndClearInFlightWindowManagerChange(
@@ -537,58 +391,30 @@
 
 void ConnectionManager::MaybeUpdateNativeCursor(ServerWindow* window) {
   // This can be null in unit tests.
-  Display* display = GetDisplayContaining(window);
+  Display* display = display_manager_->GetDisplayContaining(window);
   if (display)
     display->MaybeChangeCursorOnWindowTreeChange();
 }
 
-void ConnectionManager::CallOnDisplays(
-    mojom::DisplayManagerObserver* observer) {
-  mojo::Array<mojom::DisplayPtr> displays(displays_.size());
-  {
-    size_t i = 0;
-    // TODO(sky): need ordering!
-    for (Display* display : displays_) {
-      displays[i] = DisplayToMojomDisplay(display);
-      ++i;
-    }
-  }
-  observer->OnDisplays(std::move(displays));
-}
-
-void ConnectionManager::CallOnDisplayChanged(
-    mojom::DisplayManagerObserver* observer,
-    Display* display) {
-  mojo::Array<mojom::DisplayPtr> displays(1);
-  displays[0] = DisplayToMojomDisplay(display);
-  display_manager_observers_.ForAllPtrs(
-      [&displays](mojom::DisplayManagerObserver* observer) {
-        observer->OnDisplaysChanged(displays.Clone());
-      });
-}
-
 mus::SurfacesState* ConnectionManager::GetSurfacesState() {
   return surfaces_state_.get();
 }
 
-void ConnectionManager::OnScheduleWindowPaint(const ServerWindow* window) {
+void ConnectionManager::OnScheduleWindowPaint(ServerWindow* window) {
   if (!in_destructor_)
     SchedulePaint(window, gfx::Rect(window->bounds().size()));
 }
 
 const ServerWindow* ConnectionManager::GetRootWindow(
     const ServerWindow* window) const {
-  const Display* display = GetDisplayContaining(window);
+  const Display* display = display_manager_->GetDisplayContaining(window);
   return display ? display->root_window() : nullptr;
 }
 
 void ConnectionManager::ScheduleSurfaceDestruction(ServerWindow* window) {
-  for (Display* display : displays_) {
-    if (display->root_window()->Contains(window)) {
-      display->ScheduleSurfaceDestruction(window);
-      break;
-    }
-  }
+  Display* display = display_manager_->GetDisplayContaining(window);
+  if (display)
+    display->ScheduleSurfaceDestruction(window);
 }
 
 ServerWindow* ConnectionManager::FindWindowForSurface(
@@ -598,7 +424,7 @@
   WindowTree* window_tree;
   if (ancestor->id().connection_id == kInvalidConnectionId) {
     WindowManagerAndDisplay wm_and_display =
-        GetWindowManagerAndDisplay(ancestor);
+        display_manager_->GetWindowManagerAndDisplay(ancestor);
     window_tree = wm_and_display.window_manager_state
                       ? wm_and_display.window_manager_state->tree()
                       : nullptr;
@@ -617,8 +443,7 @@
 }
 
 void ConnectionManager::OnWindowDestroyed(ServerWindow* window) {
-  if (!in_destructor_)
-    ProcessWindowDeleted(window);
+  ProcessWindowDeleted(window);
 }
 
 void ConnectionManager::OnWillChangeWindowHierarchy(ServerWindow* window,
@@ -723,7 +548,7 @@
 void ConnectionManager::OnWindowTextInputStateChanged(
     ServerWindow* window,
     const ui::TextInputState& state) {
-  Display* display = GetDisplayContaining(window);
+  Display* display = display_manager_->GetDisplayContaining(window);
   display->UpdateTextInputState(window, state);
 }
 
@@ -747,18 +572,17 @@
   }
 }
 
-void ConnectionManager::AddObserver(mojom::DisplayManagerObserverPtr observer) {
-  // TODO(sky): this needs to be per user.
+void ConnectionManager::OnWillDestroyDisplay(Display* display) {
+  for (auto& pair : tree_map_)
+    pair.second->OnWillDestroyDisplay(display);
+}
 
-  // Many clients key off the frame decorations to size widgets. Wait for frame
-  // decorations before notifying so that we don't have to worry about clients
-  // resizing appropriately.
-  if (!got_valid_frame_decorations_) {
-    display_manager_observers_.AddInterfacePtr(std::move(observer));
-    return;
-  }
-  CallOnDisplays(observer.get());
-  display_manager_observers_.AddInterfacePtr(std::move(observer));
+void ConnectionManager::OnFirstDisplayReady() {
+  delegate_->OnFirstDisplayReady();
+}
+
+void ConnectionManager::OnNoMoreDisplays() {
+  delegate_->OnNoMoreDisplays();
 }
 
 }  // namespace ws
diff --git a/components/mus/ws/connection_manager.h b/components/mus/ws/connection_manager.h
index b341bcd..b6d81f7 100644
--- a/components/mus/ws/connection_manager.h
+++ b/components/mus/ws/connection_manager.h
@@ -8,18 +8,16 @@
 #include <stdint.h>
 
 #include <map>
-#include <set>
 #include <vector>
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/timer/timer.h"
-#include "components/mus/public/interfaces/display.mojom.h"
 #include "components/mus/public/interfaces/window_manager_factory.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "components/mus/public/interfaces/window_tree_host.mojom.h"
 #include "components/mus/surfaces/surfaces_state.h"
 #include "components/mus/ws/display.h"
+#include "components/mus/ws/display_manager_delegate.h"
 #include "components/mus/ws/ids.h"
 #include "components/mus/ws/operation.h"
 #include "components/mus/ws/server_window_delegate.h"
@@ -29,32 +27,17 @@
 #include "mojo/converters/surfaces/custom_surface_converter.h"
 #include "mojo/public/cpp/bindings/array.h"
 #include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
 
 namespace mus {
 namespace ws {
 
 class ConnectionManagerDelegate;
+class DisplayManager;
 class ServerWindow;
 class WindowManagerState;
 class WindowTree;
 class WindowTreeBinding;
 
-struct WindowManagerAndDisplay {
-  WindowManagerAndDisplay() : window_manager_state(nullptr), display(nullptr) {}
-
-  WindowManagerState* window_manager_state;
-  Display* display;
-};
-
-struct WindowManagerAndDisplayConst {
-  WindowManagerAndDisplayConst()
-      : window_manager_state(nullptr), display(nullptr) {}
-  const WindowManagerState* window_manager_state;
-  const Display* display;
-};
-
 // ConnectionManager manages the set of connections to the window server (all
 // the WindowTrees) as well as providing the root of the hierarchy.
 //
@@ -62,7 +45,7 @@
 // clearer.
 class ConnectionManager : public ServerWindowDelegate,
                           public ServerWindowObserver,
-                          public mojom::DisplayManager {
+                          public DisplayManagerDelegate {
  public:
   ConnectionManager(ConnectionManagerDelegate* delegate,
                     const scoped_refptr<mus::SurfacesState>& surfaces_state);
@@ -72,10 +55,10 @@
 
   UserIdTracker* user_id_tracker() { return &user_id_tracker_; }
 
-  // Adds/removes a Display. ConnectionManager owns the Displays.
-  void AddDisplay(Display* display);
-  void DestroyDisplay(Display* display);
-  std::set<Display*> displays() { return displays_; }
+  DisplayManager* display_manager() { return display_manager_.get(); }
+  const DisplayManager* display_manager() const {
+    return display_manager_.get();
+  }
 
   // Creates a new ServerWindow. The return value is owned by the caller, but
   // must be destroyed before ConnectionManager.
@@ -86,10 +69,6 @@
   // Returns the id for the next WindowTree.
   ConnectionSpecificId GetAndAdvanceNextConnectionId();
 
-  // Returns the id for the next root window (both for the root of a Display
-  // as well as the root of WindowManagers).
-  uint16_t GetAndAdvanceNextRootId();
-
   // See description of WindowTree::Embed() for details. This assumes
   // |transport_window_id| is valid.
   WindowTree* EmbedAtWindow(ServerWindow* root,
@@ -116,19 +95,13 @@
   ServerWindow* GetWindow(const WindowId& id);
 
   // Schedules a paint for the specified region in the coordinates of |window|.
-  void SchedulePaint(const ServerWindow* window, const gfx::Rect& bounds);
+  void SchedulePaint(ServerWindow* window, const gfx::Rect& bounds);
 
   OperationType current_operation_type() const {
     return current_operation_ ? current_operation_->type()
                               : OperationType::NONE;
   }
 
-  // Invoked when the Display's PlatformDisplay is closed.
-  void OnDisplayClosed();
-
-  // Called when the AcceleratedWidget is available for |display|.
-  void OnDisplayAcceleratedWidgetAvailable(Display* display);
-
   // Invoked when a connection messages a client about the change. This is used
   // to avoid sending ServerChangeIdAdvanced() unnecessarily.
   void OnTreeMessagedClient(ConnectionSpecificId id);
@@ -148,23 +121,6 @@
   }
   const WindowTree* GetTreeWithRoot(const ServerWindow* window) const;
 
-  // Returns the Display that contains |window|, or null if |window| is not
-  // attached to a display.
-  Display* GetDisplayContaining(const ServerWindow* window);
-  const Display* GetDisplayContaining(const ServerWindow* window) const;
-
-  WindowManagerAndDisplayConst GetWindowManagerAndDisplay(
-      const ServerWindow* window) const;
-  WindowManagerAndDisplay GetWindowManagerAndDisplay(
-      const ServerWindow* window);
-
-  Display* GetActiveDisplay();
-
-  bool has_displays() const { return !displays_.empty(); }
-
-  void AddDisplayManagerBinding(
-      mojo::InterfaceRequest<mojom::DisplayManager> request);
-
   void OnFirstWindowManagerFactorySet();
 
   WindowManagerFactoryRegistry* window_manager_factory_registry() {
@@ -191,9 +147,6 @@
   // TODO(sky): decide what we want to do here.
   void WindowManagerSentBogusMessage() {}
 
-  // Returns the Display for |display|.
-  mojom::DisplayPtr DisplayToMojomDisplay(Display* display);
-
   // These functions trivially delegate to all WindowTrees, which in
   // term notify their clients.
   void ProcessWindowBoundsChanged(const ServerWindow* window,
@@ -219,7 +172,6 @@
   void ProcessWindowDeleted(const ServerWindow* window);
   void ProcessWillChangeWindowPredefinedCursor(ServerWindow* window,
                                                int32_t cursor_id);
-  void ProcessFrameDecorationValuesChanged(Display* display);
 
  private:
   friend class Operation;
@@ -261,16 +213,9 @@
   // Run in response to events which may cause us to change the native cursor.
   void MaybeUpdateNativeCursor(ServerWindow* window);
 
-  // Calls OnDisplays() on |observer|.
-  void CallOnDisplays(mojom::DisplayManagerObserver* observer);
-
-  // Calls observer->OnDisplaysChanged() with the display for |display|.
-  void CallOnDisplayChanged(mojom::DisplayManagerObserver* observer,
-                            Display* display);
-
   // Overridden from ServerWindowDelegate:
   mus::SurfacesState* GetSurfacesState() override;
-  void OnScheduleWindowPaint(const ServerWindow* window) override;
+  void OnScheduleWindowPaint(ServerWindow* window) override;
   const ServerWindow* GetRootWindow(const ServerWindow* window) const override;
   void ScheduleSurfaceDestruction(ServerWindow* window) override;
   ServerWindow* FindWindowForSurface(
@@ -310,8 +255,10 @@
   void OnTransientWindowRemoved(ServerWindow* window,
                                 ServerWindow* transient_child) override;
 
-  // Overriden from mojom::DisplayManager:
-  void AddObserver(mojom::DisplayManagerObserverPtr observer) override;
+  // DisplayManagerDelegate:
+  void OnWillDestroyDisplay(Display* display) override;
+  void OnFirstDisplayReady() override;
+  void OnNoMoreDisplays() override;
 
   UserIdTracker user_id_tracker_;
 
@@ -323,18 +270,11 @@
   // ID to use for next WindowTree.
   ConnectionSpecificId next_connection_id_;
 
-  // ID to use for next root node.
-  uint16_t next_root_id_;
+  scoped_ptr<DisplayManager> display_manager_;
 
   // Set of WindowTrees.
   WindowTreeMap tree_map_;
 
-  // Displays are initially added to |pending_displays_|. When the display is
-  // initialized it is moved to |displays_|. ConnectionManager owns the
-  // Displays.
-  std::set<Display*> pending_displays_;
-  std::set<Display*> displays_;
-
   // If non-null then we're processing a client operation. The Operation is
   // not owned by us (it's created on the stack by WindowTree).
   Operation* current_operation_;
@@ -348,14 +288,6 @@
   // Next id supplied to the window manager.
   uint32_t next_wm_change_id_;
 
-  mojo::BindingSet<mojom::DisplayManager> display_manager_bindings_;
-  // WARNING: only use these once |got_valid_frame_decorations_| is true.
-  // TODO(sky): refactor this out into its own class.
-  mojo::InterfacePtrSet<mojom::DisplayManagerObserver>
-      display_manager_observers_;
-
-  bool got_valid_frame_decorations_;
-
   WindowManagerFactoryRegistry window_manager_factory_registry_;
 
   DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
diff --git a/components/mus/ws/connection_manager_delegate.h b/components/mus/ws/connection_manager_delegate.h
index ce4fad4..a777ecb 100644
--- a/components/mus/ws/connection_manager_delegate.h
+++ b/components/mus/ws/connection_manager_delegate.h
@@ -35,7 +35,7 @@
   // Called once when the AcceleratedWidget of a Display is available.
   virtual void OnFirstDisplayReady();
 
-  virtual void OnNoMoreRootConnections() = 0;
+  virtual void OnNoMoreDisplays() = 0;
 
   // Creates a WindowTreeBinding in response to Embed() calls on the
   // ConnectionManager.
diff --git a/components/mus/ws/display.cc b/components/mus/ws/display.cc
index 3ee54d13..ef878ea 100644
--- a/components/mus/ws/display.cc
+++ b/components/mus/ws/display.cc
@@ -10,6 +10,7 @@
 #include "components/mus/ws/connection_manager.h"
 #include "components/mus/ws/connection_manager_delegate.h"
 #include "components/mus/ws/display_binding.h"
+#include "components/mus/ws/display_manager.h"
 #include "components/mus/ws/focus_controller.h"
 #include "components/mus/ws/platform_display.h"
 #include "components/mus/ws/window_manager_factory_service.h"
@@ -53,8 +54,6 @@
   return second;
 }
 
-uint32_t next_id = 1;
-
 }  // namespace
 
 class Display::ProcessedEventTarget {
@@ -91,18 +90,13 @@
                  mojo::Connector* connector,
                  const scoped_refptr<GpuState>& gpu_state,
                  const scoped_refptr<SurfacesState>& surfaces_state)
-    : id_(next_id++),
+    : id_(connection_manager->display_manager()->GetAndAdvanceNextDisplayId()),
       connection_manager_(connection_manager),
       event_dispatcher_(this),
       platform_display_(
           PlatformDisplay::Create(connector, gpu_state, surfaces_state)),
       tree_awaiting_input_ack_(nullptr),
       last_cursor_(0) {
-  frame_decoration_values_ = mojom::FrameDecorationValues::New();
-  frame_decoration_values_->normal_client_area_insets = mojo::Insets::New();
-  frame_decoration_values_->maximized_client_area_insets = mojo::Insets::New();
-  frame_decoration_values_->max_title_bar_button_width = 0u;
-
   platform_display_->Init(this);
 
   connection_manager_->window_manager_factory_registry()->AddObserver(this);
@@ -128,23 +122,49 @@
 void Display::Init(scoped_ptr<DisplayBinding> binding) {
   init_called_ = true;
   binding_ = std::move(binding);
-  connection_manager_->AddDisplay(this);
+  display_manager()->AddDisplay(this);
   InitWindowManagersIfNecessary();
 }
 
-void Display::SetFrameDecorationValues(mojom::FrameDecorationValuesPtr values) {
-  // TODO(sky): this needs to be moved to WindowManagerState.
-  frame_decoration_values_ = values.Clone();
-  connection_manager_->ProcessFrameDecorationValuesChanged(this);
+DisplayManager* Display::display_manager() {
+  return connection_manager_->display_manager();
 }
 
-bool Display::SchedulePaintIfInViewport(const ServerWindow* window,
-                                        const gfx::Rect& bounds) {
-  if (root_->Contains(window)) {
-    platform_display_->SchedulePaint(window, bounds);
-    return true;
-  }
-  return false;
+const DisplayManager* Display::display_manager() const {
+  return connection_manager_->display_manager();
+}
+
+mojom::DisplayPtr Display::ToMojomDisplay() const {
+  mojom::DisplayPtr display_ptr = mojom::Display::New();
+  display_ptr = mojom::Display::New();
+  display_ptr->id = id_;
+  display_ptr->bounds = mojo::Rect::New();
+  // TODO(sky): Display should know it's origin.
+  display_ptr->bounds->x = 0;
+  display_ptr->bounds->y = 0;
+  display_ptr->bounds->width = root_->bounds().size().width();
+  display_ptr->bounds->height = root_->bounds().size().height();
+  // TODO(sky): window manager needs an API to set the work area.
+  display_ptr->work_area = display_ptr->bounds.Clone();
+  display_ptr->device_pixel_ratio =
+      platform_display_->GetViewportMetrics().device_pixel_ratio;
+  display_ptr->rotation = platform_display_->GetRotation();
+  // TODO(sky): make this real.
+  display_ptr->is_primary = true;
+  // TODO(sky): make this real.
+  display_ptr->touch_support = mojom::TouchSupport::UNKNOWN;
+  display_ptr->frame_decoration_values = mojom::FrameDecorationValues::New();
+  display_ptr->frame_decoration_values->normal_client_area_insets =
+      mojo::Insets::New();
+  display_ptr->frame_decoration_values->maximized_client_area_insets =
+      mojo::Insets::New();
+  return display_ptr;
+}
+
+void Display::SchedulePaint(const ServerWindow* window,
+                            const gfx::Rect& bounds) {
+  DCHECK(root_->Contains(window));
+  platform_display_->SchedulePaint(window, bounds);
 }
 
 void Display::ScheduleSurfaceDestruction(ServerWindow* window) {
@@ -187,8 +207,8 @@
              : window_manager_state_map_.begin()->second.get();
 }
 
-WindowManagerState* Display::GetWindowManagerStateForUser(
-    const UserId& user_id) {
+const WindowManagerState* Display::GetWindowManagerStateForUser(
+    const UserId& user_id) const {
   auto iter = window_manager_state_map_.find(user_id);
   return iter == window_manager_state_map_.end() ? nullptr : iter->second.get();
 }
@@ -247,7 +267,7 @@
   platform_display_->SetImeVisibility(visible);
 }
 
-void Display::OnWindowTreeConnectionError(WindowTree* tree) {
+void Display::OnWillDestroyTree(WindowTree* tree) {
   for (auto it = window_manager_state_map_.begin();
        it != window_manager_state_map_.end(); ++it) {
     if (it->second->tree() == tree) {
@@ -298,7 +318,7 @@
   if (!init_called_ || !root_)
     return;
 
-  connection_manager_->OnDisplayAcceleratedWidgetAvailable(this);
+  display_manager()->OnDisplayAcceleratedWidgetAvailable(this);
   if (binding_) {
     scoped_ptr<WindowManagerState> wms_ptr(new WindowManagerState(this));
     WindowManagerState* wms = wms_ptr.get();
@@ -435,7 +455,7 @@
 }
 
 void Display::OnDisplayClosed() {
-  connection_manager_->DestroyDisplay(this);
+  display_manager()->DestroyDisplay(this);
 }
 
 void Display::OnViewportMetricsChanged(
@@ -443,7 +463,7 @@
     const mojom::ViewportMetrics& new_metrics) {
   if (!root_) {
     root_.reset(connection_manager_->CreateServerWindow(
-        RootWindowId(connection_manager_->GetAndAdvanceNextRootId()),
+        display_manager()->GetAndAdvanceNextRootId(),
         ServerWindow::Properties()));
     root_->SetBounds(gfx::Rect(new_metrics.size_in_pixels.To<gfx::Size>()));
     root_->SetVisible(true);
@@ -457,6 +477,8 @@
     for (auto& pair : window_manager_state_map_)
       pair.second->root()->SetBounds(wm_bounds);
   }
+  // TODO(sky): if bounds changed, then need to update
+  // Display/WindowManagerState appropriately (e.g. notify observers).
   connection_manager_->ProcessViewportMetricsChanged(this, old_metrics,
                                                      new_metrics);
 }
@@ -542,7 +564,8 @@
   WindowTree* wms_tree_with_old_focused_window = nullptr;
   if (old_focused_window) {
     WindowManagerState* wms =
-        connection_manager_->GetWindowManagerAndDisplay(old_focused_window)
+        display_manager()
+            ->GetWindowManagerAndDisplay(old_focused_window)
             .window_manager_state;
     wms_tree_with_old_focused_window = wms ? wms->tree() : nullptr;
     if (wms_tree_with_old_focused_window &&
@@ -556,7 +579,8 @@
   }
   if (new_focused_window) {
     WindowManagerState* wms =
-        connection_manager_->GetWindowManagerAndDisplay(new_focused_window)
+        display_manager()
+            ->GetWindowManagerAndDisplay(new_focused_window)
             .window_manager_state;
     WindowTree* wms_tree = wms ? wms->tree() : nullptr;
     if (wms_tree && wms_tree != wms_tree_with_old_focused_window &&
@@ -631,14 +655,15 @@
   if (!state)
     return;
 
-  // DestroyTree() calls back to OnWindowTreeConnectionError() and the
-  // WindowManagerState is destroyed (and removed).
+  // DestroyTree() calls back to OnWillDestroyTree() and the WindowManagerState
+  // is destroyed (and removed).
   connection_manager_->DestroyTree(state->tree());
   DCHECK_EQ(0u, window_manager_state_map_.count(id));
 }
 
 void Display::OnWindowManagerFactorySet(WindowManagerFactoryService* service) {
-  CreateWindowManagerStateFromService(service);
+  if (!binding_)
+    CreateWindowManagerStateFromService(service);
 }
 
 }  // namespace ws
diff --git a/components/mus/ws/display.h b/components/mus/ws/display.h
index 6cf8975..69cfb9e 100644
--- a/components/mus/ws/display.h
+++ b/components/mus/ws/display.h
@@ -32,6 +32,7 @@
 
 class ConnectionManager;
 class DisplayBinding;
+class DisplayManager;
 class FocusController;
 class WindowManagerState;
 class WindowTree;
@@ -73,17 +74,16 @@
 
   uint32_t id() const { return id_; }
 
-  // TODO(sky): move to WMM.
-  void SetFrameDecorationValues(mojom::FrameDecorationValuesPtr values);
-  const mojom::FrameDecorationValues& frame_decoration_values() const {
-    return *frame_decoration_values_;
-  }
+  DisplayManager* display_manager();
+  const DisplayManager* display_manager() const;
 
-  // Schedules a paint for the specified region in the coordinates of |window|
-  // if the |window| is in this viewport. Returns whether |window| is in the
-  // viewport.
-  bool SchedulePaintIfInViewport(const ServerWindow* window,
-                                 const gfx::Rect& bounds);
+  // Returns a mojom::Display for the specified display. WindowManager specific
+  // values are not set. In general you should use
+  // WindowManagerState::ToMojomDisplay().
+  mojom::DisplayPtr ToMojomDisplay() const;
+
+  // Schedules a paint for the specified region in the coordinates of |window|.
+  void SchedulePaint(const ServerWindow* window, const gfx::Rect& bounds);
 
   // Schedules destruction of surfaces in |window|. If a frame has been
   // scheduled but not drawn surface destruction is delayed until the frame is
@@ -109,7 +109,13 @@
   WindowManagerState* GetWindowManagerStateWithRoot(const ServerWindow* window);
   // TODO(sky): this is wrong, plumb through user_id.
   WindowManagerState* GetFirstWindowManagerState();
-  WindowManagerState* GetWindowManagerStateForUser(const UserId& user_id);
+  WindowManagerState* GetWindowManagerStateForUser(const UserId& user_id) {
+    return const_cast<WindowManagerState*>(
+        const_cast<const Display*>(this)->GetWindowManagerStateForUser(
+            user_id));
+  }
+  const WindowManagerState* GetWindowManagerStateForUser(
+      const UserId& user_id) const;
   size_t num_window_manger_states() const {
     return window_manager_state_map_.size();
   }
@@ -136,9 +142,8 @@
     return event_dispatcher_.capture_window();
   }
 
-  // Called just before |tree| is destroyed after its connection encounters an
-  // error.
-  void OnWindowTreeConnectionError(WindowTree* tree);
+  // Called just before |tree| is destroyed.
+  void OnWillDestroyTree(WindowTree* tree);
 
   // Called when a client updates a cursor. This will update the cursor on the
   // native display if the cursor is currently under |window|.
@@ -274,8 +279,6 @@
 
   WindowManagerStateMap window_manager_state_map_;
 
-  mojom::FrameDecorationValuesPtr frame_decoration_values_;
-
   DISALLOW_COPY_AND_ASSIGN(Display);
 };
 
diff --git a/components/mus/ws/display_manager.cc b/components/mus/ws/display_manager.cc
new file mode 100644
index 0000000..7b321e6
--- /dev/null
+++ b/components/mus/ws/display_manager.cc
@@ -0,0 +1,153 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mus/ws/display_manager.h"
+
+#include "components/mus/ws/display.h"
+#include "components/mus/ws/display_manager_delegate.h"
+#include "components/mus/ws/server_window.h"
+#include "components/mus/ws/user_display_manager.h"
+
+namespace mus {
+namespace ws {
+
+DisplayManager::DisplayManager(DisplayManagerDelegate* delegate)
+    // |next_root_id_| is used as the lower bits, so that starting at 0 is
+    // fine. |next_display_id_| is used by itself, so we start at 1 to reserve
+    // 0 as invalid.
+    : delegate_(delegate),
+      next_root_id_(0),
+      next_display_id_(1) {}
+
+DisplayManager::~DisplayManager() {
+  DestroyAllDisplays();
+}
+
+UserDisplayManager* DisplayManager::GetUserDisplayManager(
+    const UserId& user_id) {
+  if (!user_display_managers_.count(user_id)) {
+    user_display_managers_[user_id] =
+        make_scoped_ptr(new UserDisplayManager(this, user_id));
+  }
+  return user_display_managers_[user_id].get();
+}
+
+void DisplayManager::AddDisplay(Display* display) {
+  DCHECK_EQ(0u, pending_displays_.count(display));
+  pending_displays_.insert(display);
+}
+
+void DisplayManager::DestroyDisplay(Display* display) {
+  delegate_->OnWillDestroyDisplay(display);
+
+  if (pending_displays_.count(display)) {
+    pending_displays_.erase(display);
+  } else {
+    for (const auto& pair : user_display_managers_)
+      pair.second->OnWillDestroyDisplay(display);
+
+    DCHECK(displays_.count(display));
+    displays_.erase(display);
+  }
+  delete display;
+
+  // If we have no more roots left, let the app know so it can terminate.
+  // TODO(sky): move to delegate/observer.
+  if (!displays_.size() && !pending_displays_.size())
+    delegate_->OnNoMoreDisplays();
+}
+
+void DisplayManager::DestroyAllDisplays() {
+  while (!pending_displays_.empty())
+    DestroyDisplay(*pending_displays_.begin());
+  DCHECK(pending_displays_.empty());
+
+  while (!displays_.empty())
+    DestroyDisplay(*displays_.begin());
+  DCHECK(displays_.empty());
+}
+
+std::set<const Display*> DisplayManager::displays() const {
+  std::set<const Display*> ret_value(displays_.begin(), displays_.end());
+  return ret_value;
+}
+
+Display* DisplayManager::GetDisplayContaining(ServerWindow* window) {
+  return const_cast<Display*>(
+      static_cast<const DisplayManager*>(this)->GetDisplayContaining(window));
+}
+
+const Display* DisplayManager::GetDisplayContaining(
+    const ServerWindow* window) const {
+  while (window && window->parent())
+    window = window->parent();
+  for (Display* display : displays_) {
+    if (window == display->root_window())
+      return display;
+  }
+  return nullptr;
+}
+
+Display* DisplayManager::GetActiveDisplay() {
+  // TODO(sky): this isn't active, but first. Make it active.
+  return displays_.size() ? *displays_.begin() : nullptr;
+}
+
+WindowManagerAndDisplayConst DisplayManager::GetWindowManagerAndDisplay(
+    const ServerWindow* window) const {
+  const ServerWindow* last = window;
+  while (window && window->parent()) {
+    last = window;
+    window = window->parent();
+  }
+  for (Display* display : displays_) {
+    if (window == display->root_window()) {
+      WindowManagerAndDisplayConst result;
+      result.display = display;
+      result.window_manager_state =
+          display->GetWindowManagerStateWithRoot(last);
+      return result;
+    }
+  }
+  return WindowManagerAndDisplayConst();
+}
+
+WindowManagerAndDisplay DisplayManager::GetWindowManagerAndDisplay(
+    const ServerWindow* window) {
+  WindowManagerAndDisplayConst result_const =
+      const_cast<const DisplayManager*>(this)->GetWindowManagerAndDisplay(
+          window);
+  WindowManagerAndDisplay result;
+  result.display = const_cast<Display*>(result_const.display);
+  result.window_manager_state =
+      const_cast<WindowManagerState*>(result_const.window_manager_state);
+  return result;
+}
+
+WindowId DisplayManager::GetAndAdvanceNextRootId() {
+  // TODO(sky): handle wrapping!
+  const uint16_t id = next_root_id_++;
+  DCHECK_LT(id, next_root_id_);
+  return RootWindowId(id);
+}
+
+uint32_t DisplayManager::GetAndAdvanceNextDisplayId() {
+  // TODO(sky): handle wrapping!
+  const uint32_t id = next_display_id_++;
+  DCHECK_LT(id, next_display_id_);
+  return id;
+}
+
+void DisplayManager::OnDisplayAcceleratedWidgetAvailable(Display* display) {
+  DCHECK_NE(0u, pending_displays_.count(display));
+  DCHECK_EQ(0u, displays_.count(display));
+  const bool is_first_display = displays_.empty();
+  displays_.insert(display);
+  pending_displays_.erase(display);
+  if (is_first_display)
+    delegate_->OnFirstDisplayReady();
+}
+
+}  // namespace ws
+}  // namespace mus
diff --git a/components/mus/ws/display_manager.h b/components/mus/ws/display_manager.h
new file mode 100644
index 0000000..686b15a0
--- /dev/null
+++ b/components/mus/ws/display_manager.h
@@ -0,0 +1,104 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MUS_WS_DISPLAY_MANAGER_H_
+#define COMPONENTS_MUS_WS_DISPLAY_MANAGER_H_
+
+#include <map>
+#include <set>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/mus/ws/ids.h"
+#include "components/mus/ws/user_id.h"
+
+namespace mus {
+namespace ws {
+
+class Display;
+class DisplayManagerDelegate;
+class ServerWindow;
+class UserDisplayManager;
+class WindowManagerState;
+
+struct WindowManagerAndDisplay {
+  WindowManagerAndDisplay() : window_manager_state(nullptr), display(nullptr) {}
+
+  WindowManagerState* window_manager_state;
+  Display* display;
+};
+
+struct WindowManagerAndDisplayConst {
+  WindowManagerAndDisplayConst()
+      : window_manager_state(nullptr), display(nullptr) {}
+  const WindowManagerState* window_manager_state;
+  const Display* display;
+};
+
+class DisplayManager {
+ public:
+  explicit DisplayManager(DisplayManagerDelegate* delegate);
+  ~DisplayManager();
+
+  // Returns the UserDisplayManager for |user_id|. DisplayManager owns the
+  // return value.
+  UserDisplayManager* GetUserDisplayManager(const UserId& user_id);
+
+  // Adds/removes a Display. DisplayManager owns the Displays.
+  // TODO(sky): make add take a scoped_ptr.
+  void AddDisplay(Display* display);
+  void DestroyDisplay(Display* display);
+  void DestroyAllDisplays();
+  const std::set<Display*>& displays() { return displays_; }
+  std::set<const Display*> displays() const;
+
+  // Returns the Display that contains |window|, or null if |window| is not
+  // attached to a display.
+  Display* GetDisplayContaining(ServerWindow* window);
+  const Display* GetDisplayContaining(const ServerWindow* window) const;
+
+  Display* GetActiveDisplay();
+
+  WindowManagerAndDisplayConst GetWindowManagerAndDisplay(
+      const ServerWindow* window) const;
+  WindowManagerAndDisplay GetWindowManagerAndDisplay(
+      const ServerWindow* window);
+
+  bool has_displays() const { return !displays_.empty(); }
+  bool has_active_or_pending_displays() const {
+    return !displays_.empty() || !pending_displays_.empty();
+  }
+
+  // Returns the id for the next root window (both for the root of a Display
+  // as well as the root of WindowManagers).
+  WindowId GetAndAdvanceNextRootId();
+
+  uint32_t GetAndAdvanceNextDisplayId();
+
+  // Called when the AcceleratedWidget is available for |display|.
+  void OnDisplayAcceleratedWidgetAvailable(Display* display);
+
+ private:
+  DisplayManagerDelegate* delegate_;
+
+  // Displays are initially added to |pending_displays_|. When the display is
+  // initialized it is moved to |displays_|. ConnectionManager owns the
+  // Displays.
+  std::set<Display*> pending_displays_;
+  std::set<Display*> displays_;
+
+  std::map<UserId, scoped_ptr<UserDisplayManager>> user_display_managers_;
+
+  // ID to use for next root node.
+  ConnectionSpecificId next_root_id_;
+
+  uint32_t next_display_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(DisplayManager);
+};
+
+}  // namespace ws
+}  // namespace mus
+
+#endif  // COMPONENTS_MUS_WS_DISPLAY_MANAGER_H_
diff --git a/components/mus/ws/display_manager_delegate.h b/components/mus/ws/display_manager_delegate.h
new file mode 100644
index 0000000..0af7760
--- /dev/null
+++ b/components/mus/ws/display_manager_delegate.h
@@ -0,0 +1,26 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MUS_WS_DISPLAY_MANAGER_DELEGATE_H_
+#define COMPONENTS_MUS_WS_DISPLAY_MANAGER_DELEGATE_H_
+
+namespace mus {
+namespace ws {
+
+class Display;
+
+class DisplayManagerDelegate {
+ public:
+  virtual void OnWillDestroyDisplay(Display* display) = 0;
+  virtual void OnFirstDisplayReady() = 0;
+  virtual void OnNoMoreDisplays() = 0;
+
+ protected:
+  virtual ~DisplayManagerDelegate() {}
+};
+
+}  // namespace ws
+}  // namespace mus
+
+#endif  // COMPONENTS_MUS_WS_DISPLAY_MANAGER_DELEGATE_H_
diff --git a/components/mus/ws/display_unittest.cc b/components/mus/ws/display_unittest.cc
index 663e04c1..128d3a97 100644
--- a/components/mus/ws/display_unittest.cc
+++ b/components/mus/ws/display_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/mus/surfaces/surfaces_state.h"
 #include "components/mus/ws/connection_manager.h"
 #include "components/mus/ws/connection_manager_delegate.h"
+#include "components/mus/ws/display_manager.h"
 #include "components/mus/ws/ids.h"
 #include "components/mus/ws/platform_display.h"
 #include "components/mus/ws/platform_display_factory.h"
@@ -80,16 +81,17 @@
 
   const UserId kTestId1 = "2";
   const UserId kTestId2 = "21";
+  DisplayManager* display_manager = connection_manager_->display_manager();
   WindowManagerFactoryRegistryTestApi(
       connection_manager_->window_manager_factory_registry())
       .AddService(kTestId1, &test_window_manager_factory_);
   // The first register should trigger creation of the default
   // Displays. There should be kNumHostsToCreate Displays.
   EXPECT_EQ(static_cast<size_t>(kNumHostsToCreate),
-            connection_manager_->displays().size());
+            display_manager->displays().size());
 
   // Each host should have a WindowManagerState for kTestId1.
-  for (Display* display : connection_manager_->displays()) {
+  for (Display* display : display_manager->displays()) {
     EXPECT_EQ(1u, display->num_window_manger_states());
     EXPECT_TRUE(display->GetWindowManagerStateForUser(kTestId1));
     EXPECT_FALSE(display->GetWindowManagerStateForUser(kTestId2));
@@ -99,7 +101,7 @@
   WindowManagerFactoryRegistryTestApi(
       connection_manager_->window_manager_factory_registry())
       .AddService(kTestId2, &test_window_manager_factory_);
-  for (Display* display : connection_manager_->displays()) {
+  for (Display* display : display_manager->displays()) {
     ASSERT_EQ(2u, display->num_window_manger_states());
     WindowManagerState* state1 =
         display->GetWindowManagerStateForUser(kTestId1);
@@ -123,11 +125,12 @@
       .AddService(kTestId1, &test_window_manager_factory_);
 
   // Add another registry, should trigger creation of another wm.
+  DisplayManager* display_manager = connection_manager_->display_manager();
   WindowManagerFactoryRegistryTestApi(
       connection_manager_->window_manager_factory_registry())
       .AddService(kTestId2, &test_window_manager_factory_);
-  ASSERT_EQ(1u, connection_manager_->displays().size());
-  Display* display = *connection_manager_->displays().begin();
+  ASSERT_EQ(1u, display_manager->displays().size());
+  Display* display = *display_manager->displays().begin();
   ASSERT_EQ(2u, display->num_window_manger_states());
   // There should be two trees, one for each windowmanager.
   EXPECT_EQ(2u, connection_manager_->num_trees());
@@ -139,15 +142,15 @@
     connection_manager_->DestroyTree(state->tree());
     ASSERT_EQ(1u, display->num_window_manger_states());
     EXPECT_FALSE(display->GetWindowManagerStateForUser(kTestId1));
-    EXPECT_EQ(1u, connection_manager_->displays().size());
+    EXPECT_EQ(1u, display_manager->displays().size());
     EXPECT_EQ(1u, connection_manager_->num_trees());
   }
 
-  EXPECT_FALSE(connection_manager_delegate_.got_on_no_more_connections());
+  EXPECT_FALSE(connection_manager_delegate_.got_on_no_more_displays());
   // Destroy the Display, which should shutdown the trees.
-  connection_manager_->DestroyDisplay(display);
+  connection_manager_->display_manager()->DestroyDisplay(display);
   EXPECT_EQ(0u, connection_manager_->num_trees());
-  EXPECT_TRUE(connection_manager_delegate_.got_on_no_more_connections());
+  EXPECT_TRUE(connection_manager_delegate_.got_on_no_more_displays());
 }
 
 }  // namespace test
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
index 4aa6b8c..71dea6063 100644
--- a/components/mus/ws/event_dispatcher.cc
+++ b/components/mus/ws/event_dispatcher.cc
@@ -58,11 +58,13 @@
  public:
   explicit EventMatcher(const mojom::EventMatcher& matcher)
       : fields_to_match_(NONE),
+        accelerator_phase_(mojom::AcceleratorPhase::PRE_TARGET),
         event_type_(ui::ET_UNKNOWN),
         event_flags_(ui::EF_NONE),
         ignore_event_flags_(ui::EF_NONE),
         keyboard_code_(ui::VKEY_UNKNOWN),
         pointer_type_(ui::EventPointerType::POINTER_TYPE_UNKNOWN) {
+    accelerator_phase_ = matcher.accelerator_phase;
     if (matcher.type_matcher) {
       fields_to_match_ |= TYPE;
       switch (matcher.type_matcher->type) {
@@ -124,7 +126,10 @@
 
   ~EventMatcher() {}
 
-  bool MatchesEvent(const ui::Event& event) const {
+  bool MatchesEvent(const ui::Event& event,
+                    const mojom::AcceleratorPhase phase) const {
+    if (accelerator_phase_ != phase)
+      return false;
     if ((fields_to_match_ & TYPE) && event.type() != event_type_)
       return false;
     int flags = event.flags() & ~ignore_event_flags_;
@@ -154,6 +159,7 @@
 
   bool Equals(const EventMatcher& matcher) const {
     return fields_to_match_ == matcher.fields_to_match_ &&
+           accelerator_phase_ == matcher.accelerator_phase_ &&
            event_type_ == matcher.event_type_ &&
            event_flags_ == matcher.event_flags_ &&
            ignore_event_flags_ == matcher.ignore_event_flags_ &&
@@ -173,6 +179,7 @@
   };
 
   uint32_t fields_to_match_;
+  mojom::AcceleratorPhase accelerator_phase_;
   ui::EventType event_type_;
   // Bitfields of kEventFlag* and kMouseEventFlag* values in
   // input_event_constants.mojom.
@@ -296,7 +303,8 @@
     const ui::KeyEvent* key_event = event.AsKeyEvent();
     if (event.type() == ui::ET_KEY_PRESSED && !key_event->is_char()) {
       uint32_t accelerator = 0u;
-      if (FindAccelerator(*key_event, &accelerator)) {
+      if (FindAccelerator(*key_event, mojom::AcceleratorPhase::PRE_TARGET,
+                          &accelerator)) {
         delegate_->OnAccelerator(accelerator, event);
         return;
       }
@@ -504,9 +512,10 @@
 }
 
 bool EventDispatcher::FindAccelerator(const ui::KeyEvent& event,
+                                      const mojom::AcceleratorPhase phase,
                                       uint32_t* accelerator_id) {
   for (const auto& pair : accelerators_) {
-    if (pair.second.MatchesEvent(event)) {
+    if (pair.second.MatchesEvent(event, phase)) {
       *accelerator_id = pair.first;
       return true;
     }
diff --git a/components/mus/ws/event_dispatcher.h b/components/mus/ws/event_dispatcher.h
index 1f36fe6..432213e 100644
--- a/components/mus/ws/event_dispatcher.h
+++ b/components/mus/ws/event_dispatcher.h
@@ -137,11 +137,13 @@
   // observer for a window if any pointer events are targeting it.
   bool IsObservingWindow(ServerWindow* window);
 
-  // Looks to see if there is an accelerator bound to the specified code/flags.
-  // If there is one, sets |accelerator_id| to the id of the accelerator invoked
-  // and returns true. If there is none, returns false so normal key event
-  // processing can continue.
-  bool FindAccelerator(const ui::KeyEvent& event, uint32_t* accelerator_id);
+  // Looks to see if there is an accelerator bound to the specified code/flags,
+  // and of the matching |phase|. If there is one, sets |accelerator_id| to the
+  // id of the accelerator invoked and returns true. If there is none, returns
+  // false so normal key event processing can continue.
+  bool FindAccelerator(const ui::KeyEvent& event,
+                       const mojom::AcceleratorPhase phase,
+                       uint32_t* accelerator_id);
 
   // ServerWindowObserver:
   void OnWillChangeWindowHierarchy(ServerWindow* window,
diff --git a/components/mus/ws/event_dispatcher_unittest.cc b/components/mus/ws/event_dispatcher_unittest.cc
index a6d6c09..5dac279 100644
--- a/components/mus/ws/event_dispatcher_unittest.cc
+++ b/components/mus/ws/event_dispatcher_unittest.cc
@@ -355,6 +355,26 @@
   EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator());
 }
 
+// Tests that a post-target accelerator is not triggered by ProcessEvent.
+TEST_F(EventDispatcherTest, PostTargetAccelerator) {
+  TestEventDispatcherDelegate* event_dispatcher_delegate =
+      test_event_dispatcher_delegate();
+  EventDispatcher* dispatcher = event_dispatcher();
+
+  mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher(
+      mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown);
+  matcher->accelerator_phase = mojom::AcceleratorPhase::POST_TARGET;
+  uint32_t accelerator_1 = 1;
+  dispatcher->AddAccelerator(accelerator_1, std::move(matcher));
+
+  ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN);
+  dispatcher->ProcessEvent(key);
+  EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator());
+
+  // TODO(jonross): Update this test to include actual invokation of PostTarget
+  // acceleratos once events acking includes consuming.
+}
+
 TEST_F(EventDispatcherTest, Capture) {
   ServerWindow* root = root_window();
   scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
diff --git a/components/mus/ws/server_window_delegate.h b/components/mus/ws/server_window_delegate.h
index 760d45a6..8aaad34 100644
--- a/components/mus/ws/server_window_delegate.h
+++ b/components/mus/ws/server_window_delegate.h
@@ -23,7 +23,7 @@
  public:
   virtual SurfacesState* GetSurfacesState() = 0;
 
-  virtual void OnScheduleWindowPaint(const ServerWindow* window) = 0;
+  virtual void OnScheduleWindowPaint(ServerWindow* window) = 0;
 
   // Returns the root of the window tree to which this |window| is attached.
   // Returns null if this window is not attached up through to a root window.
diff --git a/components/mus/ws/test_server_window_delegate.cc b/components/mus/ws/test_server_window_delegate.cc
index 24677a6..9a033b3 100644
--- a/components/mus/ws/test_server_window_delegate.cc
+++ b/components/mus/ws/test_server_window_delegate.cc
@@ -17,8 +17,7 @@
   return nullptr;
 }
 
-void TestServerWindowDelegate::OnScheduleWindowPaint(
-    const ServerWindow* window) {}
+void TestServerWindowDelegate::OnScheduleWindowPaint(ServerWindow* window) {}
 
 const ServerWindow* TestServerWindowDelegate::GetRootWindow(
     const ServerWindow* window) const {
diff --git a/components/mus/ws/test_server_window_delegate.h b/components/mus/ws/test_server_window_delegate.h
index d299984..f7661e5 100644
--- a/components/mus/ws/test_server_window_delegate.h
+++ b/components/mus/ws/test_server_window_delegate.h
@@ -24,7 +24,7 @@
  private:
   // ServerWindowDelegate:
   mus::SurfacesState* GetSurfacesState() override;
-  void OnScheduleWindowPaint(const ServerWindow* window) override;
+  void OnScheduleWindowPaint(ServerWindow* window) override;
   const ServerWindow* GetRootWindow(const ServerWindow* window) const override;
   void ScheduleSurfaceDestruction(ServerWindow* window) override;
   ServerWindow* FindWindowForSurface(
diff --git a/components/mus/ws/test_utils.cc b/components/mus/ws/test_utils.cc
index 55dc179..a02b675 100644
--- a/components/mus/ws/test_utils.cc
+++ b/components/mus/ws/test_utils.cc
@@ -247,8 +247,8 @@
 TestConnectionManagerDelegate::TestConnectionManagerDelegate() {}
 TestConnectionManagerDelegate::~TestConnectionManagerDelegate() {}
 
-void TestConnectionManagerDelegate::OnNoMoreRootConnections() {
-  got_on_no_more_connections_ = true;
+void TestConnectionManagerDelegate::OnNoMoreDisplays() {
+  got_on_no_more_displays_ = true;
 }
 
 scoped_ptr<WindowTreeBinding>
diff --git a/components/mus/ws/test_utils.h b/components/mus/ws/test_utils.h
index 216d3a0b..642fd1b7 100644
--- a/components/mus/ws/test_utils.h
+++ b/components/mus/ws/test_utils.h
@@ -7,12 +7,14 @@
 
 #include <stdint.h>
 
+#include "components/mus/public/interfaces/display.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "components/mus/ws/connection_manager_delegate.h"
 #include "components/mus/ws/display.h"
 #include "components/mus/ws/platform_display.h"
 #include "components/mus/ws/platform_display_factory.h"
 #include "components/mus/ws/test_change_tracker.h"
+#include "components/mus/ws/user_display_manager.h"
 #include "components/mus/ws/window_manager_factory_registry.h"
 #include "components/mus/ws/window_tree.h"
 #include "components/mus/ws/window_tree_binding.h"
@@ -38,6 +40,25 @@
 
 // -----------------------------------------------------------------------------
 
+class UserDisplayManagerTestApi {
+ public:
+  explicit UserDisplayManagerTestApi(UserDisplayManager* udm) : udm_(udm) {}
+  ~UserDisplayManagerTestApi() {}
+
+  void SetTestObserver(mojom::DisplayManagerObserver* observer) {
+    udm_->test_observer_ = observer;
+    if (observer)
+      udm_->OnObserverAdded(observer);
+  }
+
+ private:
+  UserDisplayManager* udm_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserDisplayManagerTestApi);
+};
+
+// -----------------------------------------------------------------------------
+
 class WindowTreeTestApi {
  public:
   WindowTreeTestApi(WindowTree* tree);
@@ -211,12 +232,10 @@
   }
   TestWindowTreeBinding* last_binding() { return last_binding_; }
 
-  bool got_on_no_more_connections() const {
-    return got_on_no_more_connections_;
-  }
+  bool got_on_no_more_displays() const { return got_on_no_more_displays_; }
 
   // ConnectionManagerDelegate:
-  void OnNoMoreRootConnections() override;
+  void OnNoMoreDisplays() override;
   scoped_ptr<WindowTreeBinding> CreateWindowTreeBindingForEmbedAtWindow(
       ws::ConnectionManager* connection_manager,
       ws::WindowTree* tree,
@@ -231,7 +250,7 @@
   TestWindowTreeBinding* last_binding_ = nullptr;
   Display* display_ = nullptr;
   ConnectionManager* connection_manager_ = nullptr;
-  bool got_on_no_more_connections_ = false;
+  bool got_on_no_more_displays_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(TestConnectionManagerDelegate);
 };
diff --git a/components/mus/ws/user_display_manager.cc b/components/mus/ws/user_display_manager.cc
new file mode 100644
index 0000000..b432a2f5
--- /dev/null
+++ b/components/mus/ws/user_display_manager.cc
@@ -0,0 +1,124 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mus/ws/user_display_manager.h"
+
+#include "components/mus/ws/display.h"
+#include "components/mus/ws/display_manager.h"
+#include "components/mus/ws/window_manager_state.h"
+
+namespace mus {
+namespace ws {
+
+UserDisplayManager::UserDisplayManager(ws::DisplayManager* display_manager,
+                                       const UserId& user_id)
+    : display_manager_(display_manager), user_id_(user_id) {
+  for (const WindowManagerState* wms : GetWindowManagerStatesForUser()) {
+    if (wms->got_frame_decoration_values()) {
+      got_valid_frame_decorations_ = true;
+      break;
+    }
+  }
+}
+
+UserDisplayManager::~UserDisplayManager() {}
+
+void UserDisplayManager::OnFrameDecorationValuesChanged(
+    WindowManagerState* wms) {
+  if (!got_valid_frame_decorations_) {
+    got_valid_frame_decorations_ = true;
+    display_manager_observers_.ForAllPtrs([this](
+        mojom::DisplayManagerObserver* observer) { CallOnDisplays(observer); });
+    if (test_observer_)
+      CallOnDisplays(test_observer_);
+    return;
+  }
+
+  display_manager_observers_.ForAllPtrs(
+      [this, &wms](mojom::DisplayManagerObserver* observer) {
+        CallOnDisplayChanged(wms, observer);
+      });
+  if (test_observer_)
+    CallOnDisplayChanged(wms, test_observer_);
+}
+
+void UserDisplayManager::AddDisplayManagerBinding(
+    mojo::InterfaceRequest<mojom::DisplayManager> request) {
+  display_manager_bindings_.AddBinding(this, std::move(request));
+}
+
+void UserDisplayManager::OnWillDestroyDisplay(Display* display) {
+  if (!display->GetWindowManagerStateForUser(user_id_)
+           ->got_frame_decoration_values()) {
+    return;
+  }
+
+  display_manager_observers_.ForAllPtrs(
+      [this, &display](mojom::DisplayManagerObserver* observer) {
+        observer->OnDisplayRemoved(display->id());
+      });
+  if (test_observer_)
+    test_observer_->OnDisplayRemoved(display->id());
+}
+
+std::set<const WindowManagerState*>
+UserDisplayManager::GetWindowManagerStatesForUser() const {
+  std::set<const WindowManagerState*> result;
+  for (const Display* display : display_manager_->displays()) {
+    const WindowManagerState* wms =
+        display->GetWindowManagerStateForUser(user_id_);
+    if (wms && wms->got_frame_decoration_values())
+      result.insert(wms);
+  }
+  return result;
+}
+
+void UserDisplayManager::OnObserverAdded(
+    mojom::DisplayManagerObserver* observer) {
+  // Many clients key off the frame decorations to size widgets. Wait for frame
+  // decorations before notifying so that we don't have to worry about clients
+  // resizing appropriately.
+  if (!got_valid_frame_decorations_)
+    return;
+
+  CallOnDisplays(observer);
+}
+
+void UserDisplayManager::CallOnDisplays(
+    mojom::DisplayManagerObserver* observer) {
+  std::set<const WindowManagerState*> wmss = GetWindowManagerStatesForUser();
+  mojo::Array<mojom::DisplayPtr> display_ptrs(wmss.size());
+  {
+    size_t i = 0;
+    // TODO(sky): need ordering!
+    for (const WindowManagerState* wms : wmss) {
+      display_ptrs[i] = wms->ToMojomDisplay();
+      ++i;
+    }
+  }
+  observer->OnDisplays(std::move(display_ptrs));
+}
+
+void UserDisplayManager::CallOnDisplayChanged(
+    WindowManagerState* wms,
+    mojom::DisplayManagerObserver* observer) {
+  mojo::Array<mojom::DisplayPtr> displays(1);
+  displays[0] = wms->ToMojomDisplay();
+  display_manager_observers_.ForAllPtrs(
+      [&displays](mojom::DisplayManagerObserver* observer) {
+        observer->OnDisplaysChanged(displays.Clone());
+      });
+  if (test_observer_)
+    test_observer_->OnDisplaysChanged(displays.Clone());
+}
+
+void UserDisplayManager::AddObserver(
+    mojom::DisplayManagerObserverPtr observer) {
+  mojom::DisplayManagerObserver* observer_impl = observer.get();
+  display_manager_observers_.AddInterfacePtr(std::move(observer));
+  OnObserverAdded(observer_impl);
+}
+
+}  // namespace ws
+}  // namespace mus
diff --git a/components/mus/ws/user_display_manager.h b/components/mus/ws/user_display_manager.h
new file mode 100644
index 0000000..c17a7c6
--- /dev/null
+++ b/components/mus/ws/user_display_manager.h
@@ -0,0 +1,83 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MUS_WS_USER_DISPLAY_MANAGER_H_
+#define COMPONENTS_MUS_WS_USER_DISPLAY_MANAGER_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "components/mus/public/interfaces/display.mojom.h"
+#include "components/mus/ws/user_id.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+
+namespace mus {
+namespace ws {
+
+class Display;
+class DisplayManager;
+class WindowManagerState;
+
+namespace test {
+class UserDisplayManagerTestApi;
+}
+
+// Provides per user display state.
+class UserDisplayManager : public mojom::DisplayManager {
+ public:
+  UserDisplayManager(ws::DisplayManager* display_manager,
+                     const UserId& user_id);
+  ~UserDisplayManager() override;
+
+  void OnFrameDecorationValuesChanged(WindowManagerState* wms);
+
+  void AddDisplayManagerBinding(
+      mojo::InterfaceRequest<mojom::DisplayManager> request);
+
+  // Called by Display prior to |display| being removed and destroyed.
+  void OnWillDestroyDisplay(Display* display);
+
+ private:
+  friend class test::UserDisplayManagerTestApi;
+
+  // Returns the WindowManagerStates for the associated user that have frame
+  // decoration values.
+  std::set<const WindowManagerState*> GetWindowManagerStatesForUser() const;
+
+  void OnObserverAdded(mojom::DisplayManagerObserver* observer);
+
+  // Calls OnDisplays() on |observer|.
+  void CallOnDisplays(mojom::DisplayManagerObserver* observer);
+
+  // Calls observer->OnDisplaysChanged() with the display for |display|.
+  void CallOnDisplayChanged(WindowManagerState* wms,
+                            mojom::DisplayManagerObserver* observer);
+
+  // Overriden from mojom::DisplayManager:
+  void AddObserver(mojom::DisplayManagerObserverPtr observer) override;
+
+  ws::DisplayManager* display_manager_;
+
+  const UserId user_id_;
+
+  // Set to true the first time at least one Display has valid frame values.
+  bool got_valid_frame_decorations_ = false;
+
+  mojo::BindingSet<mojom::DisplayManager> display_manager_bindings_;
+
+  // WARNING: only use these once |got_valid_frame_decorations_| is true.
+  mojo::InterfacePtrSet<mojom::DisplayManagerObserver>
+      display_manager_observers_;
+
+  // Observer used for tests.
+  mojom::DisplayManagerObserver* test_observer_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(UserDisplayManager);
+};
+
+}  // namespace ws
+}  // namespace mus
+
+#endif  // COMPONENTS_MUS_WS_USER_DISPLAY_MANAGER_H_
diff --git a/components/mus/ws/user_display_manager_unittest.cc b/components/mus/ws/user_display_manager_unittest.cc
new file mode 100644
index 0000000..bf02e01fd
--- /dev/null
+++ b/components/mus/ws/user_display_manager_unittest.cc
@@ -0,0 +1,233 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/mus/common/types.h"
+#include "components/mus/common/util.h"
+#include "components/mus/public/interfaces/window_tree.mojom.h"
+#include "components/mus/surfaces/surfaces_state.h"
+#include "components/mus/ws/connection_manager.h"
+#include "components/mus/ws/connection_manager_delegate.h"
+#include "components/mus/ws/display_binding.h"
+#include "components/mus/ws/display_manager.h"
+#include "components/mus/ws/ids.h"
+#include "components/mus/ws/platform_display.h"
+#include "components/mus/ws/platform_display_factory.h"
+#include "components/mus/ws/server_window.h"
+#include "components/mus/ws/test_utils.h"
+#include "components/mus/ws/window_manager_state.h"
+#include "components/mus/ws/window_tree.h"
+#include "components/mus/ws/window_tree_binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace mus {
+namespace ws {
+namespace test {
+namespace {
+
+class TestWindowManagerFactory : public mojom::WindowManagerFactory {
+ public:
+  TestWindowManagerFactory() {}
+  ~TestWindowManagerFactory() override {}
+
+  // mojom::WindowManagerFactory:
+  void CreateWindowManager(
+      mus::mojom::DisplayPtr display,
+      mus::mojom::WindowTreeClientRequest client) override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestWindowManagerFactory);
+};
+
+class TestDisplayManagerObserver : public mojom::DisplayManagerObserver {
+ public:
+  TestDisplayManagerObserver() {}
+  ~TestDisplayManagerObserver() override {}
+
+  std::string GetAndClearObserverCalls() {
+    std::string result;
+    std::swap(observer_calls_, result);
+    return result;
+  }
+
+ private:
+  void AddCall(const std::string& call) {
+    if (!observer_calls_.empty())
+      observer_calls_ += "\n";
+    observer_calls_ += call;
+  }
+
+  std::string DisplayIdsToString(
+      const mojo::Array<mojom::DisplayPtr>& displays) {
+    std::string display_ids;
+    for (const auto& display : displays) {
+      if (!display_ids.empty())
+        display_ids += " ";
+      display_ids += base::Int64ToString(display->id);
+    }
+    return display_ids;
+  }
+
+  // mojom::DisplayManagerObserver:
+  void OnDisplays(mojo::Array<mojom::DisplayPtr> displays) override {
+    AddCall("OnDisplays " + DisplayIdsToString(displays));
+  }
+  void OnDisplaysChanged(mojo::Array<mojom::DisplayPtr> displays) override {
+    AddCall("OnDisplaysChanged " + DisplayIdsToString(displays));
+  }
+  void OnDisplayRemoved(int64_t id) override {
+    AddCall("OnDisplayRemoved " + base::Int64ToString(id));
+  }
+
+  std::string observer_calls_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerObserver);
+};
+
+mojom::FrameDecorationValuesPtr CreateDefaultFrameDecorationValues() {
+  mojom::FrameDecorationValuesPtr frame_decoration_values =
+      mojom::FrameDecorationValues::New();
+  frame_decoration_values->normal_client_area_insets = mojo::Insets::New();
+  frame_decoration_values->maximized_client_area_insets = mojo::Insets::New();
+  return frame_decoration_values;
+}
+
+}  // namespace
+
+// -----------------------------------------------------------------------------
+
+class UserDisplayManagerTest : public testing::Test {
+ public:
+  UserDisplayManagerTest()
+      : cursor_id_(0), platform_display_factory_(&cursor_id_) {}
+  ~UserDisplayManagerTest() override {}
+
+ protected:
+  // testing::Test:
+  void SetUp() override {
+    PlatformDisplay::set_factory_for_testing(&platform_display_factory_);
+    connection_manager_.reset(new ConnectionManager(
+        &connection_manager_delegate_, scoped_refptr<SurfacesState>()));
+    connection_manager_delegate_.set_connection_manager(
+        connection_manager_.get());
+  }
+
+ protected:
+  int32_t cursor_id_;
+  TestPlatformDisplayFactory platform_display_factory_;
+  TestConnectionManagerDelegate connection_manager_delegate_;
+  scoped_ptr<ConnectionManager> connection_manager_;
+  base::MessageLoop message_loop_;
+  TestWindowManagerFactory test_window_manager_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserDisplayManagerTest);
+};
+
+TEST_F(UserDisplayManagerTest, OnlyNotifyWhenFrameDecorationsSet) {
+  connection_manager_delegate_.set_num_displays_to_create(1);
+
+  const UserId kUserId1 = "2";
+  TestDisplayManagerObserver display_manager_observer1;
+  DisplayManager* display_manager = connection_manager_->display_manager();
+  WindowManagerFactoryRegistryTestApi(
+      connection_manager_->window_manager_factory_registry())
+      .AddService(kUserId1, &test_window_manager_factory_);
+  UserDisplayManager* user_display_manager1 =
+      display_manager->GetUserDisplayManager(kUserId1);
+  ASSERT_TRUE(user_display_manager1);
+  UserDisplayManagerTestApi(user_display_manager1)
+      .SetTestObserver(&display_manager_observer1);
+  // Observer should not have been notified yet.
+  EXPECT_EQ(std::string(),
+            display_manager_observer1.GetAndClearObserverCalls());
+
+  // Set the frame decoration values, which should trigger sending immediately.
+  ASSERT_EQ(1u, display_manager->displays().size());
+  Display* display1 = *display_manager->displays().begin();
+  display1->GetWindowManagerStateForUser(kUserId1)->SetFrameDecorationValues(
+      CreateDefaultFrameDecorationValues());
+  EXPECT_EQ("OnDisplays 1",
+            display_manager_observer1.GetAndClearObserverCalls());
+
+  UserDisplayManagerTestApi(user_display_manager1).SetTestObserver(nullptr);
+}
+
+TEST_F(UserDisplayManagerTest, AddObserverAfterFrameDecorationsSet) {
+  connection_manager_delegate_.set_num_displays_to_create(1);
+
+  const UserId kUserId1 = "2";
+  TestDisplayManagerObserver display_manager_observer1;
+  DisplayManager* display_manager = connection_manager_->display_manager();
+  WindowManagerFactoryRegistryTestApi(
+      connection_manager_->window_manager_factory_registry())
+      .AddService(kUserId1, &test_window_manager_factory_);
+  UserDisplayManager* user_display_manager1 =
+      display_manager->GetUserDisplayManager(kUserId1);
+  ASSERT_TRUE(user_display_manager1);
+  ASSERT_EQ(1u, display_manager->displays().size());
+  Display* display1 = *display_manager->displays().begin();
+  display1->GetWindowManagerStateForUser(kUserId1)->SetFrameDecorationValues(
+      CreateDefaultFrameDecorationValues());
+
+  UserDisplayManagerTestApi(user_display_manager1)
+      .SetTestObserver(&display_manager_observer1);
+  EXPECT_EQ("OnDisplays 1",
+            display_manager_observer1.GetAndClearObserverCalls());
+
+  UserDisplayManagerTestApi(user_display_manager1).SetTestObserver(nullptr);
+}
+
+TEST_F(UserDisplayManagerTest, AddRemoveDisplay) {
+  connection_manager_delegate_.set_num_displays_to_create(1);
+
+  const UserId kUserId1 = "2";
+  TestDisplayManagerObserver display_manager_observer1;
+  DisplayManager* display_manager = connection_manager_->display_manager();
+  WindowManagerFactoryRegistryTestApi(
+      connection_manager_->window_manager_factory_registry())
+      .AddService(kUserId1, &test_window_manager_factory_);
+  UserDisplayManager* user_display_manager1 =
+      display_manager->GetUserDisplayManager(kUserId1);
+  ASSERT_TRUE(user_display_manager1);
+  ASSERT_EQ(1u, display_manager->displays().size());
+  Display* display1 = *display_manager->displays().begin();
+  display1->GetWindowManagerStateForUser(kUserId1)->SetFrameDecorationValues(
+      CreateDefaultFrameDecorationValues());
+  UserDisplayManagerTestApi(user_display_manager1)
+      .SetTestObserver(&display_manager_observer1);
+  EXPECT_EQ("OnDisplays 1",
+            display_manager_observer1.GetAndClearObserverCalls());
+
+  // Add another display.
+  Display* display2 =
+      new Display(connection_manager_.get(), nullptr, scoped_refptr<GpuState>(),
+                  scoped_refptr<mus::SurfacesState>());
+  display2->Init(nullptr);
+
+  // Observer should not have been notified yet as frame decorations not set.
+  EXPECT_EQ("", display_manager_observer1.GetAndClearObserverCalls());
+  display2->GetWindowManagerStateForUser(kUserId1)->SetFrameDecorationValues(
+      CreateDefaultFrameDecorationValues());
+  EXPECT_EQ("OnDisplaysChanged 2",
+            display_manager_observer1.GetAndClearObserverCalls());
+
+  // Remove the display and verify observer is notified.
+  display_manager->DestroyDisplay(display2);
+  display2 = nullptr;
+  EXPECT_EQ("OnDisplayRemoved 2",
+            display_manager_observer1.GetAndClearObserverCalls());
+
+  UserDisplayManagerTestApi(user_display_manager1).SetTestObserver(nullptr);
+}
+
+}  // namespace test
+}  // namespace ws
+}  // namespace mus
diff --git a/components/mus/ws/window_manager_state.cc b/components/mus/ws/window_manager_state.cc
index f017dca6..f7ccc63d2d 100644
--- a/components/mus/ws/window_manager_state.cc
+++ b/components/mus/ws/window_manager_state.cc
@@ -5,7 +5,9 @@
 #include "components/mus/ws/window_manager_state.h"
 
 #include "components/mus/ws/connection_manager.h"
+#include "components/mus/ws/display_manager.h"
 #include "components/mus/ws/server_window.h"
+#include "components/mus/ws/user_display_manager.h"
 #include "mojo/shell/public/interfaces/connector.mojom.h"
 
 namespace mus {
@@ -25,9 +27,14 @@
     : display_(display),
       is_user_id_valid_(is_user_id_valid),
       user_id_(user_id) {
+  frame_decoration_values_ = mojom::FrameDecorationValues::New();
+  frame_decoration_values_->normal_client_area_insets = mojo::Insets::New();
+  frame_decoration_values_->maximized_client_area_insets = mojo::Insets::New();
+  frame_decoration_values_->max_title_bar_button_width = 0u;
+
   ConnectionManager* connection_manager = display_->connection_manager();
   root_.reset(connection_manager->CreateServerWindow(
-      RootWindowId(connection_manager->GetAndAdvanceNextRootId()),
+      connection_manager->display_manager()->GetAndAdvanceNextRootId(),
       ServerWindow::Properties()));
   // Our root is always a child of the Display's root. Do this
   // before the WindowTree has been created so that the client doesn't get
@@ -37,5 +44,22 @@
   display->root_window()->Add(root_.get());
 }
 
+void WindowManagerState::SetFrameDecorationValues(
+    mojom::FrameDecorationValuesPtr values) {
+  got_frame_decoration_values_ = true;
+  frame_decoration_values_ = values.Clone();
+  display_->display_manager()
+      ->GetUserDisplayManager(user_id_)
+      ->OnFrameDecorationValuesChanged(this);
+}
+
+mojom::DisplayPtr WindowManagerState::ToMojomDisplay() const {
+  mojom::DisplayPtr display_ptr = display_->ToMojomDisplay();
+  // TODO(sky): set work area.
+  display_ptr->work_area = display_ptr->bounds.Clone();
+  display_ptr->frame_decoration_values = frame_decoration_values_.Clone();
+  return display_ptr;
+}
+
 }  // namespace ws
 }  // namespace mus
diff --git a/components/mus/ws/window_manager_state.h b/components/mus/ws/window_manager_state.h
index adc30c1..c0fe99aa 100644
--- a/components/mus/ws/window_manager_state.h
+++ b/components/mus/ws/window_manager_state.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include "base/memory/scoped_ptr.h"
+#include "components/mus/public/interfaces/display.mojom.h"
 #include "components/mus/ws/user_id.h"
 
 namespace mus {
@@ -34,6 +35,21 @@
   WindowTree* tree() { return tree_; }
   const WindowTree* tree() const { return tree_; }
 
+  Display* display() { return display_; }
+  const Display* display() const { return display_; }
+
+  void SetFrameDecorationValues(mojom::FrameDecorationValuesPtr values);
+  const mojom::FrameDecorationValues& frame_decoration_values() const {
+    return *frame_decoration_values_;
+  }
+  bool got_frame_decoration_values() const {
+    return got_frame_decoration_values_;
+  }
+
+  // Returns a mojom::Display for the specified display. WindowManager specific
+  // values are not set.
+  mojom::DisplayPtr ToMojomDisplay() const;
+
  private:
   friend class Display;
 
@@ -49,6 +65,10 @@
   scoped_ptr<ServerWindow> root_;
   WindowTree* tree_ = nullptr;
 
+  // Set to true the first time SetFrameDecorationValues() is received.
+  bool got_frame_decoration_values_ = false;
+  mojom::FrameDecorationValuesPtr frame_decoration_values_;
+
   DISALLOW_COPY_AND_ASSIGN(WindowManagerState);
 };
 
diff --git a/components/mus/ws/window_tree.cc b/components/mus/ws/window_tree.cc
index 7e1c405..7782e8b3 100644
--- a/components/mus/ws/window_tree.cc
+++ b/components/mus/ws/window_tree.cc
@@ -13,6 +13,7 @@
 #include "components/mus/ws/connection_manager.h"
 #include "components/mus/ws/default_access_policy.h"
 #include "components/mus/ws/display.h"
+#include "components/mus/ws/display_manager.h"
 #include "components/mus/ws/focus_controller.h"
 #include "components/mus/ws/operation.h"
 #include "components/mus/ws/platform_display.h"
@@ -154,7 +155,7 @@
 }
 
 const Display* WindowTree::GetDisplay(const ServerWindow* window) const {
-  return window ? connection_manager_->GetDisplayContaining(window) : nullptr;
+  return window ? display_manager()->GetDisplayContaining(window) : nullptr;
 }
 
 void WindowTree::OnWindowDestroyingTreeImpl(WindowTree* tree) {
@@ -563,20 +564,31 @@
                                      transient_client_window_id.id);
 }
 
+DisplayManager* WindowTree::display_manager() {
+  return connection_manager_->display_manager();
+}
+
+const DisplayManager* WindowTree::display_manager() const {
+  return connection_manager_->display_manager();
+}
+
 Display* WindowTree::GetDisplayForWindowManager() {
+  return GetWindowManagerStateForWindowManager()->display();
+}
+
+WindowManagerState* WindowTree::GetWindowManagerStateForWindowManager() {
   // The WindowTree for the wm has one and only one root.
   CHECK_EQ(1u, roots_.size());
 
   // Indicates this connection is for the wm.
   DCHECK(window_manager_internal_);
 
-  Display* display = GetDisplay(*roots_.begin());
-  WindowManagerAndDisplay wm_and_display =
-      connection_manager_->GetWindowManagerAndDisplay(*roots_.begin());
-  CHECK(wm_and_display.display);
-  CHECK(wm_and_display.window_manager_state);
-  DCHECK_EQ(this, wm_and_display.window_manager_state->tree());
-  return display;
+  WindowManagerState* wms = display_manager()
+                                ->GetWindowManagerAndDisplay(*roots_.begin())
+                                .window_manager_state;
+  CHECK(wms);
+  DCHECK_EQ(this, wms->tree());
+  return wms;
 }
 
 bool WindowTree::ShouldRouteToWindowManager(const ServerWindow* window) const {
@@ -592,9 +604,9 @@
 
   // The WindowManager is attached to the root of the Display, if there isn't a
   // WindowManager attached no need to route to it.
-  const WindowManagerState* wms =
-      connection_manager_->GetWindowManagerAndDisplay(window)
-          .window_manager_state;
+  const WindowManagerState* wms = display_manager()
+                                      ->GetWindowManagerAndDisplay(window)
+                                      .window_manager_state;
   if (!wms || !wms->tree()->window_manager_internal_)
     return false;
 
@@ -891,7 +903,7 @@
     mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) {
   DCHECK(!waiting_for_top_level_window_info_);
   const ClientWindowId client_window_id(transport_window_id);
-  Display* display = connection_manager_->GetActiveDisplay();
+  Display* display = display_manager()->GetActiveDisplay();
   // TODO(sky): need a way for client to provide context.
   WindowManagerState* wms =
       display ? display->GetFirstWindowManagerState() : nullptr;
@@ -1039,9 +1051,9 @@
         connection_manager_->GenerateWindowManagerChangeId(this, change_id);
     // |window_id| may be a client id, use the id from the window to ensure
     // the windowmanager doesn't get an id it doesn't know about.
-    WindowManagerState* wms =
-        connection_manager_->GetWindowManagerAndDisplay(window)
-            .window_manager_state;
+    WindowManagerState* wms = display_manager()
+                                  ->GetWindowManagerAndDisplay(window)
+                                  .window_manager_state;
     wms->tree()->window_manager_internal_->WmSetBounds(
         wm_change_id, wms->tree()->ClientWindowIdForWindow(window).id,
         std::move(bounds));
@@ -1074,9 +1086,9 @@
   if (window && ShouldRouteToWindowManager(window)) {
     const uint32_t wm_change_id =
         connection_manager_->GenerateWindowManagerChangeId(this, change_id);
-    WindowManagerState* wms =
-        connection_manager_->GetWindowManagerAndDisplay(window)
-            .window_manager_state;
+    WindowManagerState* wms = display_manager()
+                                  ->GetWindowManagerAndDisplay(window)
+                                  .window_manager_state;
     wms->tree()->window_manager_internal_->WmSetProperty(
         wm_change_id, wms->tree()->ClientWindowIdForWindow(window).id, name,
         std::move(value));
@@ -1318,8 +1330,9 @@
 
 void WindowTree::WmSetFrameDecorationValues(
     mojom::FrameDecorationValuesPtr values) {
-  if (GetDisplayForWindowManager())
-    GetDisplayForWindowManager()->SetFrameDecorationValues(std::move(values));
+  WindowManagerState* wm_state = GetWindowManagerStateForWindowManager();
+  if (wm_state)
+    wm_state->SetFrameDecorationValues(std::move(values));
 }
 
 void WindowTree::OnWmCreatedTopLevelWindow(uint32_t change_id,
diff --git a/components/mus/ws/window_tree.h b/components/mus/ws/window_tree.h
index fed9da0..378186d 100644
--- a/components/mus/ws/window_tree.h
+++ b/components/mus/ws/window_tree.h
@@ -15,7 +15,6 @@
 
 #include "base/containers/hash_tables.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "components/mus/public/interfaces/surface_id.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
@@ -34,9 +33,11 @@
 
 class AccessPolicy;
 class ConnectionManager;
+class DisplayManager;
 class Display;
 class ServerWindow;
 class TargetedEvent;
+class WindowManagerState;
 class WindowTreeTest;
 
 namespace test {
@@ -212,8 +213,12 @@
     EMBED,
   };
 
+  DisplayManager* display_manager();
+  const DisplayManager* display_manager() const;
+
   // Used when this tree is the window manager.
   Display* GetDisplayForWindowManager();
+  WindowManagerState* GetWindowManagerStateForWindowManager();
 
   bool ShouldRouteToWindowManager(const ServerWindow* window) const;
 
diff --git a/components/offline_pages/BUILD.gn b/components/offline_pages/BUILD.gn
index 88dbd1e..cdbdb7ba 100644
--- a/components/offline_pages/BUILD.gn
+++ b/components/offline_pages/BUILD.gn
@@ -61,6 +61,7 @@
 
   deps = [
     "//base",
+    "//components/version_info",
   ]
 }
 
diff --git a/components/offline_pages/DEPS b/components/offline_pages/DEPS
index 9f96ba9..2a2c644 100644
--- a/components/offline_pages/DEPS
+++ b/components/offline_pages/DEPS
@@ -2,6 +2,7 @@
   "+components/bookmarks",
   "+components/keyed_service",
   "+components/leveldb_proto",
+  "+components/version_info",
   "+net",
   "+third_party/leveldatabase",
 ]
diff --git a/components/offline_pages/offline_page_feature.cc b/components/offline_pages/offline_page_feature.cc
index beee145d..ed390b88 100644
--- a/components/offline_pages/offline_page_feature.cc
+++ b/components/offline_pages/offline_page_feature.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 #include "components/offline_pages/offline_page_switches.h"
+#include "components/version_info/version_info.h"
 
 #if defined(OS_ANDROID)
 
@@ -62,7 +63,10 @@
                        base::CompareCase::SENSITIVE)) {
     return FeatureMode::ENABLED_AS_SAVED_PAGES;
   }
-  return FeatureMode::DISABLED;
+
+  // Enabled by default on trunk.
+  return version_info::IsOfficialBuild() ? FeatureMode::DISABLED
+                                         : FeatureMode::ENABLED_AS_BOOKMARKS;
 }
 
 bool IsOfflinePagesEnabled() {
diff --git a/components/offline_pages/offline_page_model.cc b/components/offline_pages/offline_page_model.cc
index 8dd7491..50698ff5 100644
--- a/components/offline_pages/offline_page_model.cc
+++ b/components/offline_pages/offline_page_model.cc
@@ -286,7 +286,14 @@
 }
 
 bool OfflinePageModel::HasOfflinePages() const {
-  DCHECK(is_loaded_);
+  // Since offline pages feature is enabled by default,
+  // NetErrorTabHelper::SetHasOfflinePages might call this before the model is
+  // fully loaded. To address this, we need to switch to asynchonous model
+  // (crbug.com/589526). But for now, we just bail out to work around the test
+  // issue.
+  if (!is_loaded_)
+    return false;
+
   // Check that at least one page is not marked for deletion. Because we have
   // pages marked for deletion, we cannot simply invert result of |empty()|.
   for (const auto& id_page_pair : offline_pages_) {
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
index a32058f..886d3cb1 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -42,6 +42,8 @@
     "PageLoad.Internal.ProvisionalAbortChainSize.NewNavigation";
 const char kAbortChainSizeSameURL[] =
     "PageLoad.Internal.ProvisionalAbortChainSize.SameURL";
+const char kAbortChainSizeNoCommit[] =
+    "PageLoad.Internal.ProvisionalAbortChainSize.NoCommit";
 
 }  // namespace internal
 
@@ -162,9 +164,10 @@
 }
 
 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url) {
-  DCHECK_GT(aborted_chain_size_same_url, 0);
-  UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeSameURL,
-                       aborted_chain_size_same_url);
+  if (aborted_chain_size_same_url > 0) {
+    UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeSameURL,
+                         aborted_chain_size_same_url);
+  }
 }
 
 }  // namespace
@@ -196,15 +199,41 @@
       timing_.IsEmpty()) {
     RecordInternalError(ERR_NO_IPCS_RECEIVED);
   }
+  // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their
+  // chain length added to the next navigation. Take care not to double count
+  // them. Also do not double count committed loads, which call this already.
+  if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION)
+    LogAbortChainHistograms(nullptr);
+
   for (const auto& observer : observers_) {
     observer->OnComplete(timing_, info);
   }
 }
 
 void PageLoadTracker::LogAbortChainHistograms(
-    ui::PageTransition committed_transition) {
+    content::NavigationHandle* final_navigation) {
   if (aborted_chain_size_ == 0)
     return;
+  // Note that this could be broken out by this navigation's abort type, if more
+  // granularity is needed. Add one to the chain size to count the current
+  // navigation. In the other cases, the current navigation is the final
+  // navigation (which commits).
+  if (!final_navigation) {
+    UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeNoCommit,
+                         aborted_chain_size_ + 1);
+    LogAbortChainSameURLHistogram(aborted_chain_size_same_url_ + 1);
+    return;
+  }
+
+  // The following is only executed for committing trackers.
+  DCHECK(!commit_time_.is_null());
+
+  // Note that histograms could be separated out by this commit's transition
+  // type, but for simplicity they will all be bucketed together.
+  LogAbortChainSameURLHistogram(aborted_chain_size_same_url_);
+
+  ui::PageTransition committed_transition =
+      final_navigation->GetPageTransition();
   switch (AbortTypeForPageTransition(committed_transition)) {
     case ABORT_RELOAD:
       UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeReload,
@@ -256,11 +285,7 @@
   for (const auto& observer : observers_) {
     observer->OnCommit(navigation_handle);
   }
-  LogAbortChainHistograms(navigation_handle->GetPageTransition());
-  // Note that histograms could be separated out by this commit's transition
-  // type, but for simplicity they will all be bucketed together.
-  if (aborted_chain_size_same_url_ > 0)
-    LogAbortChainSameURLHistogram(aborted_chain_size_same_url_);
+  LogAbortChainHistograms(navigation_handle);
 }
 
 void PageLoadTracker::FailedProvisionalLoad(
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h
index ab17a8e..aaac42e6 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.h
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -36,6 +36,7 @@
 extern const char kAbortChainSizeReload[];
 extern const char kAbortChainSizeForwardBack[];
 extern const char kAbortChainSizeNewNavigation[];
+extern const char kAbortChainSizeNoCommit[];
 extern const char kAbortChainSizeSameURL[];
 
 }  // namespace internal
@@ -152,12 +153,17 @@
 
  private:
   PageLoadExtraInfo GetPageLoadMetricsInfo();
+
   // Only valid to call post-commit.
   const GURL& committed_url();
 
   void UpdateAbortInternal(UserAbortType abort_type,
                            base::TimeTicks timestamp);
-  void LogAbortChainHistograms(ui::PageTransition committed_transition);
+
+  // If |final_navigation| is null, then this is an "unparented" abort chain,
+  // and represents a sequence of provisional aborts that never ends with a
+  // committed load.
+  void LogAbortChainHistograms(content::NavigationHandle* final_navigation);
 
   // Whether the renderer should be sending timing IPCs to this page load.
   bool renderer_tracked_;
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
index 1978ec7..21c2a7c 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -339,4 +339,29 @@
   histogram_tester_.ExpectBucketCount(internal::kAbortChainSizeSameURL, 3, 1);
 }
 
+TEST_F(MetricsWebContentsObserverTest, LogAbortChainsNoCommit) {
+  content::WebContentsTester* web_contents_tester =
+      content::WebContentsTester::For(web_contents());
+  content::RenderFrameHostTester* rfh_tester =
+      content::RenderFrameHostTester::For(main_rfh());
+  // Start and abort three loads before one finally commits.
+  web_contents_tester->StartNavigation(GURL(kDefaultTestUrl));
+  rfh_tester->SimulateNavigationError(GURL(kDefaultTestUrl), net::ERR_ABORTED);
+  rfh_tester->SimulateNavigationStop();
+
+  web_contents_tester->StartNavigation(GURL(kDefaultTestUrl2));
+  rfh_tester->SimulateNavigationError(GURL(kDefaultTestUrl2), net::ERR_ABORTED);
+  rfh_tester->SimulateNavigationStop();
+
+  web_contents_tester->StartNavigation(GURL(kDefaultTestUrl));
+  rfh_tester->SimulateNavigationError(GURL(kDefaultTestUrl), net::ERR_ABORTED);
+  rfh_tester->SimulateNavigationStop();
+
+  web_contents()->Stop();
+
+  histogram_tester_.ExpectTotalCount(internal::kAbortChainSizeNoCommit, 1);
+  histogram_tester_.ExpectBucketCount(internal::kAbortChainSizeNoCommit, 3,
+                                      1);
+}
+
 }  // namespace page_load_metrics
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index fa1eb1be..9e781d5 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -1127,7 +1127,7 @@
     ScopedVector<autofill::PasswordForm>* forms) const {
   DCHECK(forms);
   // You *must* change LoginTableColumns if this query changes.
-  const std::string sql_query =
+  std::string sql_query =
       "SELECT origin_url, action_url, "
       "username_element, username_value, "
       "password_element, password_value, submit_element, "
@@ -1136,12 +1136,23 @@
       "date_synced, display_name, icon_url, "
       "federation_url, skip_zero_click, generation_upload_status "
       "FROM logins WHERE signon_realm == ? ";
-  sql::Statement s;
   const GURL signon_realm(form.signon_realm);
   std::string registered_domain = GetRegistryControlledDomain(signon_realm);
   const bool should_PSL_matching_apply =
       form.scheme == PasswordForm::SCHEME_HTML &&
       ShouldPSLDomainMatchingApply(registered_domain);
+  const bool should_federated_apply = form.scheme == PasswordForm::SCHEME_HTML;
+  if (should_PSL_matching_apply)
+    sql_query += "OR signon_realm REGEXP ? ";
+  if (should_federated_apply)
+    sql_query += "OR (signon_realm LIKE ? AND password_type == 2) ";
+
+  // TODO(nyquist) Consider usage of GetCachedStatement when
+  // http://crbug.com/248608 is fixed.
+  sql::Statement s(db_.GetUniqueStatement(sql_query.c_str()));
+  s.BindString(0, form.signon_realm);
+  int placeholder = 1;
+
   // PSL matching only applies to HTML forms.
   if (should_PSL_matching_apply) {
     // We are extending the original SQL query with one that includes more
@@ -1150,11 +1161,6 @@
     // in the |logins| table. The result (scheme, domain and port) is verified
     // further down using GURL. See the functions SchemeMatches,
     // RegistryControlledDomainMatches and PortMatches.
-    const std::string extended_sql_query =
-        sql_query + "OR signon_realm REGEXP ? ";
-    // TODO(nyquist) Re-enable usage of GetCachedStatement when
-    // http://crbug.com/248608 is fixed.
-    s.Assign(db_.GetUniqueStatement(extended_sql_query.c_str()));
     // We need to escape . in the domain. Since the domain has already been
     // sanitized using GURL, we do not need to escape any other characters.
     base::ReplaceChars(registered_domain, ".", "\\.", &registered_domain);
@@ -1170,18 +1176,24 @@
     // The scheme and port has to be the same as the observed form.
     std::string regexp = "^(" + scheme + ":\\/\\/)([\\w-]+\\.)*" +
                          registered_domain + "(:" + port + ")?\\/$";
-    s.BindString(0, form.signon_realm);
-    s.BindString(1, regexp);
-  } else {
+    s.BindString(placeholder++, regexp);
+  }
+  if (should_federated_apply) {
+    std::string expression =
+        base::StringPrintf("federation://%s/%%", form.origin.host().c_str());
+    s.BindString(placeholder++, expression);
+  }
+
+  if (!should_PSL_matching_apply && !should_federated_apply) {
+    // Otherwise the histogram is reported in StatementToForms.
     UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering",
                               PSL_DOMAIN_MATCH_NOT_USED,
                               PSL_DOMAIN_MATCH_COUNT);
-    s.Assign(db_.GetCachedStatement(SQL_FROM_HERE, sql_query.c_str()));
-    s.BindString(0, form.signon_realm);
   }
 
-  return StatementToForms(&s, should_PSL_matching_apply ? &form : nullptr,
-                          forms);
+  return StatementToForms(
+      &s, should_PSL_matching_apply || should_federated_apply ? &form : nullptr,
+      forms);
 }
 
 bool LoginDatabase::GetLoginsCreatedBetween(
@@ -1297,7 +1309,7 @@
 // static
 bool LoginDatabase::StatementToForms(
     sql::Statement* statement,
-    const autofill::PasswordForm* psl_match,
+    const autofill::PasswordForm* matched_form,
     ScopedVector<autofill::PasswordForm>* forms) {
   PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE;
 
@@ -1310,23 +1322,26 @@
       return false;
     if (result == ENCRYPTION_RESULT_ITEM_FAILURE)
       continue;
-    DCHECK(result == ENCRYPTION_RESULT_SUCCESS);
-    if (psl_match && psl_match->signon_realm != new_form->signon_realm) {
+    DCHECK_EQ(ENCRYPTION_RESULT_SUCCESS, result);
+    if (matched_form && matched_form->signon_realm != new_form->signon_realm) {
       if (new_form->scheme != PasswordForm::SCHEME_HTML)
         continue;  // Ignore non-HTML matches.
 
-      if (!IsPublicSuffixDomainMatch(new_form->signon_realm,
-                                     psl_match->signon_realm)) {
+      if (IsPublicSuffixDomainMatch(new_form->signon_realm,
+                                    matched_form->signon_realm)) {
+        psl_domain_match_metric = PSL_DOMAIN_MATCH_FOUND;
+        new_form->is_public_suffix_match = true;
+      } else if (!new_form->federation_origin.unique() &&
+                 IsFederatedMatch(new_form->signon_realm,
+                                  matched_form->origin)) {
+      } else {
         continue;
       }
-
-      psl_domain_match_metric = PSL_DOMAIN_MATCH_FOUND;
-      new_form->is_public_suffix_match = true;
     }
     forms->push_back(std::move(new_form));
   }
 
-  if (psl_match) {
+  if (matched_form) {
     UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering",
                               psl_domain_match_metric, PSL_DOMAIN_MATCH_COUNT);
   }
diff --git a/components/password_manager/core/browser/login_database.h b/components/password_manager/core/browser/login_database.h
index 3568fc3..c992f3e 100644
--- a/components/password_manager/core/browser/login_database.h
+++ b/components/password_manager/core/browser/login_database.h
@@ -83,7 +83,8 @@
   // All Get* methods below overwrite |forms| with the returned credentials. On
   // success, those methods return true.
 
-  // Gets a list of credentials matching |form|, including blacklisted matches.
+  // Gets a list of credentials matching |form|, including blacklisted matches
+  // and federated credentials.
   bool GetLogins(const autofill::PasswordForm& form,
                  ScopedVector<autofill::PasswordForm>* forms) const
       WARN_UNUSED_RESULT;
@@ -188,10 +189,10 @@
       ScopedVector<autofill::PasswordForm>* forms) const;
 
   // Overwrites |forms| with credentials retrieved from |statement|. If
-  // |psl_match| is not null, filters out all results but thos PSL-matching
-  // |*psl_match|. On success returns true.
+  // |matched_form| is not null, filters out all results but those PSL-matching
+  // |*matched_form| or federated credentials for it. On success returns true.
   static bool StatementToForms(sql::Statement* statement,
-                               const autofill::PasswordForm* psl_match,
+                               const autofill::PasswordForm* matched_form,
                                ScopedVector<autofill::PasswordForm>* forms);
 
   base::FilePath db_path_;
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 859aca1..46ba8f57 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -373,6 +373,52 @@
   result.clear();
 }
 
+TEST_F(LoginDatabaseTest, TestFederatedMatching) {
+  ScopedVector<autofill::PasswordForm> result;
+
+  // Example password form.
+  PasswordForm form;
+  form.origin = GURL("https://foo.com/");
+  form.action = GURL("https://foo.com/login");
+  form.username_value = ASCIIToUTF16("test@gmail.com");
+  form.password_value = ASCIIToUTF16("test");
+  form.signon_realm = "https://foo.com/";
+  form.ssl_valid = true;
+  form.preferred = false;
+  form.scheme = PasswordForm::SCHEME_HTML;
+
+  // We go to the mobile site.
+  PasswordForm form2(form);
+  form2.origin = GURL("https://mobile.foo.com/");
+  form2.action = GURL("https://mobile.foo.com/login");
+  form2.signon_realm = "federation://mobile.foo.com/accounts.google.com";
+  form2.username_value = ASCIIToUTF16("test1@gmail.com");
+  form2.type = autofill::PasswordForm::TYPE_API;
+  form2.federation_origin = url::Origin(GURL("https://accounts.google.com/"));
+
+  // Add it and make sure it is there.
+  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
+  EXPECT_EQ(AddChangeForForm(form2), db().AddLogin(form2));
+  EXPECT_TRUE(db().GetAutofillableLogins(&result));
+  EXPECT_EQ(2U, result.size());
+
+  // Match against desktop.
+  PasswordForm form_request;
+  form_request.origin = GURL("https://foo.com/");
+  form_request.signon_realm = "https://foo.com/";
+  form_request.scheme = PasswordForm::SCHEME_HTML;
+  EXPECT_TRUE(db().GetLogins(form_request, &result));
+  EXPECT_THAT(result, testing::ElementsAre(testing::Pointee(form)));
+
+  // Match against the mobile site.
+  form_request.origin = GURL("https://mobile.foo.com/");
+  form_request.signon_realm = "https://mobile.foo.com/";
+  EXPECT_TRUE(db().GetLogins(form_request, &result));
+  form.is_public_suffix_match = true;
+  EXPECT_THAT(result, testing::UnorderedElementsAre(testing::Pointee(form),
+                                                    testing::Pointee(form2)));
+}
+
 TEST_F(LoginDatabaseTest, TestPublicSuffixDisabledForNonHTMLForms) {
   TestNonHTMLFormPSLMatching(PasswordForm::SCHEME_BASIC);
   TestNonHTMLFormPSLMatching(PasswordForm::SCHEME_DIGEST);
@@ -435,10 +481,60 @@
 
   // Match against the other site. Should not match since feature should not be
   // enabled for this domain.
+  ASSERT_FALSE(ShouldPSLDomainMatchingApply(
+      GetRegistryControlledDomain(GURL(form2.signon_realm))));
+
   EXPECT_TRUE(db().GetLogins(form2, &result));
   EXPECT_EQ(0U, result.size());
 }
 
+TEST_F(LoginDatabaseTest, TestFederatedMatchingWithoutPSLMatching) {
+  ScopedVector<autofill::PasswordForm> result;
+
+  // Example password form.
+  PasswordForm form;
+  form.origin = GURL("https://accounts.google.com/");
+  form.action = GURL("https://accounts.google.com/login");
+  form.username_value = ASCIIToUTF16("test@gmail.com");
+  form.password_value = ASCIIToUTF16("test");
+  form.signon_realm = "https://accounts.google.com/";
+  form.ssl_valid = true;
+  form.preferred = false;
+  form.scheme = PasswordForm::SCHEME_HTML;
+
+  // We go to a different site on the same domain where PSL is disabled.
+  PasswordForm form2(form);
+  form2.origin = GURL("https://some.other.google.com/");
+  form2.action = GURL("https://some.other.google.com/login");
+  form2.signon_realm = "federation://some.other.google.com/accounts.google.com";
+  form2.username_value = ASCIIToUTF16("test1@gmail.com");
+  form2.type = autofill::PasswordForm::TYPE_API;
+  form2.federation_origin = url::Origin(GURL("https://accounts.google.com/"));
+
+  // Add it and make sure it is there.
+  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
+  EXPECT_EQ(AddChangeForForm(form2), db().AddLogin(form2));
+  EXPECT_TRUE(db().GetAutofillableLogins(&result));
+  EXPECT_EQ(2U, result.size());
+
+  // Match against the first one.
+  PasswordForm form_request;
+  form_request.origin = form.origin;
+  form_request.signon_realm = form.signon_realm;
+  form_request.scheme = PasswordForm::SCHEME_HTML;
+  EXPECT_TRUE(db().GetLogins(form_request, &result));
+  EXPECT_THAT(result, testing::ElementsAre(testing::Pointee(form)));
+
+  // Match against the second one.
+  ASSERT_FALSE(ShouldPSLDomainMatchingApply(
+      GetRegistryControlledDomain(GURL(form2.signon_realm))));
+  form_request.origin = form2.origin;
+  form_request.signon_realm = form2.signon_realm;
+  EXPECT_TRUE(db().GetLogins(form_request, &result));
+  form.is_public_suffix_match = true;
+  EXPECT_THAT(result, testing::ElementsAre(testing::Pointee(form2)));
+}
+
 // This test fails if the implementation of GetLogins uses GetCachedStatement
 // instead of GetUniqueStatement, since REGEXP is in use. See
 // http://crbug.com/248608.
diff --git a/components/password_manager/core/browser/psl_matching_helper.cc b/components/password_manager/core/browser/psl_matching_helper.cc
index 2f7f9d6f..5482feb 100644
--- a/components/password_manager/core/browser/psl_matching_helper.cc
+++ b/components/password_manager/core/browser/psl_matching_helper.cc
@@ -7,6 +7,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/strings/string_util.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/common/password_manager_switches.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -49,4 +50,12 @@
       net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
 }
 
+bool IsFederatedMatch(const std::string& signon_realm, const GURL& origin) {
+  // The format should be "federation://origin.host/federation.host;
+  std::string federated_realm = "federation://" + origin.host() + "/";
+  return signon_realm.size() > federated_realm.size() &&
+         base::StartsWith(signon_realm, federated_realm,
+                          base::CompareCase::INSENSITIVE_ASCII);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/psl_matching_helper.h b/components/password_manager/core/browser/psl_matching_helper.h
index 9e9a10e..22071b60 100644
--- a/components/password_manager/core/browser/psl_matching_helper.h
+++ b/components/password_manager/core/browser/psl_matching_helper.h
@@ -44,6 +44,10 @@
 // registry-controlled domain part.
 std::string GetRegistryControlledDomain(const GURL& signon_realm);
 
+// Returns true iff |signon_realm| designates a federated credential for the
+// |origin|.
+bool IsFederatedMatch(const std::string& signon_realm, const GURL& origin);
+
 }  // namespace password_manager
 
 #endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PSL_MATCHING_HELPER_H_
diff --git a/components/password_manager/core/browser/psl_matching_helper_unittest.cc b/components/password_manager/core/browser/psl_matching_helper_unittest.cc
index 01f4e8a..68381d2c 100644
--- a/components/password_manager/core/browser/psl_matching_helper_unittest.cc
+++ b/components/password_manager/core/browser/psl_matching_helper_unittest.cc
@@ -21,7 +21,7 @@
     bool should_match;
   };
 
-  TestPair pairs[] = {
+  const TestPair pairs[] = {
       {"http://facebook.com", "http://facebook.com", true},
       {"http://facebook.com/path", "http://facebook.com/path", true},
       {"http://facebook.com/path1", "http://facebook.com/path2", true},
@@ -44,17 +44,45 @@
       {"", "http://www.example.com", false},
       {"http://www.example.com", "bad url", false},
       {"http://www.example.com/%00", "http://www.example.com/%00", false},
+      {"federation://example.com/google.com", "https://example.com/", false},
   };
 
-  for (size_t i = 0; i < arraysize(pairs); ++i) {
+  for (const TestPair& pair : pairs) {
     autofill::PasswordForm form1;
-    form1.signon_realm = pairs[i].url1;
+    form1.signon_realm = pair.url1;
     autofill::PasswordForm form2;
-    form2.signon_realm = pairs[i].url2;
-    EXPECT_EQ(pairs[i].should_match,
+    form2.signon_realm = pair.url2;
+    EXPECT_EQ(pair.should_match,
               IsPublicSuffixDomainMatch(form1.signon_realm, form2.signon_realm))
-        << "First URL = " << pairs[i].url1
-        << ", second URL = " << pairs[i].url2;
+        << "First URL = " << pair.url1 << ", second URL = " << pair.url2;
+  }
+}
+
+TEST(PSLMatchingUtilsTest, IsFederatedMatch) {
+  struct TestPair {
+    const char* signon_realm;
+    const char* origin;
+    bool should_match;
+  };
+
+  const TestPair pairs[] = {
+      {"https://facebook.com", "https://facebook.com", false},
+      {"", "", false},
+      {"", "https://facebook.com/", false},
+      {"https://facebook.com/", "", false},
+      {"federation://example.com/google.com", "https://example.com/", true},
+      {"federation://example.com/google.com", "http://example.com/", true},
+      {"federation://example.com/google.com", "example.com", false},
+      {"federation://example.com/", "http://example.com/", false},
+      {"federation://example.com/google.com", "example", false},
+  };
+
+  for (const TestPair& pair : pairs) {
+    std::string signon_realm = pair.signon_realm;
+    GURL origin(pair.origin);
+    EXPECT_EQ(pair.should_match, IsFederatedMatch(signon_realm, origin))
+        << "signon_realm = " << pair.signon_realm
+        << ", origin = " << pair.origin;
   }
 }
 
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc
index 05611db..5075df3 100644
--- a/components/plugins/renderer/webview_plugin.cc
+++ b/components/plugins/renderer/webview_plugin.cc
@@ -134,8 +134,8 @@
     // scheduleAnimation, but due to timers controlling widget update,
     // scheduleAnimation may be invoked before this initialize call (which
     // comes through the widget update process). It doesn't hurt to mark
-    // for layout again, and it does help us in the race-condition situation.
-    container_->setNeedsLayout();
+    // for animation again, and it does help us in the race-condition situation.
+    container_->scheduleAnimation();
 
     old_title_ = container_->element().getAttribute("title");
 
@@ -164,9 +164,7 @@
   return delegate_->GetV8ScriptableObject(isolate);
 }
 
-// TODO(wkorman): Look into renaming this to something more in line with
-// either the Blink lifecycle or Compositor layer tree host nomenclature.
-void WebViewPlugin::layoutIfNeeded() {
+void WebViewPlugin::updateAllLifecyclePhases() {
   web_view_->updateAllLifecyclePhases();
 }
 
@@ -313,7 +311,7 @@
   if (container_) {
     // This should never happen; see also crbug.com/545039 for context.
     CHECK(!is_painting_);
-    container_->setNeedsLayout();
+    container_->scheduleAnimation();
   }
 }
 
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h
index 4f86b6d..a703816 100644
--- a/components/plugins/renderer/webview_plugin.h
+++ b/components/plugins/renderer/webview_plugin.h
@@ -88,7 +88,7 @@
 
   v8::Local<v8::Object> v8ScriptableObject(v8::Isolate* isolate) override;
 
-  void layoutIfNeeded() override;
+  void updateAllLifecyclePhases() override;
   void paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override;
 
   // Coordinates are relative to the containing window.
diff --git a/components/policy/core/common/cloud/system_policy_request_context.cc b/components/policy/core/common/cloud/system_policy_request_context.cc
index 488fd25..c4cb570 100644
--- a/components/policy/core/common/cloud/system_policy_request_context.cc
+++ b/components/policy/core/common/cloud/system_policy_request_context.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "base/single_thread_task_runner.h"
 #include "net/cookies/cookie_monster.h"
+#include "net/cookies/cookie_store.h"
 #include "net/http/http_network_layer.h"
 #include "net/url_request/url_request_context.h"
 
@@ -56,9 +57,11 @@
         system_context->http_transaction_factory()->GetSession()));
     context_->set_http_transaction_factory(http_transaction_factory_.get());
 
+    cookie_store_.reset(new net::CookieMonster(NULL, NULL));
+
     // No cookies, please. We also don't track channel IDs (no
     // ChannelIDService).
-    context_->set_cookie_store(new net::CookieMonster(NULL, NULL));
+    context_->set_cookie_store(cookie_store_.get());
   }
 
   return context_.get();
diff --git a/components/policy/core/common/cloud/system_policy_request_context.h b/components/policy/core/common/cloud/system_policy_request_context.h
index 24f19dc..7aaeeda7 100644
--- a/components/policy/core/common/cloud/system_policy_request_context.h
+++ b/components/policy/core/common/cloud/system_policy_request_context.h
@@ -12,6 +12,7 @@
 #define COMPONENTS_POLICY_CORE_COMMON_CLOUD_SYSTEM_POLICY_REQUEST_CONTEXT_H_
 
 namespace net {
+class CookieStore;
 class HttpNetworkLayer;
 }
 
@@ -35,13 +36,16 @@
  private:
   scoped_refptr<net::URLRequestContextGetter> system_context_getter_;
 
-  // The lazy-initialized URLRequestContext associated with this getter.
-  scoped_ptr<net::URLRequestContext> context_;
-
   // HttpNetworkLayer associated with |context_|.
   scoped_ptr<net::HttpNetworkLayer> http_transaction_factory_;
 
+  scoped_ptr<net::CookieStore> cookie_store_;
+
   net::StaticHttpUserAgentSettings http_user_agent_settings_;
+
+  // The lazy-initialized URLRequestContext associated with this getter.
+  scoped_ptr<net::URLRequestContext> context_;
+
   DISALLOW_COPY_AND_ASSIGN(SystemPolicyRequestContext);
 };
 
diff --git a/components/ssl_config/ssl_config_service_manager_pref.cc b/components/ssl_config/ssl_config_service_manager_pref.cc
index af1cd09..fe1e2434c 100644
--- a/components/ssl_config/ssl_config_service_manager_pref.cc
+++ b/components/ssl_config/ssl_config_service_manager_pref.cc
@@ -11,8 +11,8 @@
 
 #include "base/bind.h"
 #include "base/feature_list.h"
+#include "base/location.h"
 #include "base/macros.h"
-#include "base/metrics/field_trial.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
@@ -83,12 +83,6 @@
   return version;
 }
 
-bool IsRC4EnabledByDefault() {
-  const std::string group_name =
-      base::FieldTrialList::FindFullName("RC4Ciphers");
-  return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
-}
-
 const base::Feature kSSLVersionFallbackTLSv11 {
     "SSLVersionFallbackTLSv1.1", base::FEATURE_DISABLED_BY_DEFAULT,
 };
@@ -198,10 +192,6 @@
       io_task_runner_(io_task_runner) {
   DCHECK(local_state);
 
-  local_state->SetDefaultPrefValue(
-      ssl_config::prefs::kRC4Enabled,
-      new base::FundamentalValue(IsRC4EnabledByDefault()));
-
   // Restore the TLS 1.1 fallback leg if enabled via features.
   // TODO(davidben): Remove this when the fallback removal has succeeded.
   // https://crbug.com/536200.
diff --git a/components/sync_driver/device_info_service.cc b/components/sync_driver/device_info_service.cc
index 8702864..6a63dcb 100644
--- a/components/sync_driver/device_info_service.cc
+++ b/components/sync_driver/device_info_service.cc
@@ -4,6 +4,7 @@
 
 #include "components/sync_driver/device_info_service.h"
 
+#include <set>
 #include <utility>
 #include <vector>
 
@@ -69,8 +70,59 @@
 SyncError DeviceInfoService::MergeSyncData(
     scoped_ptr<MetadataChangeList> metadata_change_list,
     EntityDataMap entity_data_map) {
-  // TODO(skym): crbug.com/543406: Implementation.
-  return SyncError();
+  if (!has_provider_initialized_ || !has_data_loaded_ || !change_processor()) {
+    return SyncError(
+        FROM_HERE, SyncError::DATATYPE_ERROR,
+        "Cannot call MergeSyncData without provider, data, and processor.",
+        syncer::DEVICE_INFO);
+  }
+
+  // Local data should typically be near empty, with the only possible value
+  // corresponding to this device. This is because on signout all device info
+  // data is blown away. However, this simplification is being ignored here and
+  // a full difference is going to be calculated to explore what other service
+  // implementations may look like.
+  std::set<std::string> local_only_tags;
+  for (const auto& kv : all_data_) {
+    local_only_tags.insert(kv.first);
+  }
+
+  bool has_changes = false;
+  std::string local_tag =
+      local_device_info_provider_->GetLocalDeviceInfo()->guid();
+  scoped_ptr<WriteBatch> batch = store_->CreateWriteBatch();
+  for (const auto& kv : entity_data_map) {
+    const std::string tag = GetClientTag(kv.second.value());
+    const DeviceInfoSpecifics& specifics =
+        kv.second.value().specifics.device_info();
+
+    // Ignore any remote changes that have our local cache guid.
+    if (tag == local_tag) {
+      continue;
+    }
+
+    // Remote data wins conflicts.
+    local_only_tags.erase(tag);
+    StoreSpecifics(make_scoped_ptr(new DeviceInfoSpecifics(specifics)),
+                   batch.get());
+    has_changes = true;
+  }
+
+  for (const std::string& tag : local_only_tags) {
+    change_processor()->Put(tag, CopyIntoNewEntityData(*all_data_[tag]),
+                            metadata_change_list.get());
+  }
+
+  // Transfer at the end because processor Put calls may update metadata.
+  static_cast<SimpleMetadataChangeList*>(metadata_change_list.get())
+      ->TransferChanges(store_.get(), batch.get());
+  store_->CommitWriteBatch(
+      std::move(batch),
+      base::Bind(&DeviceInfoService::OnCommit, weak_factory_.GetWeakPtr()));
+  if (has_changes) {
+    NotifyObservers();
+  }
+  return syncer::SyncError();
 }
 
 SyncError DeviceInfoService::ApplySyncChanges(
@@ -128,8 +180,8 @@
 
   syncer::SyncError error;
   scoped_ptr<DataBatchImpl> batch(new DataBatchImpl());
-  for (auto& tag : client_tags) {
-    auto iter = all_data_.find(tag);
+  for (const auto& tag : client_tags) {
+    const auto iter = all_data_.find(tag);
     if (iter != all_data_.end()) {
       batch->Put(tag, CopyIntoNewEntityData(*iter->second));
     }
@@ -148,7 +200,7 @@
 
   syncer::SyncError error;
   scoped_ptr<DataBatchImpl> batch(new DataBatchImpl());
-  for (auto& kv : all_data_) {
+  for (const auto& kv : all_data_) {
     batch->Put(kv.first, CopyIntoNewEntityData(*kv.second));
   }
   callback.Run(error, std::move(batch));
@@ -169,7 +221,7 @@
 
 scoped_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo(
     const std::string& client_id) const {
-  ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id);
+  const ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id);
   if (iter == all_data_.end()) {
     return scoped_ptr<DeviceInfo>();
   }
diff --git a/components/sync_driver/device_info_service_unittest.cc b/components/sync_driver/device_info_service_unittest.cc
index ccaa692..4cd69c6 100644
--- a/components/sync_driver/device_info_service_unittest.cc
+++ b/components/sync_driver/device_info_service_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/strings/stringprintf.h"
 #include "components/sync_driver/local_device_info_provider_mock.h"
 #include "sync/api/data_batch.h"
+#include "sync/api/entity_data.h"
 #include "sync/api/metadata_batch.h"
 #include "sync/api/model_type_store.h"
 #include "sync/internal_api/public/test/model_type_store_test_util.h"
@@ -29,6 +30,7 @@
 using syncer_v2::EntityChange;
 using syncer_v2::EntityChangeList;
 using syncer_v2::EntityData;
+using syncer_v2::EntityDataMap;
 using syncer_v2::EntityDataPtr;
 using syncer_v2::MetadataBatch;
 using syncer_v2::MetadataChangeList;
@@ -97,6 +99,18 @@
   ASSERT_TRUE(expected.empty());
 }
 
+// Creats an EntityData/EntityDataPtr around a copy of the given specifics.
+EntityDataPtr SpecificsToEntity(const DeviceInfoSpecifics& specifics) {
+  EntityData data;
+  // These tests do not care about the tag hash, but EntityData and friends
+  // cannot differentiate between the default EntityData object if the hash
+  // is unset, which causes pass/copy operations to no-op and things start to
+  // break, so we throw in a junk value and forget about it.
+  data.client_tag_hash = "junk";
+  *data.specifics.mutable_device_info() = specifics;
+  return data.PassToPtr();
+}
+
 // Instead of actually processing anything, simply accumulates all instructions
 // in members that can then be accessed. TODO(skym): If this ends up being
 // useful for other model type unittests it should be moved out to a shared
@@ -206,6 +220,13 @@
     return specifics;
   }
 
+  // Override to allow specific cache guids.
+  DeviceInfoSpecifics GenerateTestSpecifics(const std::string& guid) {
+    DeviceInfoSpecifics specifics(GenerateTestSpecifics());
+    specifics.set_cache_guid(guid);
+    return specifics;
+  }
+
   // Helper method to reduce duplicated code between tests. Wraps the given
   // specifics object in an EntityData and EntityChange of type ACTION_ADD, and
   // pushes them onto the given change list. The corresponding client tag the
@@ -213,15 +234,9 @@
   // service to generate the tag.
   std::string PushBackEntityChangeAdd(const DeviceInfoSpecifics& specifics,
                                       EntityChangeList* changes) {
-    EntityData data;
-    // These tests do not care about the tag hash, but EntityData and friends
-    // cannot differentiate between the default EntityData object if the hash
-    // is unset, which causes pass/copy operations to no-op and things start to
-    // break, so we throw in a junk value and forget about it.
-    data.client_tag_hash = "junk";
-    *data.specifics.mutable_device_info() = specifics;
-    const std::string tag = service()->GetClientTag(data);
-    changes->push_back(EntityChange::CreateAdd(tag, data.PassToPtr()));
+    EntityDataPtr ptr = SpecificsToEntity(specifics);
+    const std::string tag = service()->GetClientTag(ptr.value());
+    changes->push_back(EntityChange::CreateAdd(tag, ptr));
     return tag;
   }
 
@@ -537,8 +552,8 @@
   // The point of this test is to try to apply remote changes that have the same
   // cache guid as the local device. The service should ignore these changes
   // since only it should be performing writes on its data.
-  DeviceInfoSpecifics specifics = GenerateTestSpecifics();
-  specifics.set_cache_guid(local_device()->GetLocalDeviceInfo()->guid());
+  DeviceInfoSpecifics specifics =
+      GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid());
 
   EntityChangeList data_changes;
   const std::string tag = PushBackEntityChangeAdd(specifics, &data_changes);
@@ -560,6 +575,94 @@
   EXPECT_EQ(0, change_count());
 }
 
+TEST_F(DeviceInfoServiceTest, MergeBeforeInit) {
+  InitializeService();
+  const SyncError error = service()->MergeSyncData(
+      service()->CreateMetadataChangeList(), EntityDataMap());
+  EXPECT_TRUE(error.IsSet());
+  EXPECT_EQ(0, change_count());
+}
+
+TEST_F(DeviceInfoServiceTest, MergeEmpty) {
+  InitializeAndPump();
+  SetProcessorAndPump();
+  const SyncError error = service()->MergeSyncData(
+      service()->CreateMetadataChangeList(), EntityDataMap());
+  EXPECT_FALSE(error.IsSet());
+  EXPECT_EQ(0, change_count());
+}
+
+TEST_F(DeviceInfoServiceTest, MergeWithData) {
+  const DeviceInfoSpecifics unique_local(GenerateTestSpecifics("unique_local"));
+  const DeviceInfoSpecifics conflict_local(GenerateTestSpecifics("conflict"));
+  DeviceInfoSpecifics conflict_remote(GenerateTestSpecifics("conflict"));
+  DeviceInfoSpecifics unique_remote(GenerateTestSpecifics("unique_remote"));
+
+  scoped_ptr<WriteBatch> batch = store()->CreateWriteBatch();
+  store()->WriteData(batch.get(), unique_local.cache_guid(),
+                     unique_local.SerializeAsString());
+  store()->WriteData(batch.get(), conflict_local.cache_guid(),
+                     conflict_local.SerializeAsString());
+  store()->CommitWriteBatch(std::move(batch),
+                            base::Bind(&AssertResultIsSuccess));
+
+  InitializeAndPump();
+  SetProcessorAndPump();
+
+  EntityDataMap remote_input;
+  remote_input[conflict_remote.cache_guid()] =
+      SpecificsToEntity(conflict_remote);
+  remote_input[unique_remote.cache_guid()] = SpecificsToEntity(unique_remote);
+
+  DataTypeState state;
+  state.set_encryption_key_name("ekn");
+  scoped_ptr<MetadataChangeList> metadata_changes(
+      service()->CreateMetadataChangeList());
+  metadata_changes->UpdateDataTypeState(state);
+
+  const SyncError error =
+      service()->MergeSyncData(std::move(metadata_changes), remote_input);
+  EXPECT_FALSE(error.IsSet());
+  EXPECT_EQ(1, change_count());
+
+  // The remote should beat the local in conflict.
+  EXPECT_EQ(3u, service()->GetAllDeviceInfo().size());
+  AssertEqual(unique_local, *service()->GetDeviceInfo("unique_local").get());
+  AssertEqual(unique_remote, *service()->GetDeviceInfo("unique_remote").get());
+  AssertEqual(conflict_remote, *service()->GetDeviceInfo("conflict").get());
+
+  // Service should have told the processor about the existance of unique_local.
+  EXPECT_TRUE(processor()->delete_set().empty());
+  EXPECT_EQ(1u, processor()->put_map().size());
+  const auto& it = processor()->put_map().find("unique_local");
+  ASSERT_NE(processor()->put_map().end(), it);
+  AssertEqual(unique_local, it->second->specifics.device_info());
+
+  // TODO(skym): Uncomment once SimpleMetadataChangeList::TransferChanges is
+  // implemented.
+  // ASSERT_EQ(state.encryption_key_name(),
+  // processor()->metadata()->GetDataTypeState().encryption_key_name());
+}
+
+TEST_F(DeviceInfoServiceTest, MergeLocalGuid) {
+  InitializeAndPump();
+  SetProcessorAndPump();
+
+  // Service should ignore this because it uses the local device's guid.
+  DeviceInfoSpecifics specifics(
+      GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid()));
+  EntityDataMap remote_input;
+  remote_input[specifics.cache_guid()] = SpecificsToEntity(specifics);
+
+  const SyncError error = service()->MergeSyncData(
+      service()->CreateMetadataChangeList(), remote_input);
+  EXPECT_FALSE(error.IsSet());
+  EXPECT_EQ(0, change_count());
+  EXPECT_TRUE(service()->GetAllDeviceInfo().empty());
+  EXPECT_TRUE(processor()->delete_set().empty());
+  EXPECT_TRUE(processor()->put_map().empty());
+}
+
 }  // namespace
 
 }  // namespace sync_driver_v2
diff --git a/components/test_runner/test_plugin.h b/components/test_runner/test_plugin.h
index 55c28322..65b60e4 100644
--- a/components/test_runner/test_plugin.h
+++ b/components/test_runner/test_plugin.h
@@ -63,7 +63,7 @@
   NPObject* scriptableObject() override;
   bool canProcessDrag() const override;
   bool supportsKeyboardFocus() const override;
-  void layoutIfNeeded() override {}
+  void updateAllLifecyclePhases() override {}
   void paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override {}
   void updateGeometry(const blink::WebRect& window_rect,
                       const blink::WebRect& clip_rect,
diff --git a/content/browser/android/synchronous_compositor_base.cc b/content/browser/android/synchronous_compositor_base.cc
index 1ef5e861..39d8b24 100644
--- a/content/browser/android/synchronous_compositor_base.cc
+++ b/content/browser/android/synchronous_compositor_base.cc
@@ -25,10 +25,10 @@
     g_gpu_service = LAZY_INSTANCE_INITIALIZER;
 
 base::Thread* CreateInProcessGpuThreadForSynchronousCompositor(
-    const InProcessChildThreadParams& params) {
+    const InProcessChildThreadParams& params,
+    const gpu::GpuPreferences& gpu_preferences) {
   DCHECK(g_gpu_service.Get());
-  return new InProcessGpuThread(params,
-                                g_gpu_service.Get()->gpu_preferences(),
+  return new InProcessGpuThread(params, gpu_preferences,
                                 g_gpu_service.Get()->sync_point_manager());
 }
 
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
index 257f71a..47205b6 100644
--- a/content/browser/child_process_launcher.cc
+++ b/content/browser/child_process_launcher.cc
@@ -160,10 +160,12 @@
   DCHECK(mojo_fd.is_valid());
 
 #if defined(OS_ANDROID)
-  files_to_register->Share(kPrimaryIPCChannel, ipcfd.get());
+  if (ipcfd.get() != -1)
+    files_to_register->Share(kPrimaryIPCChannel, ipcfd.get());
   files_to_register->Share(kMojoIPCChannel, mojo_fd.get());
 #else
-  files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd));
+  if (ipcfd.get() != -1)
+    files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd));
   files_to_register->Transfer(kMojoIPCChannel, std::move(mojo_fd));
 #endif
 #endif
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index f9b793f..7ef7ca4 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -14,6 +14,7 @@
 #include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/navigator.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/frame_host/traced_frame_tree_node.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/common/frame_messages.h"
 #include "content/common/site_isolation_policy.h"
@@ -105,6 +106,12 @@
       g_frame_tree_node_id_map.Get().insert(
           std::make_pair(frame_tree_node_id_, this));
   CHECK(result.second);
+
+  TRACE_EVENT_OBJECT_CREATED_WITH_ID(
+      "navigation", "FrameTreeNode",
+      TRACE_ID_WITH_SCOPE("FrameTreeNode", frame_tree_node_id_));
+  TraceSnapshot();
+  base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
 }
 
 FrameTreeNode::~FrameTreeNode() {
@@ -116,6 +123,11 @@
     opener_->RemoveObserver(opener_observer_.get());
 
   g_frame_tree_node_id_map.Get().erase(frame_tree_node_id_);
+
+  TRACE_EVENT_OBJECT_DELETED_WITH_ID(
+      "navigation", "FrameTreeNode",
+      TRACE_ID_WITH_SCOPE("FrameTreeNode", frame_tree_node_id_));
+  base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
 }
 
 void FrameTreeNode::AddObserver(Observer* observer) {
@@ -172,6 +184,7 @@
 
 void FrameTreeNode::ResetForNewProcess() {
   current_frame_host()->set_last_committed_url(GURL());
+  TraceSnapshot();
 
   // Remove child nodes from the tree, then delete them. This destruction
   // operation will notify observers.
@@ -197,6 +210,7 @@
   if (!has_committed_real_load_ && url != GURL(url::kAboutBlankURL))
     has_committed_real_load_ = true;
   current_frame_host()->set_last_committed_url(url);
+  TraceSnapshot();
 }
 
 void FrameTreeNode::SetCurrentOrigin(const url::Origin& origin) {
@@ -448,4 +462,16 @@
   }
 }
 
+void FrameTreeNode::OnTraceLogEnabled() {
+  TraceSnapshot();
+}
+
+void FrameTreeNode::TraceSnapshot() const {
+  TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
+      "navigation", "FrameTreeNode",
+      TRACE_ID_WITH_SCOPE("FrameTreeNode", frame_tree_node_id_),
+      scoped_ptr<base::trace_event::ConvertableToTraceFormat>(
+          new TracedFrameTreeNode(*this)));
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h
index c108da5..fda8ecd 100644
--- a/content/browser/frame_host/frame_tree_node.h
+++ b/content/browser/frame_host/frame_tree_node.h
@@ -32,7 +32,8 @@
 // of those frames. We are mirroring this tree in the browser process. This
 // class represents a node in this tree and is a wrapper for all objects that
 // are frame-specific (as opposed to page-specific).
-class CONTENT_EXPORT FrameTreeNode {
+class CONTENT_EXPORT FrameTreeNode :
+  public base::trace_event::TraceLog::EnabledStateObserver {
  public:
   class Observer {
    public:
@@ -64,7 +65,7 @@
                 const std::string& unique_name,
                 const blink::WebFrameOwnerProperties& frame_owner_properties);
 
-  ~FrameTreeNode();
+  ~FrameTreeNode() override;
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
@@ -267,11 +268,17 @@
   // FrameTreeNode.
   void BeforeUnloadCanceled();
 
+  // TraceLog::EnabledStateObserver
+  void OnTraceLogEnabled() override;
+  void OnTraceLogDisabled() override {}
+
  private:
   class OpenerDestroyedObserver;
 
   void set_parent(FrameTreeNode* parent) { parent_ = parent; }
 
+  void TraceSnapshot() const;
+
   // The next available browser-global FrameTreeNode ID.
   static int next_frame_tree_node_id_;
 
diff --git a/content/browser/frame_host/traced_frame_tree_node.cc b/content/browser/frame_host/traced_frame_tree_node.cc
new file mode 100644
index 0000000..fc27dc5d
--- /dev/null
+++ b/content/browser/frame_host/traced_frame_tree_node.cc
@@ -0,0 +1,76 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/traced_frame_tree_node.h"
+
+#include "base/command_line.h"
+#include "base/json/json_writer.h"
+#include "base/strings/stringprintf.h"
+#include "content/browser/frame_host/frame_tree.h"
+#include "content/public/common/content_switches.h"
+#include "url/gurl.h"
+
+namespace content {
+
+TracedFrameTreeNode::TracedFrameTreeNode(const FrameTreeNode& node)
+    : parent_node_id_(-1),
+      process_id_(-1),
+      routing_id_(-1) {
+  FrameTreeNode* parent = node.parent();
+  if (parent)
+    parent_node_id_ = parent->frame_tree_node_id();
+
+  RenderFrameHostImpl* current_frame_host = node.current_frame_host();
+  if (!current_frame_host)
+    return;
+
+  if (current_frame_host->last_committed_url().is_valid())
+    url_ = current_frame_host->last_committed_url().spec();
+
+  base::ProcessHandle process_handle =
+    current_frame_host->GetProcess()->GetHandle();
+  if (process_handle == base::kNullProcessHandle)
+    return;
+
+  // On Windows, |rph->GetHandle()| does not duplicate ownership
+  // of the process handle and the render host still retains it. Therefore, we
+  // cannot create a base::Process object, which provides a proper way to get a
+  // process id, from the handle. For a stopgap, we use this deprecated
+  // function that does not require the ownership (http://crbug.com/417532).
+  process_id_ = base::GetProcId(process_handle);
+
+  routing_id_ = current_frame_host->GetRoutingID();
+  DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
+}
+
+TracedFrameTreeNode::~TracedFrameTreeNode() {
+}
+
+void TracedFrameTreeNode::AppendAsTraceFormat(std::string* out) const {
+  scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
+
+  if (parent_node_id_ >= 0) {
+    scoped_ptr<base::DictionaryValue> ref(new base::DictionaryValue());
+    ref->SetString("id_ref", base::StringPrintf("0x%x", parent_node_id_));
+    ref->SetString("scope", "FrameTreeNode");
+    value->Set("parent", std::move(ref));
+  }
+
+  if (process_id_ >= 0) {
+    scoped_ptr<base::DictionaryValue> ref(new base::DictionaryValue());
+    ref->SetInteger("pid_ref", process_id_);
+    ref->SetString("id_ref", base::StringPrintf("0x%x", routing_id_));
+    ref->SetString("scope", "RenderFrame");
+    value->Set("RenderFrame", std::move(ref));
+  }
+
+  if (!url_.empty())
+    value->SetString("url", url_);
+
+  std::string tmp;
+  base::JSONWriter::Write(*value, &tmp);
+  *out += tmp;
+}
+
+}  // content
diff --git a/content/browser/frame_host/traced_frame_tree_node.h b/content/browser/frame_host/traced_frame_tree_node.h
new file mode 100644
index 0000000..79c2a80
--- /dev/null
+++ b/content/browser/frame_host/traced_frame_tree_node.h
@@ -0,0 +1,36 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
+#include "base/trace_event/trace_event_impl.h"
+#include "base/values.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class FrameTree;
+class FrameTreeNode;
+
+// This is a temporary container used when tracing snapshots of FrameTree
+// objects. When a snapshot of a FrameTree is taken, a TracedFrameTreeNode is
+// created and stored by the tracing system until the trace is dumped.
+class CONTENT_EXPORT TracedFrameTreeNode :
+  public base::trace_event::ConvertableToTraceFormat {
+ public:
+  TracedFrameTreeNode(const FrameTreeNode& node);
+  void AppendAsTraceFormat(std::string* out) const override;
+
+ private:
+  ~TracedFrameTreeNode() override;
+
+  int parent_node_id_;
+  std::string url_;
+  int process_id_;
+  int routing_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(TracedFrameTreeNode);
+};
+
+}  // content
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 3433b55..b15d0db 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -36,6 +36,7 @@
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/gpu_utils.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
@@ -44,6 +45,7 @@
 #include "content/public/common/result_codes.h"
 #include "content/public/common/sandbox_type.h"
 #include "content/public/common/sandboxed_process_launcher_delegate.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_switches.h"
@@ -105,7 +107,6 @@
 #endif
   switches::kEnableHeapProfiling,
   switches::kEnableLogging,
-  switches::kEnableShareGroupAsyncTextureUpload,
 #if defined(OS_ANDROID)
   switches::kEnableUnifiedMediaPipeline,
 #endif
@@ -134,9 +135,6 @@
   switches::kEnableSandboxLogging,
   switches::kShowMacOverlayBorders,
 #endif
-#if defined(USE_AURA)
-  switches::kUIPrioritizeInGpuProcess,
-#endif
 #if defined(USE_OZONE)
   switches::kOzonePlatform,
 #endif
@@ -546,7 +544,8 @@
     DCHECK(g_gpu_main_thread_factory);
     in_process_gpu_thread_.reset(
         g_gpu_main_thread_factory(InProcessChildThreadParams(
-            channel_id, base::MessageLoop::current()->task_runner())));
+            channel_id, base::MessageLoop::current()->task_runner()),
+            GetGpuPreferencesFromCommandLine()));
     base::Thread::Options options;
 #if defined(OS_WIN)
     // WGL needs to create its own window and pump messages on it.
@@ -562,7 +561,7 @@
     return false;
   }
 
-  if (!Send(new GpuMsg_Initialize()))
+  if (!Send(new GpuMsg_Initialize(GetGpuPreferencesFromCommandLine())))
     return false;
 
   return true;
@@ -982,13 +981,13 @@
   if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED)
     cmd_line->AppendSwitch(switches::kDisableGpuSandbox);
 
+  // TODO(penghuang): Replace all GPU related switches with GpuPreferences.
+  // https://crbug.com/590825
   // If you want a browser command-line switch passed to the GPU process
   // you need to add it to |kSwitchNames| at the beginning of this file.
   cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
                              arraysize(kSwitchNames));
   cmd_line->CopySwitchesFrom(
-      browser_command_line, switches::kGpuSwitches, switches::kNumGpuSwitches);
-  cmd_line->CopySwitchesFrom(
       browser_command_line, switches::kGLSwitchesCopiedFromGpuProcessHost,
       switches::kGLSwitchesCopiedFromGpuProcessHostNumSwitches);
 
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index b3f6419a..90703a7 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -40,6 +40,7 @@
 }
 
 namespace gpu {
+struct GpuPreferences;
 struct SyncToken;
 }
 
@@ -52,7 +53,7 @@
 class ShaderDiskCache;
 
 typedef base::Thread* (*GpuMainThreadFactoryFunction)(
-    const InProcessChildThreadParams&);
+    const InProcessChildThreadParams&, const gpu::GpuPreferences&);
 
 class GpuProcessHost : public BrowserChildProcessHostDelegate,
                        public IPC::Sender,
diff --git a/content/browser/net/quota_policy_cookie_store.cc b/content/browser/net/quota_policy_cookie_store.cc
index ac0f31a..6767eb8d 100644
--- a/content/browser/net/quota_policy_cookie_store.cc
+++ b/content/browser/net/quota_policy_cookie_store.cc
@@ -129,17 +129,18 @@
 CookieStoreConfig::~CookieStoreConfig() {
 }
 
-net::CookieStore* CreateCookieStore(const CookieStoreConfig& config) {
+scoped_ptr<net::CookieStore> CreateCookieStore(
+    const CookieStoreConfig& config) {
   // TODO(bcwhite): Remove ScopedTracker below once crbug.com/483686 is fixed.
   tracked_objects::ScopedTracker tracking_profile(
       FROM_HERE_WITH_EXPLICIT_FUNCTION("483686 content::CreateCookieStore"));
 
-  net::CookieMonster* cookie_monster = nullptr;
+  scoped_ptr<net::CookieMonster> cookie_monster;
 
   if (config.path.empty()) {
     // Empty path means in-memory store.
-    cookie_monster = new net::CookieMonster(nullptr,
-                                            config.cookie_delegate.get());
+    cookie_monster.reset(
+        new net::CookieMonster(nullptr, config.cookie_delegate.get()));
   } else {
     scoped_refptr<base::SequencedTaskRunner> client_task_runner =
         config.client_task_runner;
@@ -171,8 +172,8 @@
             sqlite_store.get(),
             config.storage_policy.get());
 
-    cookie_monster =
-        new net::CookieMonster(persistent_store, config.cookie_delegate.get());
+    cookie_monster.reset(
+        new net::CookieMonster(persistent_store, config.cookie_delegate.get()));
     if ((config.session_cookie_mode ==
          CookieStoreConfig::PERSISTANT_SESSION_COOKIES) ||
         (config.session_cookie_mode ==
@@ -184,7 +185,7 @@
   if (!config.cookieable_schemes.empty())
     cookie_monster->SetCookieableSchemes(config.cookieable_schemes);
 
-  return cookie_monster;
+  return std::move(cookie_monster);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index e438033e..17ce1b5 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -814,12 +814,11 @@
     const std::string& channel_id) {
   scoped_refptr<base::SingleThreadTaskRunner> runner =
       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
-  scoped_refptr<base::SequencedTaskRunner> mojo_task_runner =
-      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)
-          ->task_runner();
   if (ShouldUseMojoChannel()) {
     VLOG(1) << "Mojo Channel is enabled on host";
 
+    mojo_channel_token_ = mojo::edk::GenerateRandomToken();
+
     // Do NOT expand ifdef or run time condition checks here! Synchronous
     // IPCs from browser process are banned. It is only narrowly allowed
     // for Android WebView to maintain backward compatibility.
@@ -828,14 +827,14 @@
     if (base::CommandLine::ForCurrentProcess()->HasSwitch(
             switches::kIPCSyncCompositing)) {
       return IPC::SyncChannel::Create(
-          IPC::ChannelMojo::CreateServerFactory(mojo_task_runner, channel_id),
-          this, runner.get(), true, &never_signaled_);
+          IPC::ChannelMojo::CreateServerFactory(mojo_channel_token_), this,
+          runner.get(), true, &never_signaled_);
     }
 #endif  // OS_ANDROID
 
     return IPC::ChannelProxy::Create(
-        IPC::ChannelMojo::CreateServerFactory(mojo_task_runner, channel_id),
-        this, runner.get());
+        IPC::ChannelMojo::CreateServerFactory(mojo_channel_token_), this,
+        runner.get());
   }
 
     // Do NOT expand ifdef or run time condition checks here! See comment above.
@@ -1375,6 +1374,11 @@
 #endif
 
   AppendCompositorCommandLineFlags(command_line);
+
+  if (!mojo_channel_token_.empty()) {
+    command_line->AppendSwitchASCII(switches::kMojoChannelToken,
+                                    mojo_channel_token_);
+  }
 }
 
 void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
@@ -1385,6 +1389,7 @@
   static const char* const kSwitchNames[] = {
     switches::kAgcStartupMinVolume,
     switches::kAllowLoopbackInPeerConnection,
+    switches::kAndroidFontsPath,
     switches::kAudioBufferSize,
     switches::kBlinkPlatformLogChannels,
     switches::kBlinkSettings,
@@ -1401,7 +1406,6 @@
     switches::kDisableDirectNPAPIRequests,
     switches::kDisableDisplayList2dCanvas,
     switches::kDisableDistanceFieldText,
-    switches::kDisableEncryptedMedia,
     switches::kDisableFileSystem,
     switches::kDisableGestureRequirementForMediaPlayback,
     switches::kDisableGestureRequirementForPresentation,
@@ -1414,7 +1418,6 @@
     switches::kDisableLCDText,
     switches::kDisableLocalStorage,
     switches::kDisableLogging,
-    switches::kDisableMediaSource,
     switches::kDisableMediaSuspend,
     switches::kDisableMojoChannel,
     switches::kDisableNotifications,
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index eadda68..949dcaeb 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -526,6 +526,8 @@
   base::WaitableEvent never_signaled_;
 #endif
 
+  std::string mojo_channel_token_;
+
   base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
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 62b0b38..7baa14a 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -3433,20 +3433,6 @@
   return requestor;
 }
 
-- (void)viewWillStartLiveResize {
-  [super viewWillStartLiveResize];
-  RenderWidgetHostImpl* widget = renderWidgetHostView_->render_widget_host_;
-  if (widget)
-    widget->Send(new ViewMsg_SetInLiveResize(widget->GetRoutingID(), true));
-}
-
-- (void)viewDidEndLiveResize {
-  [super viewDidEndLiveResize];
-  RenderWidgetHostImpl* widget = renderWidgetHostView_->render_widget_host_;
-  if (widget)
-    widget->Send(new ViewMsg_SetInLiveResize(widget->GetRoutingID(), false));
-}
-
 - (void)updateCursor:(NSCursor*)cursor {
   if (currentCursor_ == cursor)
     return;
diff --git a/content/browser/renderer_host/sandbox_ipc_linux.cc b/content/browser/renderer_host/sandbox_ipc_linux.cc
index 8fb50d4..186c4f4c 100644
--- a/content/browser/renderer_host/sandbox_ipc_linux.cc
+++ b/content/browser/renderer_host/sandbox_ipc_linux.cc
@@ -120,6 +120,9 @@
     }
   }
 
+  if (blink_platform_impl_)
+    blink::shutdownWithoutV8();
+
   VLOG(1) << "SandboxIPCHandler stopping.";
 }
 
@@ -434,9 +437,6 @@
 }
 
 SandboxIPCHandler::~SandboxIPCHandler() {
-  if (blink_platform_impl_)
-    blink::shutdownWithoutV8();
-
   if (IGNORE_EINTR(close(lifeline_fd_)) < 0)
     PLOG(ERROR) << "close";
   if (IGNORE_EINTR(close(browser_socket_)) < 0)
diff --git a/content/browser/resolve_proxy_msg_helper_unittest.cc b/content/browser/resolve_proxy_msg_helper_unittest.cc
index 5e3dd0de..bc723fe8 100644
--- a/content/browser/resolve_proxy_msg_helper_unittest.cc
+++ b/content/browser/resolve_proxy_msg_helper_unittest.cc
@@ -90,8 +90,7 @@
 
  private:
   bool OnMessageReceived(const IPC::Message& msg) override {
-    base::TupleTypes<ViewHostMsg_ResolveProxy::ReplyParam>::ValueTuple
-        reply_data;
+    ViewHostMsg_ResolveProxy::ReplyParam reply_data;
     EXPECT_TRUE(ViewHostMsg_ResolveProxy::ReadReplyParam(&msg, &reply_data));
     DCHECK(!pending_result_.get());
     pending_result_.reset(
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 3645c01..229a7d3 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -1339,36 +1339,42 @@
     case RUNNING:
       RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
       return;
+    case STARTING:
+      DCHECK(!start_callbacks_.empty());
+      break;
     case STOPPING:
     case STOPPED:
-    case STARTING:
       if (start_callbacks_.empty()) {
         start_callbacks_.push_back(
             base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult,
                        weak_factory_.GetWeakPtr()));
       }
-      // Keep the live registration while starting the worker.
-      start_callbacks_.push_back(
-          base::Bind(&RunStartWorkerCallback, callback, protect));
-      StartWorkerInternal();
-      return;
+      break;
   }
+
+  // Keep the live registration while starting the worker.
+  start_callbacks_.push_back(
+      base::Bind(&RunStartWorkerCallback, callback, protect));
+
+  if (running_status() == STOPPED)
+    StartWorkerInternal();
+  DCHECK(timeout_timer_.IsRunning());
 }
 
 void ServiceWorkerVersion::StartWorkerInternal() {
-  if (!metrics_)
-    metrics_.reset(new Metrics(this));
+  DCHECK_EQ(STOPPED, running_status());
 
-  if (!timeout_timer_.IsRunning())
-    StartTimeoutTimer();
-  if (running_status() == STOPPED) {
-    DCHECK(!pause_after_download_ || !IsInstalled(status()));
-    embedded_worker_->Start(
-        version_id_, scope_, script_url_,
-        base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
-                   weak_factory_.GetWeakPtr()),
-        pause_after_download_);
-  }
+  DCHECK(!metrics_);
+  metrics_.reset(new Metrics(this));
+
+  StartTimeoutTimer();
+
+  DCHECK(!pause_after_download_ || !IsInstalled(status()));
+  embedded_worker_->Start(
+      version_id_, scope_, script_url_,
+      base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
+                 weak_factory_.GetWeakPtr()),
+      pause_after_download_);
 }
 
 void ServiceWorkerVersion::StartTimeoutTimer() {
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 04ae5ebe..5974715 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -839,7 +839,6 @@
   window_.reset(new aura::Window(this));
   window_->set_owned_by_parent(false);
   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
-  window_->SetTransparent(false);
   window_->Init(ui::LAYER_NOT_DRAWN);
   window_->AddObserver(this);
   aura::Window* root_window = context ? context->GetRootWindow() : NULL;
diff --git a/content/browser/web_contents/web_contents_view_mus.cc b/content/browser/web_contents/web_contents_view_mus.cc
index b987ab1..d4860b3a 100644
--- a/content/browser/web_contents/web_contents_view_mus.cc
+++ b/content/browser/web_contents/web_contents_view_mus.cc
@@ -104,7 +104,6 @@
   aura_window_.reset(new aura::Window(this));
   aura_window_->set_owned_by_parent(false);
   aura_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
-  aura_window_->SetTransparent(false);
   aura_window_->Init(ui::LAYER_NOT_DRAWN);
   aura::Window* root_window = context ? context->GetRootWindow() : nullptr;
   if (root_window) {
diff --git a/content/browser/zygote_host/zygote_communication_linux.cc b/content/browser/zygote_host/zygote_communication_linux.cc
index 8682098..54f5176a 100644
--- a/content/browser/zygote_host/zygote_communication_linux.cc
+++ b/content/browser/zygote_host/zygote_communication_linux.cc
@@ -280,7 +280,8 @@
   // to the zygote/renderers.
   // Should this list be obtained from browser_render_process_host.cc?
   static const char* kForwardSwitches[] = {
-      switches::kAllowSandboxDebugging, switches::kDisableSeccompFilterSandbox,
+      switches::kAllowSandboxDebugging, switches::kAndroidFontsPath,
+      switches::kDisableSeccompFilterSandbox,
       switches::kEnableHeapProfiling,
       switches::kEnableLogging,  // Support, e.g., --enable-logging=stderr.
       // Zygote process needs to know what resources to have loaded when it
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 80be4c03..59739a98 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -54,6 +54,7 @@
 #include "content/common/in_process_child_thread_params.h"
 #include "content/common/mojo/mojo_shell_connection_impl.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/mojo_channel_switches.h"
 #include "ipc/attachment_broker.h"
 #include "ipc/attachment_broker_unprivileged.h"
 #include "ipc/ipc_logging.h"
@@ -62,6 +63,7 @@
 #include "ipc/ipc_sync_channel.h"
 #include "ipc/ipc_sync_message_filter.h"
 #include "ipc/mojo/ipc_channel_mojo.h"
+#include "ipc/mojo/scoped_ipc_support.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/platform_channel_pair.h"
 
@@ -360,10 +362,10 @@
   bool create_pipe_now = true;
   if (use_mojo_channel) {
     VLOG(1) << "Mojo is enabled on child";
-    scoped_refptr<base::SequencedTaskRunner> io_task_runner = GetIOTaskRunner();
-    DCHECK(io_task_runner);
     channel_->Init(
-        IPC::ChannelMojo::CreateClientFactory(io_task_runner, channel_name_),
+        IPC::ChannelMojo::CreateClientFactory(
+            base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+                switches::kMojoChannelToken)),
         create_pipe_now);
     return;
   }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index c7a8f476..b627ef1 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -19,23 +19,12 @@
 #include "ui/gl/gl_switches.h"
 #include "ui/native_theme/native_theme_switches.h"
 
-#if defined(OS_ANDROID)
-#include <cpu-features.h>
-#include "base/android/build_info.h"
-#include "media/base/android/media_codec_util.h"
-#endif
-
 using blink::WebRuntimeFeatures;
 
 namespace content {
 
 static void SetRuntimeFeatureDefaultsForPlatform() {
 #if defined(OS_ANDROID)
-  // EME implementation needs Android MediaCodec API.
-  if (!media::MediaCodecUtil::IsMediaCodecAvailable()) {
-    WebRuntimeFeatures::enableEncryptedMedia(false);
-  }
-
   // Android does not have support for PagePopup
   WebRuntimeFeatures::enablePagePopup(false);
   // Android does not yet support SharedWorker. crbug.com/154571
@@ -81,9 +70,6 @@
   if (command_line.HasSwitch(switches::kDisableDatabases))
     WebRuntimeFeatures::enableDatabase(false);
 
-  if (command_line.HasSwitch(switches::kDisableMediaSource))
-    WebRuntimeFeatures::enableMediaSource(false);
-
   if (command_line.HasSwitch(switches::kDisableNotifications)) {
     WebRuntimeFeatures::enableNotifications(false);
 
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc
index 311fa7f4..435ea30 100644
--- a/content/child/v8_value_converter_impl_unittest.cc
+++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/values.h"
 #include "content/child/v8_value_converter_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 namespace content {
@@ -287,6 +288,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   // Set up objects to throw when reading or writing 'foo'.
   const char* source =
@@ -329,6 +331,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "var arr = [];"
@@ -405,6 +408,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "Object.prototype.foo = 'foo';"
@@ -429,6 +433,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "return { foo: undefined, bar: null };"
@@ -487,6 +492,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "return {"
@@ -525,6 +531,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "var a = [0];"
@@ -549,6 +556,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Object> object;
   {
diff --git a/content/common/gpu/gpu_host_messages.h b/content/common/gpu/gpu_host_messages.h
index 1428c8a..7ba30f4 100644
--- a/content/common/gpu/gpu_host_messages.h
+++ b/content/common/gpu/gpu_host_messages.h
@@ -14,6 +14,7 @@
 #include "content/public/common/common_param_traits.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/command_buffer/common/value_state.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
 #include "gpu/config/gpu_info.h"
 #include "gpu/ipc/common/memory_stats.h"
 #include "ipc/ipc_channel_handle.h"
@@ -100,6 +101,33 @@
 IPC_STRUCT_TRAITS_END()
 #endif
 
+IPC_STRUCT_TRAITS_BEGIN(gpu::GpuPreferences)
+  IPC_STRUCT_TRAITS_MEMBER(single_process)
+  IPC_STRUCT_TRAITS_MEMBER(in_process_gpu)
+  IPC_STRUCT_TRAITS_MEMBER(ui_prioritize_in_gpu_process)
+  IPC_STRUCT_TRAITS_MEMBER(compile_shader_always_succeeds)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gl_error_limit)
+  IPC_STRUCT_TRAITS_MEMBER(disable_glsl_translator)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gpu_driver_bug_workarounds)
+  IPC_STRUCT_TRAITS_MEMBER(disable_shader_name_hashing)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_command_logging)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_debugging)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_logging_gpu)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gpu_program_cache)
+  IPC_STRUCT_TRAITS_MEMBER(enforce_gl_minimums)
+  IPC_STRUCT_TRAITS_MEMBER(force_gpu_mem_available)
+  IPC_STRUCT_TRAITS_MEMBER(gpu_program_cache_size)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gpu_shader_disk_cache)
+  IPC_STRUCT_TRAITS_MEMBER(enable_share_group_async_texture_upload)
+  IPC_STRUCT_TRAITS_MEMBER(enable_subscribe_uniform_extension)
+  IPC_STRUCT_TRAITS_MEMBER(enable_threaded_texture_mailboxes)
+  IPC_STRUCT_TRAITS_MEMBER(gl_shader_interm_output)
+  IPC_STRUCT_TRAITS_MEMBER(emulate_shader_precision)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_logging)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_tracing)
+  IPC_STRUCT_TRAITS_MEMBER(enable_unsafe_es3_apis)
+IPC_STRUCT_TRAITS_END()
+
 //------------------------------------------------------------------------------
 // GPU Messages
 // These are messages from the browser to the GPU process.
@@ -109,7 +137,8 @@
 // up between the browser and GPU process before doing any work that might
 // potentially crash the GPU process. Detection of the child process
 // exiting abruptly is predicated on having the IPC channel set up.
-IPC_MESSAGE_CONTROL0(GpuMsg_Initialize)
+IPC_MESSAGE_CONTROL1(GpuMsg_Initialize,
+                     gpu::GpuPreferences /* gpu_prefernces */)
 
 // Tells the GPU process to shutdown itself.
 IPC_MESSAGE_CONTROL0(GpuMsg_Finalize)
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc
index d8da2982..1de68a2e 100644
--- a/content/common/gpu/media/android_video_decode_accelerator.cc
+++ b/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -169,7 +169,14 @@
 };
 
 // Helper class to share an IO timer for DoIOTask() execution; prevents each
-// AVDA instance from starting its own high frequency timer.
+// AVDA instance from starting its own high frequency timer.  The intuition
+// behind this is that, if we're waiting for long enough, then either (a)
+// MediaCodec is broken or (b) MediaCodec is waiting on us to change state
+// (e.g., get new demuxed data / get a free picture buffer / return an output
+// buffer to MediaCodec).  This is inherently a race, since we don't know if
+// MediaCodec is broken or just slow.  Since the MediaCodec API doesn't let
+// us wait on MediaCodec state changes prior to L, we more or less have to
+// time out or keep polling forever in some common cases.
 class AVDATimerManager {
  public:
   // Request periodic callback of |avda_instance|->DoIOTask(). Does nothing if
@@ -177,6 +184,12 @@
   // will start the repeating timer on an interval of DecodePollDelay().
   void StartTimer(AndroidVideoDecodeAccelerator* avda_instance) {
     avda_instances_.insert(avda_instance);
+
+    // If the timer is running, StopTimer() might have been called earlier, if
+    // so remove the instance from the pending erasures.
+    if (timer_running_)
+      pending_erase_.erase(avda_instance);
+
     if (io_timer_.IsRunning())
       return;
     io_timer_.Start(FROM_HERE, DecodePollDelay(), this,
@@ -825,6 +838,11 @@
 
   strategy_->ReuseOnePictureBuffer(i->second);
 
+  // Turn the timer back on.  If it timed out, it might be because MediaCodec
+  // is waiting for us to return a buffer.  We can't assume that it will be
+  // ready to send us a buffer back immediately, though we do try DoIOTask
+  // to be optimistic.
+  ManageTimer(true);
   DoIOTask();
 }
 
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
index adbc105..695f06b 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
@@ -2448,12 +2448,6 @@
         RETURN_ON_HR_FAILURE(hr, "Failed to set media type attributes", false);
       }
       hr = transform->SetOutputType(0, media_type.get(), 0);  // No flags
-      if (FAILED(hr)) {
-        base::debug::Alias(&hr);
-        // TODO(ananta)
-        // Remove this CHECK when this stabilizes in the field.
-        CHECK(false);
-      }
       RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false);
       return true;
     }
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index b343ced..5bb3409 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -907,11 +907,6 @@
                     gfx::Rect /* window frame */,
                     gfx::Rect /* content view frame */)
 
-// Message sent from the browser to the renderer when the user starts or stops
-// resizing the view.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetInLiveResize,
-                    bool /* enable */)
-
 // Tell the renderer that plugin IME has completed.
 IPC_MESSAGE_ROUTED2(ViewMsg_PluginImeCompositionCompleted,
                     base::string16 /* text */,
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 4ad86b28..4f5c244 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -186,6 +186,8 @@
       'public/browser/gpu_data_manager_observer.h',
       'public/browser/gpu_service_registry.cc',
       'public/browser/gpu_service_registry.h',
+      'public/browser/gpu_utils.cc',
+      'public/browser/gpu_utils.h',
       'public/browser/histogram_fetcher.h',
       'public/browser/host_zoom_map.h',
       'public/browser/indexed_db_context.h',
@@ -778,6 +780,8 @@
       'browser/frame_host/render_widget_host_view_child_frame.h',
       'browser/frame_host/render_widget_host_view_guest.cc',
       'browser/frame_host/render_widget_host_view_guest.h',
+      'browser/frame_host/traced_frame_tree_node.cc',
+      'browser/frame_host/traced_frame_tree_node.h',
       'browser/gamepad/gamepad_consumer.h',
       'browser/gamepad/gamepad_data_fetcher.cc',
       'browser/gamepad/gamepad_data_fetcher.h',
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 1bb3df0..5b20df9 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -46,15 +46,6 @@
 static base::LazyInstance<scoped_refptr<ThreadSafeSender> >
     g_thread_safe_sender = LAZY_INSTANCE_INITIALIZER;
 
-bool GetSizeTFromSwitch(const base::CommandLine* command_line,
-                        const base::StringPiece& switch_string,
-                        size_t* value) {
-  if (!command_line->HasSwitch(switch_string))
-    return false;
-  std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
-  return base::StringToSizeT(switch_value, value);
-}
-
 bool GpuProcessLogMessageHandler(int severity,
                                  const char* file, int line,
                                  size_t message_start,
@@ -158,7 +149,6 @@
     GpuMemoryBufferFactory* gpu_memory_buffer_factory,
     gpu::SyncPointManager* sync_point_manager)
     : ChildThreadImpl(GetOptions(gpu_memory_buffer_factory)),
-      gpu_preferences_(GetGpuPreferencesFromCommandLine()),
       dead_on_arrival_(dead_on_arrival),
       sync_point_manager_(sync_point_manager),
       gpu_info_(gpu_info),
@@ -348,7 +338,8 @@
   Send(new GpuHostMsg_CacheShader(client_id, key, shader));
 }
 
-void GpuChildThread::OnInitialize() {
+void GpuChildThread::OnInitialize(const gpu::GpuPreferences& gpu_preferences) {
+  gpu_preferences_ = gpu_preferences;
   // Record initialization only after collecting the GPU info because that can
   // take a significant amount of time.
   gpu_info_.initialization_time = base::Time::Now() - process_start_time_;
@@ -399,70 +390,6 @@
   }
 }
 
-// static
-gpu::GpuPreferences GpuChildThread::GetGpuPreferencesFromCommandLine() {
-  // TODO(penghuang): share below code with
-  // android_webview/browser/deferred_gpu_command_service.cc
-  // http://crbug.com/590825
-  // For any modification of below code, deferred_gpu_command_service.cc should
-  // be updated as well.
-  DCHECK(base::CommandLine::InitializedForCurrentProcess());
-  const base::CommandLine* command_line =
-      base::CommandLine::ForCurrentProcess();
-  gpu::GpuPreferences gpu_preferences;
-  gpu_preferences.single_process =
-      command_line->HasSwitch(switches::kSingleProcess);
-  gpu_preferences.in_process_gpu =
-      command_line->HasSwitch(switches::kInProcessGPU);
-  gpu_preferences.ui_prioritize_in_gpu_process =
-      command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
-  gpu_preferences.compile_shader_always_succeeds =
-      command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
-  gpu_preferences.disable_gl_error_limit =
-    command_line->HasSwitch(switches::kDisableGLErrorLimit);
-  gpu_preferences.disable_glsl_translator =
-    command_line->HasSwitch(switches::kDisableGLSLTranslator);
-  gpu_preferences.disable_gpu_driver_bug_workarounds =
-    command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
-  gpu_preferences.disable_shader_name_hashing =
-    command_line->HasSwitch(switches::kDisableShaderNameHashing);
-  gpu_preferences.enable_gpu_command_logging =
-    command_line->HasSwitch(switches::kEnableGPUCommandLogging);
-  gpu_preferences.enable_gpu_debugging =
-    command_line->HasSwitch(switches::kEnableGPUDebugging);
-  gpu_preferences.enable_gpu_service_logging_gpu =
-    command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
-  gpu_preferences.disable_gpu_program_cache =
-    command_line->HasSwitch(switches::kDisableGpuProgramCache);
-  gpu_preferences.enforce_gl_minimums =
-    command_line->HasSwitch(switches::kEnforceGLMinimums);
-  if (GetSizeTFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
-                         &gpu_preferences.force_gpu_mem_available)) {
-    gpu_preferences.force_gpu_mem_available *= 1024 * 1024;
-  }
-  if (GetSizeTFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
-                         &gpu_preferences.gpu_program_cache_size)) {
-    gpu_preferences.gpu_program_cache_size *= 1024;
-  }
-  gpu_preferences.enable_share_group_async_texture_upload =
-    command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload);
-  gpu_preferences.enable_subscribe_uniform_extension =
-    command_line->HasSwitch(switches::kEnableSubscribeUniformExtension);
-  gpu_preferences.enable_threaded_texture_mailboxes =
-    command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
-  gpu_preferences.gl_shader_interm_output =
-    command_line->HasSwitch(switches::kGLShaderIntermOutput);
-  gpu_preferences.emulate_shader_precision =
-    command_line->HasSwitch(switches::kEmulateShaderPrecision);
-  gpu_preferences.enable_gpu_service_logging =
-      command_line->HasSwitch(switches::kEnableGPUServiceLogging);
-  gpu_preferences.enable_gpu_service_tracing =
-      command_line->HasSwitch(switches::kEnableGPUServiceTracing);
-  gpu_preferences.enable_unsafe_es3_apis =
-    command_line->HasSwitch(switches::kEnableUnsafeES3APIs);
-  return gpu_preferences;
-}
-
 void GpuChildThread::OnCollectGraphicsInfo() {
 #if defined(OS_WIN)
   // GPU full info collection should only happen on un-sandboxed GPU process
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index ec7d19e..80a2412 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -71,8 +71,6 @@
   void Init(const base::Time& process_start_time);
   void StopWatchdog();
 
-  static gpu::GpuPreferences GetGpuPreferencesFromCommandLine();
-
  private:
   // ChildThread overrides.
   bool Send(IPC::Message* msg) override;
@@ -103,7 +101,7 @@
                          const std::string& shader) override;
 
   // Message handlers.
-  void OnInitialize();
+  void OnInitialize(const gpu::GpuPreferences& gpu_preferences);
   void OnFinalize();
   void OnCollectGraphicsInfo();
   void OnGetVideoMemoryUsageStats();
diff --git a/content/gpu/in_process_gpu_thread.cc b/content/gpu/in_process_gpu_thread.cc
index 1453ff2a..8f170c3 100644
--- a/content/gpu/in_process_gpu_thread.cc
+++ b/content/gpu/in_process_gpu_thread.cc
@@ -74,9 +74,10 @@
 }
 
 base::Thread* CreateInProcessGpuThread(
-    const InProcessChildThreadParams& params) {
+    const InProcessChildThreadParams& params,
+    const gpu::GpuPreferences& gpu_preferences) {
   return new InProcessGpuThread(
-      params, GpuChildThread::GetGpuPreferencesFromCommandLine(), nullptr);
+      params, gpu_preferences, nullptr);
 }
 
 }  // namespace content
diff --git a/content/gpu/in_process_gpu_thread.h b/content/gpu/in_process_gpu_thread.h
index 85b2c52..6124ba8 100644
--- a/content/gpu/in_process_gpu_thread.h
+++ b/content/gpu/in_process_gpu_thread.h
@@ -54,7 +54,8 @@
 };
 
 CONTENT_EXPORT base::Thread* CreateInProcessGpuThread(
-    const InProcessChildThreadParams& params);
+    const InProcessChildThreadParams& params,
+    const gpu::GpuPreferences& gpu_preferences);
 
 }  // namespace content
 
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
index 5a261393..a5b0ed0 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -8,6 +8,7 @@
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.Intent;
+import android.test.FlakyTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 
@@ -487,8 +488,12 @@
         assertEquals("SampleTextToCopy", mContentViewCore.getSelectedText());
     }
 
+    /*
     @SmallTest
     @Feature({"TextInput"})
+    https://crbug.com/592428
+    */
+    @FlakyTest
     public void testSelectActionBarPasswordPaste() throws Exception {
         copyStringToClipboard("SamplePassword2");
 
diff --git a/content/public/browser/cookie_store_factory.h b/content/public/browser/cookie_store_factory.h
index c478adb7..1552342 100644
--- a/content/public/browser/cookie_store_factory.h
+++ b/content/public/browser/cookie_store_factory.h
@@ -10,6 +10,7 @@
 
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "content/common/content_export.h"
 
 namespace base {
@@ -95,7 +96,7 @@
   std::vector<std::string> cookieable_schemes;
 };
 
-CONTENT_EXPORT net::CookieStore* CreateCookieStore(
+CONTENT_EXPORT scoped_ptr<net::CookieStore> CreateCookieStore(
     const CookieStoreConfig& config);
 
 }  // namespace content
diff --git a/content/public/browser/gpu_utils.cc b/content/public/browser/gpu_utils.cc
new file mode 100644
index 0000000..acd28c9
--- /dev/null
+++ b/content/public/browser/gpu_utils.cc
@@ -0,0 +1,87 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/gpu_utils.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/config/gpu_switches.h"
+#include "ui/gl/gl_switches.h"
+
+namespace {
+
+bool GetUintFromSwitch(const base::CommandLine* command_line,
+                       const base::StringPiece& switch_string,
+                       uint32_t* value) {
+  if (!command_line->HasSwitch(switch_string))
+    return false;
+  std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
+  return base::StringToUint(switch_value, value);
+}
+
+}  // namespace
+
+namespace content {
+
+const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
+  DCHECK(base::CommandLine::InitializedForCurrentProcess());
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+  gpu::GpuPreferences gpu_preferences;
+  gpu_preferences.single_process =
+      command_line->HasSwitch(switches::kSingleProcess);
+  gpu_preferences.in_process_gpu =
+      command_line->HasSwitch(switches::kInProcessGPU);
+  gpu_preferences.ui_prioritize_in_gpu_process =
+      command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
+  gpu_preferences.compile_shader_always_succeeds =
+      command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
+  gpu_preferences.disable_gl_error_limit =
+      command_line->HasSwitch(switches::kDisableGLErrorLimit);
+  gpu_preferences.disable_glsl_translator =
+      command_line->HasSwitch(switches::kDisableGLSLTranslator);
+  gpu_preferences.disable_gpu_driver_bug_workarounds =
+      command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
+  gpu_preferences.disable_shader_name_hashing =
+      command_line->HasSwitch(switches::kDisableShaderNameHashing);
+  gpu_preferences.enable_gpu_command_logging =
+      command_line->HasSwitch(switches::kEnableGPUCommandLogging);
+  gpu_preferences.enable_gpu_debugging =
+      command_line->HasSwitch(switches::kEnableGPUDebugging);
+  gpu_preferences.enable_gpu_service_logging_gpu =
+      command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
+  gpu_preferences.disable_gpu_program_cache =
+      command_line->HasSwitch(switches::kDisableGpuProgramCache);
+  gpu_preferences.enforce_gl_minimums =
+      command_line->HasSwitch(switches::kEnforceGLMinimums);
+  if (GetUintFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
+                        &gpu_preferences.force_gpu_mem_available)) {
+    gpu_preferences.force_gpu_mem_available *= 1024 * 1024;
+  }
+  if (GetUintFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
+                        &gpu_preferences.gpu_program_cache_size)) {
+    gpu_preferences.gpu_program_cache_size *= 1024;
+  }
+  gpu_preferences.enable_share_group_async_texture_upload =
+      command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload);
+  gpu_preferences.enable_subscribe_uniform_extension =
+      command_line->HasSwitch(switches::kEnableSubscribeUniformExtension);
+  gpu_preferences.enable_threaded_texture_mailboxes =
+      command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
+  gpu_preferences.gl_shader_interm_output =
+      command_line->HasSwitch(switches::kGLShaderIntermOutput);
+  gpu_preferences.emulate_shader_precision =
+      command_line->HasSwitch(switches::kEmulateShaderPrecision);
+  gpu_preferences.enable_gpu_service_logging =
+      command_line->HasSwitch(switches::kEnableGPUServiceLogging);
+  gpu_preferences.enable_gpu_service_tracing =
+      command_line->HasSwitch(switches::kEnableGPUServiceTracing);
+  gpu_preferences.enable_unsafe_es3_apis =
+      command_line->HasSwitch(switches::kEnableUnsafeES3APIs);
+  return gpu_preferences;
+}
+
+}  // namespace content
diff --git a/content/public/browser/gpu_utils.h b/content/public/browser/gpu_utils.h
new file mode 100644
index 0000000..84e7808
--- /dev/null
+++ b/content/public/browser/gpu_utils.h
@@ -0,0 +1,17 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
+#define CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
+
+#include "content/common/content_export.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+
+namespace content {
+
+CONTENT_EXPORT const gpu::GpuPreferences GetGpuPreferencesFromCommandLine();
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 92b7dc4..50b2d6f 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -37,6 +37,11 @@
 // Allows debugging of sandboxed processes (see zygote_main_linux.cc).
 const char kAllowSandboxDebugging[]         = "allow-sandbox-debugging";
 
+// Uses the android SkFontManager on linux. The specified directory should
+// include the configuration xml file with the name "fonts.xml".
+// This is used in blimp to emulate android fonts on linux.
+const char kAndroidFontsPath[]          = "android-fonts-path";
+
 // Choose which logging channels in blink platform to activate.  See
 // Logging.cpp in blink's Source/platform for a list of available channels.
 const char kBlinkPlatformLogChannels[]      = "blink-platform-log-channels";
@@ -207,9 +212,6 @@
 // builds.
 const char kDisableLogging[]                = "disable-logging";
 
-// Disables Media Source API (i.e., the MediaSource object).
-const char kDisableMediaSource[]            = "disable-media-source";
-
 // Disables usage of the namespace sandbox.
 const char kDisableNamespaceSandbox[]       = "disable-namespace-sandbox";
 
@@ -342,9 +344,6 @@
 const char kForceDisplayList2dCanvas[]      = "force-display-list-2d-canvas";
 const char kDisableDisplayList2dCanvas[]    = "disable-display-list-2d-canvas";
 
-// Disables (unprefixed) Encrypted Media Extensions.
-const char kDisableEncryptedMedia[] = "disable-encrypted-media";
-
 // Enable experimental canvas features, e.g. canvas 2D context attributes
 const char kEnableExperimentalCanvasFeatures[] =
     "enable-experimental-canvas-features";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 6143111b..3a1b104 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -20,6 +20,7 @@
 CONTENT_EXPORT extern const char kAllowLoopbackInPeerConnection[];
 CONTENT_EXPORT extern const char kAllowNoSandboxJob[];
 CONTENT_EXPORT extern const char kAllowSandboxDebugging[];
+CONTENT_EXPORT extern const char kAndroidFontsPath[];
 CONTENT_EXPORT extern const char kBlinkSettings[];
 CONTENT_EXPORT extern const char kBlinkPlatformLogChannels[];
 CONTENT_EXPORT extern const char kBrowserCrashTest[];
@@ -44,7 +45,6 @@
 CONTENT_EXPORT extern const char kDisableDistanceFieldText[];
 CONTENT_EXPORT extern const char kDisableDisplayList2dCanvas[];
 extern const char kDisableDomainBlockingFor3DAPIs[];
-CONTENT_EXPORT extern const char kDisableEncryptedMedia[];
 CONTENT_EXPORT extern const char kDisableExperimentalWebGL[];
 CONTENT_EXPORT extern const char kDisableFeatures[];
 CONTENT_EXPORT extern const char kDisableFileSystem[];
@@ -70,7 +70,6 @@
 extern const char kDisableKillAfterBadIPC[];
 CONTENT_EXPORT extern const char kDisableLocalStorage[];
 CONTENT_EXPORT extern const char kDisableLogging[];
-CONTENT_EXPORT extern const char kDisableMediaSource[];
 CONTENT_EXPORT extern const char kDisableNamespaceSandbox[];
 CONTENT_EXPORT extern const char kDisableNativeGpuMemoryBuffers[];
 CONTENT_EXPORT extern const char kDisableNotifications[];
diff --git a/content/public/common/mojo_channel_switches.cc b/content/public/common/mojo_channel_switches.cc
index 8f70ce28..a94e195 100644
--- a/content/public/common/mojo_channel_switches.cc
+++ b/content/public/common/mojo_channel_switches.cc
@@ -16,9 +16,12 @@
 const char kEnableRendererMojoChannel[] =
     "enable-renderer-mojo-channel";
 
-// Disale ChannelMojo usage regardless of the platform or the process type.
+// Disable ChannelMojo usage regardless of the platform or the process type.
 const char kDisableMojoChannel[] = "disable-mojo-channel";
 
+// The token to use to construct the message pipe on which to layer ChannelMojo.
+const char kMojoChannelToken[] = "mojo-channel-token";
+
 }  // namespace switches
 
 namespace content {
diff --git a/content/public/common/mojo_channel_switches.h b/content/public/common/mojo_channel_switches.h
index 5e2af68f..a960e47 100644
--- a/content/public/common/mojo_channel_switches.h
+++ b/content/public/common/mojo_channel_switches.h
@@ -11,6 +11,7 @@
 
 extern const char kEnableRendererMojoChannel[];
 extern const char kDisableMojoChannel[];
+extern const char kMojoChannelToken[];
 
 }  // namespace switches
 
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h
index f0ccb70e..033dcea8e 100644
--- a/content/renderer/browser_plugin/browser_plugin.h
+++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -88,7 +88,7 @@
   bool supportsEditCommands() const override;
   bool supportsInputMethod() const override;
   bool canProcessDrag() const override;
-  void layoutIfNeeded() override {}
+  void updateAllLifecyclePhases() override {}
   void paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override;
   void updateGeometry(const blink::WebRect& window_rect,
                       const blink::WebRect& clip_rect,
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 32c68c82..7252043 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -62,7 +62,6 @@
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPaint.h"
@@ -752,6 +751,11 @@
   if (!info_loader_ || !info_loader_->HasSingleOrigin())
     return false;
 
+  // TODO(qinmin): After fixing crbug.com/592017, remove this command line.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kReduceSecurityForTesting))
+    return true;
+
   // TODO(qinmin): The url might be redirected when android media player
   // requests the stream. As a result, we cannot guarantee there is only
   // a single origin. Only if the HTTP request was made without credentials,
@@ -1489,12 +1493,6 @@
     const std::vector<uint8_t>& init_data) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
 
-  // Do not fire the "encrypted" event if Encrypted Media is not enabled.
-  // EME may not be enabled on Android Jelly Bean.
-  if (!blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
-    return;
-  }
-
   // TODO(xhwang): Update this UMA name. https://crbug.com/589251
   UMA_HISTOGRAM_COUNTS("Media.EME.NeedKey", 1);
 
diff --git a/content/renderer/npapi/webplugin_impl.cc b/content/renderer/npapi/webplugin_impl.cc
index c5a5302..2ad057c 100644
--- a/content/renderer/npapi/webplugin_impl.cc
+++ b/content/renderer/npapi/webplugin_impl.cc
@@ -167,7 +167,7 @@
   return true;
 }
 
-void WebPluginImpl::layoutIfNeeded() {
+void WebPluginImpl::updateAllLifecyclePhases() {
   if (!container_)
     return;
 
diff --git a/content/renderer/npapi/webplugin_impl.h b/content/renderer/npapi/webplugin_impl.h
index 8a6150e..45ec06fb 100644
--- a/content/renderer/npapi/webplugin_impl.h
+++ b/content/renderer/npapi/webplugin_impl.h
@@ -75,7 +75,7 @@
   NPObject* scriptableObject() override;
   struct _NPP* pluginNPP() override;
   bool getFormValue(blink::WebString& value) override;
-  void layoutIfNeeded() override;
+  void updateAllLifecyclePhases() override;
   void paint(blink::WebCanvas* canvas,
              const blink::WebRect& paint_rect) override;
   void updateGeometry(const blink::WebRect& window_rect,
diff --git a/content/renderer/pepper/pepper_webplugin_impl.h b/content/renderer/pepper/pepper_webplugin_impl.h
index d8ee01d..65641ea2 100644
--- a/content/renderer/pepper/pepper_webplugin_impl.h
+++ b/content/renderer/pepper/pepper_webplugin_impl.h
@@ -46,7 +46,7 @@
   void destroy() override;
   v8::Local<v8::Object> v8ScriptableObject(v8::Isolate* isolate) override;
   bool getFormValue(blink::WebString& value) override;
-  void layoutIfNeeded() override {}
+  void updateAllLifecyclePhases() override {}
   void paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override;
   void updateGeometry(const blink::WebRect& window_rect,
                       const blink::WebRect& clip_rect,
diff --git a/content/renderer/pepper/v8_var_converter_unittest.cc b/content/renderer/pepper/v8_var_converter_unittest.cc
index cd07abb..e030ffdb 100644
--- a/content/renderer/pepper/v8_var_converter_unittest.cc
+++ b/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -29,6 +29,7 @@
 #include "ppapi/shared_impl/var.h"
 #include "ppapi/shared_impl/var_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 using ppapi::ArrayBufferVar;
@@ -403,6 +404,7 @@
     v8::Local<v8::Context> context =
         v8::Local<v8::Context>::New(isolate_, context_);
     v8::Context::Scope context_scope(context);
+    blink::WebScopedMicrotaskSuppression microtasks_scope;
 
     const char* source =
         "(function() {"
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index cc773a8..9ce9869 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1418,7 +1418,6 @@
     IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
                         OnPluginImeCompositionCompleted)
     IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
-    IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize)
     IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
     IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
 #endif
@@ -1519,17 +1518,6 @@
   RenderWidget::OnUpdateWindowScreenRect(window_screen_rect);
 }
 
-#if defined(OS_MACOSX)
-void RenderViewImpl::OnSetInLiveResize(bool in_live_resize) {
-  if (!webview())
-    return;
-  if (in_live_resize)
-    webview()->willStartLiveResize();
-  else
-    webview()->willEndLiveResize();
-}
-#endif
-
 ///////////////////////////////////////////////////////////////////////////////
 
 void RenderViewImpl::SendUpdateState() {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index f03fc17..1e305e44 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -690,7 +690,6 @@
   void OnGetRenderedText();
   void OnPluginImeCompositionCompleted(const base::string16& text,
                                        int plugin_id);
-  void OnSetInLiveResize(bool in_live_resize);
   void OnSetWindowVisibility(bool visible);
   void OnWindowFrameChanged(const gfx::Rect& window_frame,
                             const gfx::Rect& view_frame);
diff --git a/content/renderer/render_view_win.cc b/content/renderer/render_view_win.cc
index 15cb47bf..51f97f5 100644
--- a/content/renderer/render_view_win.cc
+++ b/content/renderer/render_view_win.cc
@@ -32,6 +32,11 @@
   blink::WebFontRendering::setLCDOrientation(
       gfx::FontRenderParams::SubpixelRenderingToSkiaLCDOrientation(
           prefs.subpixel_rendering));
+
+  blink::WebFontRendering::setAntialiasedTextEnabled(
+      prefs.should_antialias_text);
+  blink::WebFontRendering::setLCDTextEnabled(prefs.subpixel_rendering
+      != gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE);
 }
 
 void RenderViewImpl::UpdateThemePrefs() {
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index b5bf9ae0..678e20d 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -13,12 +13,13 @@
 #include "base/i18n/rtl.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/pending_task.h"
 #include "base/strings/string_util.h"
 #include "base/sys_info.h"
 #include "base/threading/platform_thread.h"
+#include "base/timer/elapsed_timer.h"
 #include "base/timer/hi_res_timer_manager.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
@@ -93,7 +94,12 @@
 
   const base::CommandLine& parsed_command_line = parameters.command_line;
 
-  MojoShellConnectionImpl::Create();
+  {
+    base::ElapsedTimer timer;
+    MojoShellConnectionImpl::Create();
+    UMA_HISTOGRAM_TIMES("Mojo.Shell.RenderProcessInitializationTime",
+                        timer.Elapsed());
+  }
 
 #if defined(OS_MACOSX)
   base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool;
diff --git a/content/shell/browser/shell_devtools_frontend.cc b/content/shell/browser/shell_devtools_frontend.cc
index 02d59660..7d953933 100644
--- a/content/shell/browser/shell_devtools_frontend.cc
+++ b/content/shell/browser/shell_devtools_frontend.cc
@@ -76,15 +76,18 @@
 int ResponseWriter::Write(net::IOBuffer* buffer,
                           int num_bytes,
                           const net::CompletionCallback& callback) {
+  std::string chunk = std::string(buffer->data(), num_bytes);
+  if (!base::IsStringUTF8(chunk))
+    return num_bytes;
+
   base::FundamentalValue* id = new base::FundamentalValue(stream_id_);
-  base::StringValue* chunk =
-      new base::StringValue(std::string(buffer->data(), num_bytes));
+  base::StringValue* chunkValue = new base::StringValue(chunk);
 
   content::BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
       base::Bind(&ShellDevToolsFrontend::CallClientFunction,
                  shell_devtools_, "DevToolsAPI.streamWrite",
-                 base::Owned(id), base::Owned(chunk), nullptr));
+                 base::Owned(id), base::Owned(chunkValue), nullptr));
   return num_bytes;
 }
 
diff --git a/content/test/render_thread_impl_browser_test_ipc_helper.cc b/content/test/render_thread_impl_browser_test_ipc_helper.cc
index 8f454e2..1577bb4 100644
--- a/content/test/render_thread_impl_browser_test_ipc_helper.cc
+++ b/content/test/render_thread_impl_browser_test_ipc_helper.cc
@@ -51,9 +51,8 @@
       ipc_thread_->task_runner());
 
   channel_ = IPC::ChannelProxy::Create(
-      IPC::ChannelMojo::CreateServerFactory(ipc_thread_->task_runner(),
-                                            channel_id_),
-      dummy_listener_.get(), ipc_thread_->task_runner());
+      IPC::ChannelMojo::CreateServerFactory(channel_id_), dummy_listener_.get(),
+      ipc_thread_->task_runner());
 
   mojo_application_host_->Init();
   mojo_application_host_->Activate(channel_.get(),
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc
index c30e108..cebcc7b5 100644
--- a/content/zygote/zygote_main_linux.cc
+++ b/content/zygote/zygote_main_linux.cc
@@ -46,8 +46,10 @@
 #include "sandbox/linux/services/namespace_sandbox.h"
 #include "sandbox/linux/services/thread_helpers.h"
 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
+#include "third_party/WebKit/public/web/linux/WebFontRendering.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
 #include "third_party/skia/include/ports/SkFontConfigInterface.h"
+#include "third_party/skia/include/ports/SkFontMgr_android.h"
 
 #if defined(OS_LINUX)
 #include <sys/prctl.h>
@@ -344,8 +346,32 @@
 #if defined(ENABLE_WEBRTC)
   InitializeWebRtcModule();
 #endif
+
   SkFontConfigInterface::SetGlobal(
       new FontConfigIPC(GetSandboxFD()))->unref();
+
+  // Set the android SkFontMgr for blink. We need to ensure this is done
+  // before the sandbox is initialized to allow the font manager to access
+  // font configuration files on disk.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kAndroidFontsPath)) {
+    std::string android_fonts_dir =
+        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+            switches::kAndroidFontsPath);
+
+    if (android_fonts_dir.size() > 0 && android_fonts_dir.back() != '/')
+      android_fonts_dir += '/';
+    std::string font_config = android_fonts_dir + "fonts.xml";
+    SkFontMgr_Android_CustomFonts custom;
+    custom.fSystemFontUse =
+        SkFontMgr_Android_CustomFonts::SystemFontUse::kOnlyCustom;
+    custom.fBasePath = android_fonts_dir.c_str();
+    custom.fFontsXml = font_config.c_str();
+    custom.fFallbackFontsXml = nullptr;
+    custom.fIsolated = true;
+
+    blink::WebFontRendering::setSkiaFontManager(SkFontMgr_New_Android(&custom));
+  }
 }
 
 static bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback) {
diff --git a/docs/ios_build_instructions.md b/docs/ios_build_instructions.md
index 8a4e60b7..068c0f0 100644
--- a/docs/ios_build_instructions.md
+++ b/docs/ios_build_instructions.md
@@ -98,7 +98,7 @@
 1.  Add `target_os = [ "ios" ]` to the bottom of your `chromium/.gclient`
 file.
 
-1.  Make sure you have the following in your `chromium/chromium.gyp_env`
+2.  Make sure you have the following in your `chromium/chromium.gyp_env`
 file (removing the `chromium_ios_signing=0` if you want to make
 developer-signed builds):
 
@@ -109,7 +109,7 @@
 }
 ```
 
-1.  Make sure to sync again to fetch the iOS specific dependencies and
+3.  Make sure to sync again to fetch the iOS specific dependencies and
 regenerate build rules using:
 
 ```shell
diff --git a/docs/user_handle_mapping.md b/docs/user_handle_mapping.md
index 8c688a5..e3559a0 100644
--- a/docs/user_handle_mapping.md
+++ b/docs/user_handle_mapping.md
@@ -69,7 +69,7 @@
 | msw               | msw\_           | msw             |
 | nick              | nickcarter      | ncarter         |
 | oleg              |                 | olege           |
-| ortuno            | gortuno         | ortuno          |
+| ortuno            | ortuno          | ortuno          |
 | pam               | pamg            | pamg            |
 | paulirish         | paul\_irish      | paulirish       |
 | patrick           | pjohnson        | pjohnson        |
diff --git a/extensions/browser/api/web_request/form_data_parser.cc b/extensions/browser/api/web_request/form_data_parser.cc
index 0da2023..3d73e6d 100644
--- a/extensions/browser/api/web_request/form_data_parser.cc
+++ b/extensions/browser/api/web_request/form_data_parser.cc
@@ -352,7 +352,8 @@
 FormDataParser::FormDataParser() {}
 
 const net::UnescapeRule::Type FormDataParserUrlEncoded::unescape_rules_ =
-    net::UnescapeRule::URL_SPECIAL_CHARS |
+    net::UnescapeRule::PATH_SEPARATORS |
+    net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
     net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | net::UnescapeRule::SPACES |
     net::UnescapeRule::REPLACE_PLUS_WITH_SPACE;
 
diff --git a/extensions/browser/extension_api_frame_id_map.cc b/extensions/browser/extension_api_frame_id_map.cc
index 53ee551..cce1638 100644
--- a/extensions/browser/extension_api_frame_id_map.cc
+++ b/extensions/browser/extension_api_frame_id_map.cc
@@ -152,21 +152,35 @@
 }
 
 ExtensionApiFrameIdMap::FrameData ExtensionApiFrameIdMap::LookupFrameDataOnUI(
-    const RenderFrameIdKey& key) {
+    const RenderFrameIdKey& key,
+    bool for_lookup) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
+  bool lookup_successful = false;
+  FrameData data;
   FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find(key);
-  if (frame_id_iter != frame_data_map_.end())
-    return frame_id_iter->second;
+  if (frame_id_iter != frame_data_map_.end()) {
+    lookup_successful = true;
+    data = frame_id_iter->second;
+  } else {
+    data = KeyToValue(key);
+    // Don't save invalid values in the map.
+    if (data.frame_id != kInvalidFrameId) {
+      lookup_successful = true;
+      auto kvpair = FrameDataMap::value_type(key, data);
+      base::AutoLock lock(frame_data_map_lock_);
+      frame_data_map_.insert(kvpair);
+    }
+  }
 
-  FrameData cached_frame_data = KeyToValue(key);
-  // Don't save invalid values in the map.
-  if (cached_frame_data.frame_id == kInvalidFrameId)
-    return cached_frame_data;
+  // TODO(devlin): Depending on how the data looks, this may be removable after
+  // a few cycles. Check back in M52 to see if it's still needed.
+  if (for_lookup) {
+    UMA_HISTOGRAM_BOOLEAN("Extensions.ExtensionFrameMapLookupSuccessful",
+                          lookup_successful);
+  }
 
-  auto kvpair = FrameDataMap::value_type(key, cached_frame_data);
-  base::AutoLock lock(frame_data_map_lock_);
-  return frame_data_map_.insert(kvpair).first->second;
+  return data;
 }
 
 void ExtensionApiFrameIdMap::ReceivedFrameDataOnIO(
@@ -244,7 +258,7 @@
   content::BrowserThread::PostTaskAndReplyWithResult(
       content::BrowserThread::UI, FROM_HERE,
       base::Bind(&ExtensionApiFrameIdMap::LookupFrameDataOnUI,
-                 base::Unretained(this), key),
+                 base::Unretained(this), key, true /* for lookup */),
       base::Bind(&ExtensionApiFrameIdMap::ReceivedFrameDataOnIO,
                  base::Unretained(this), key));
 }
@@ -262,15 +276,17 @@
   // A valid routing ID is only meaningful with a valid process ID.
   DCHECK_GE(render_process_id, 0);
 
-  base::AutoLock lock(frame_data_map_lock_);
-  FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find(
-      RenderFrameIdKey(render_process_id, frame_routing_id));
   bool found = false;
-  if (frame_id_iter != frame_data_map_.end()) {
-    // This is very likely to happen because CacheFrameId() is called as soon
-    // as the frame is created.
-    *frame_data_out = frame_id_iter->second;
-    found = true;
+  {
+    base::AutoLock lock(frame_data_map_lock_);
+    FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find(
+        RenderFrameIdKey(render_process_id, frame_routing_id));
+    if (frame_id_iter != frame_data_map_.end()) {
+      // This is very likely to happen because CacheFrameId() is called as soon
+      // as the frame is created.
+      *frame_data_out = frame_id_iter->second;
+      found = true;
+    }
   }
 
   // TODO(devlin): Depending on how the data looks, this may be removable after
@@ -288,7 +304,7 @@
 }
 
 void ExtensionApiFrameIdMap::CacheFrameData(const RenderFrameIdKey& key) {
-  LookupFrameDataOnUI(key);
+  LookupFrameDataOnUI(key, false /* not for lookup */);
 }
 
 void ExtensionApiFrameIdMap::RemoveFrameData(content::RenderFrameHost* rfh) {
diff --git a/extensions/browser/extension_api_frame_id_map.h b/extensions/browser/extension_api_frame_id_map.h
index 6c661ff5..d98cf88 100644
--- a/extensions/browser/extension_api_frame_id_map.h
+++ b/extensions/browser/extension_api_frame_id_map.h
@@ -159,7 +159,10 @@
   // virtual for testing.
   virtual FrameData KeyToValue(const RenderFrameIdKey& key) const;
 
-  FrameData LookupFrameDataOnUI(const RenderFrameIdKey& key);
+  // Looks up the data for the given |key| and adds it to the |frame_data_map_|.
+  // |for_lookup| indicates whether this is for a pending lookup (as opposed to
+  // preemptively caching the frame data).
+  FrameData LookupFrameDataOnUI(const RenderFrameIdKey& key, bool for_lookup);
 
   // Called as soon as the frame ID is found for the given |key|, and runs all
   // queued callbacks with |cached_frame_id_pair|.
diff --git a/extensions/common/features/base_feature_provider.cc b/extensions/common/features/base_feature_provider.cc
index 4f31527..8bcec82c 100644
--- a/extensions/common/features/base_feature_provider.cc
+++ b/extensions/common/features/base_feature_provider.cc
@@ -11,6 +11,7 @@
 
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
+#include "base/values.h"
 #include "extensions/common/extensions_client.h"
 #include "extensions/common/features/complex_feature.h"
 #include "extensions/common/features/simple_feature.h"
@@ -52,7 +53,7 @@
     }
 
     if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) {
-      linked_ptr<SimpleFeature> feature((*factory_)());
+      scoped_ptr<SimpleFeature> feature((*factory_)());
 
       std::vector<std::string> split = base::SplitString(
           iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
@@ -106,7 +107,7 @@
       if (parse_error)
         continue;
 
-      features_[iter.key()] = feature;
+      features_[iter.key()] = std::move(feature);
     } else if (iter.value().GetType() == base::Value::TYPE_LIST) {
       // This is a complex feature.
       const base::ListValue* list =
@@ -133,11 +134,11 @@
         features->push_back(std::move(feature));
       }
 
-      linked_ptr<ComplexFeature> feature(
+      scoped_ptr<ComplexFeature> feature(
           new ComplexFeature(std::move(features)));
       feature->set_name(iter.key());
 
-      features_[iter.key()] = feature;
+      features_[iter.key()] = std::move(feature);
     } else {
       LOG(ERROR) << iter.key() << ": Feature description must be dictionary or"
                  << " list of dictionaries.";
@@ -151,10 +152,8 @@
 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames()
     const {
   if (feature_names_.empty()) {
-    for (FeatureMap::const_iterator iter = features_.begin();
-         iter != features_.end(); ++iter) {
-      feature_names_.push_back(iter->first);
-    }
+    for (const auto& feature : features_)
+      feature_names_.push_back(feature.first);
     // A std::map is sorted by its keys, so we don't need to sort feature_names_
     // now.
   }
@@ -162,7 +161,7 @@
 }
 
 Feature* BaseFeatureProvider::GetFeature(const std::string& name) const {
-  FeatureMap::const_iterator iter = features_.find(name);
+  const auto iter = features_.find(name);
   if (iter != features_.end())
     return iter->second.get();
   else
@@ -187,17 +186,15 @@
 std::vector<Feature*> BaseFeatureProvider::GetChildren(const Feature& parent)
     const {
   std::string prefix = parent.name() + ".";
-  const FeatureMap::const_iterator first_child = features_.lower_bound(prefix);
+  const auto first_child = features_.lower_bound(prefix);
 
   // All children have names before (parent.name() + ('.'+1)).
   ++prefix[prefix.size() - 1];
-  const FeatureMap::const_iterator after_children =
-      features_.lower_bound(prefix);
+  const auto after_children = features_.lower_bound(prefix);
 
   std::vector<Feature*> result;
   result.reserve(std::distance(first_child, after_children));
-  for (FeatureMap::const_iterator it = first_child; it != after_children;
-       ++it) {
+  for (auto it = first_child; it != after_children; ++it) {
     result.push_back(it->second.get());
   }
   return result;
diff --git a/extensions/common/features/base_feature_provider.h b/extensions/common/features/base_feature_provider.h
index e82c46d5..3b766c80 100644
--- a/extensions/common/features/base_feature_provider.h
+++ b/extensions/common/features/base_feature_provider.h
@@ -9,11 +9,14 @@
 #include <string>
 #include <vector>
 
-#include "base/memory/linked_ptr.h"
-#include "base/values.h"
+#include "base/memory/scoped_ptr.h"
 #include "extensions/common/features/feature_provider.h"
 #include "extensions/common/features/simple_feature.h"
 
+namespace Base {
+class DictionaryValue;
+}
+
 namespace extensions {
 
 // Reads Features out of a simple JSON file description.
@@ -35,8 +38,7 @@
   const std::vector<std::string>& GetAllFeatureNames() const override;
 
  private:
-  typedef std::map<std::string, linked_ptr<Feature> > FeatureMap;
-  FeatureMap features_;
+  std::map<std::string, scoped_ptr<Feature>> features_;
 
   // Populated on first use.
   mutable std::vector<std::string> feature_names_;
diff --git a/extensions/common/features/feature_provider.cc b/extensions/common/features/feature_provider.cc
index 7f93ba9..e420094a 100644
--- a/extensions/common/features/feature_provider.cc
+++ b/extensions/common/features/feature_provider.cc
@@ -8,7 +8,7 @@
 
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
-#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/common/content_switches.h"
@@ -23,7 +23,7 @@
 class Static {
  public:
   FeatureProvider* GetFeatures(const std::string& name) const {
-    FeatureProviderMap::const_iterator it = feature_providers_.find(name);
+    auto it = feature_providers_.find(name);
     if (it == feature_providers_.end())
       CRASH_WITH_MINIDUMP("FeatureProvider \"" + name + "\" not found");
     return it->second.get();
@@ -37,14 +37,11 @@
     base::Time begin_time = base::Time::Now();
 
     ExtensionsClient* client = ExtensionsClient::Get();
-    feature_providers_["api"] =
-        make_linked_ptr(client->CreateFeatureProvider("api").release());
-    feature_providers_["manifest"] =
-        make_linked_ptr(client->CreateFeatureProvider("manifest").release());
+    feature_providers_["api"] = client->CreateFeatureProvider("api");
+    feature_providers_["manifest"] = client->CreateFeatureProvider("manifest");
     feature_providers_["permission"] =
-        make_linked_ptr(client->CreateFeatureProvider("permission").release());
-    feature_providers_["behavior"] =
-        make_linked_ptr(client->CreateFeatureProvider("behavior").release());
+        client->CreateFeatureProvider("permission");
+    feature_providers_["behavior"] = client->CreateFeatureProvider("behavior");
 
     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
     std::string process_type =
@@ -61,10 +58,7 @@
     }
   }
 
-  typedef std::map<std::string, linked_ptr<FeatureProvider> >
-      FeatureProviderMap;
-
-  FeatureProviderMap feature_providers_;
+  std::map<std::string, scoped_ptr<FeatureProvider>> feature_providers_;
 };
 
 base::LazyInstance<Static> g_static = LAZY_INSTANCE_INITIALIZER;
diff --git a/extensions/renderer/activity_log_converter_strategy_unittest.cc b/extensions/renderer/activity_log_converter_strategy_unittest.cc
index 9237cad..aa80447 100644
--- a/extensions/renderer/activity_log_converter_strategy_unittest.cc
+++ b/extensions/renderer/activity_log_converter_strategy_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/values.h"
 #include "extensions/renderer/activity_log_converter_strategy.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 using content::V8ValueConverter;
@@ -122,6 +123,7 @@
       "};"
       "})();";
 
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
   v8::Local<v8::Script> script(
       v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
   v8::Local<v8::Object> v8_object = script->Run().As<v8::Object>();
diff --git a/extensions/renderer/api_test_base.cc b/extensions/renderer/api_test_base.cc
index abf868b..79f95e27 100644
--- a/extensions/renderer/api_test_base.cc
+++ b/extensions/renderer/api_test_base.cc
@@ -214,7 +214,7 @@
 }
 
 void ApiTestEnvironment::RunPromisesAgain() {
-  env()->isolate()->RunMicrotasks();
+  v8::MicrotasksScope::PerformCheckpoint(env()->isolate());
   base::MessageLoop::current()->PostTask(
       FROM_HERE, base::Bind(&ApiTestEnvironment::RunPromisesAgain,
                             base::Unretained(this)));
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc
index 68c4bd1f..06a4d55 100644
--- a/extensions/renderer/module_system_test.cc
+++ b/extensions/renderer/module_system_test.cc
@@ -253,7 +253,7 @@
 }
 
 void ModuleSystemTest::RunResolvedPromises() {
-  isolate_->RunMicrotasks();
+  v8::MicrotasksScope::PerformCheckpoint(isolate_);
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/safe_builtins.cc b/extensions/renderer/safe_builtins.cc
index 3bfa01a..3a66eaf1 100644
--- a/extensions/renderer/safe_builtins.cc
+++ b/extensions/renderer/safe_builtins.cc
@@ -9,6 +9,7 @@
 #include "base/strings/stringprintf.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/v8_helpers.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 
 namespace extensions {
 
@@ -200,6 +201,7 @@
         return;
     }
 
+    blink::WebScopedMicrotaskSuppression microtasks_scope;
     v8::Local<v8::Value> return_value;
     if (function->Call(context, recv, argc, argv.get()).ToLocal(&return_value))
       info.GetReturnValue().Set(return_value);
diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h
index d1e703e..ad37a5c4 100644
--- a/gin/public/v8_platform.h
+++ b/gin/public/v8_platform.h
@@ -19,6 +19,7 @@
   static V8Platform* Get();
 
   // v8::Platform implementation.
+  size_t NumberOfAvailableBackgroundThreads() override;
   void CallOnBackgroundThread(
       v8::Task* task,
       v8::Platform::ExpectedRuntime expected_runtime) override;
diff --git a/gin/run_microtasks_observer.cc b/gin/run_microtasks_observer.cc
index f453a66a..0ca00787 100644
--- a/gin/run_microtasks_observer.cc
+++ b/gin/run_microtasks_observer.cc
@@ -15,7 +15,7 @@
 
 void RunMicrotasksObserver::DidProcessTask(const base::PendingTask& task) {
   v8::Isolate::Scope scope(isolate_);
-  isolate_->RunMicrotasks();
+  v8::MicrotasksScope::PerformCheckpoint(isolate_);
 }
 
 }  // namespace gin
diff --git a/gin/run_microtasks_observer.h b/gin/run_microtasks_observer.h
index 7f1431f..ca160be 100644
--- a/gin/run_microtasks_observer.h
+++ b/gin/run_microtasks_observer.h
@@ -12,7 +12,7 @@
 
 // Runs any pending v8 Microtasks each time a task is completed.
 // TODO(hansmuller); At some point perhaps this can be replaced with
-// the (currently experimental) Isolate::SetAutorunMicrotasks() method.
+// the (currently experimental) v8::MicrotasksPolicy::kAuto method.
 
 class RunMicrotasksObserver : public base::MessageLoop::TaskObserver {
  public:
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc
index be7f5c2..556f7fc 100644
--- a/gin/v8_platform.cc
+++ b/gin/v8_platform.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/location.h"
+#include "base/sys_info.h"
 #include "base/threading/worker_pool.h"
 #include "base/trace_event/trace_event.h"
 #include "gin/per_isolate_data.h"
@@ -25,6 +26,19 @@
 
 V8Platform::~V8Platform() {}
 
+size_t V8Platform::NumberOfAvailableBackgroundThreads() {
+  // WorkerPool will currently always create additional threads for posted
+  // background tasks, unless there are threads sitting idle (on posix).
+  // Indicate that V8 should create no more than the number of cores available,
+  // reserving one core for the main thread.
+  const size_t available_cores =
+    static_cast<size_t>(base::SysInfo::NumberOfProcessors());
+  if (available_cores > 1) {
+    return available_cores - 1;
+  }
+  return 1;
+}
+
 void V8Platform::CallOnBackgroundThread(
     v8::Task* task,
     v8::Platform::ExpectedRuntime expected_runtime) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index a3ad4233..ca92243 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -11117,9 +11117,10 @@
         "glCompressedTexSubImage3D", format, "format");
     return;
   }
-  if (width < 0 || height < 0 || depth < 0) {
+  if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) {
     LOCAL_SET_GL_ERROR(
-        GL_INVALID_VALUE, "glCompressedTexSubImage3D", "size < 0");
+        GL_INVALID_VALUE,
+        "glCompressedTexSubImage3D", "dimensions out of range");
     return;
   }
   if (image_size < 0) {
@@ -11341,6 +11342,12 @@
         "glCompressedTexSubImage2D", "unknown texture for target");
     return;
   }
+  if (!texture_manager()->ValidForTarget(target, level, width, height, 1)) {
+    LOCAL_SET_GL_ERROR(
+        GL_INVALID_VALUE,
+        "glCompressedTexSubImage2D", "dimensions out of range");
+    return;
+  }
   Texture* texture = texture_ref->texture();
   GLenum type = 0;
   GLenum internal_format = 0;
diff --git a/gpu/command_buffer/service/gpu_preferences.h b/gpu/command_buffer/service/gpu_preferences.h
index 0c6a8839..2721e272 100644
--- a/gpu/command_buffer/service/gpu_preferences.h
+++ b/gpu/command_buffer/service/gpu_preferences.h
@@ -66,10 +66,10 @@
   bool enforce_gl_minimums = false;
 
   // Sets the total amount of memory that may be allocated for GPU resources
-  size_t force_gpu_mem_available = 0;
+  uint32_t force_gpu_mem_available = 0;
 
   // Sets the maximum size of the in-memory gpu program cache, in kb
-  size_t gpu_program_cache_size = kDefaultMaxProgramCacheMemoryBytes;
+  uint32_t gpu_program_cache_size = kDefaultMaxProgramCacheMemoryBytes;
 
   // Disables the GPU shader on disk cache.
   bool disable_gpu_shader_disk_cache = false;
diff --git a/gpu/command_buffer/service/gpu_switches.cc b/gpu/command_buffer/service/gpu_switches.cc
index a02c484..389afcb 100644
--- a/gpu/command_buffer/service/gpu_switches.cc
+++ b/gpu/command_buffer/service/gpu_switches.cc
@@ -71,27 +71,4 @@
 // round intermediate values in ANGLE.
 const char kEmulateShaderPrecision[] = "emulate-shader-precision";
 
-const char* kGpuSwitches[] = {
-    kCompileShaderAlwaysSucceeds,
-    kDisableGLErrorLimit,
-    kDisableGLSLTranslator,
-    kDisableGpuDriverBugWorkarounds,
-    kDisableShaderNameHashing,
-    kEnableGPUCommandLogging,
-    kEnableGPUDebugging,
-    kEnableGPUServiceLoggingGPU,
-    kDisableGpuProgramCache,
-    kEnforceGLMinimums,
-    kForceGpuMemAvailableMb,
-    kGpuDriverBugWorkarounds,
-    kGpuProgramCacheSizeKb,
-    kDisableGpuShaderDiskCache,
-    kEnableShareGroupAsyncTextureUpload,
-    kEnableSubscribeUniformExtension,
-    kGLShaderIntermOutput,
-    kEmulateShaderPrecision,
-};
-
-const int kNumGpuSwitches = arraysize(kGpuSwitches);
-
 }  // namespace switches
diff --git a/gpu/command_buffer/service/gpu_switches.h b/gpu/command_buffer/service/gpu_switches.h
index ac6883a..5b50e0b 100644
--- a/gpu/command_buffer/service/gpu_switches.h
+++ b/gpu/command_buffer/service/gpu_switches.h
@@ -31,9 +31,6 @@
 GPU_EXPORT extern const char kGLShaderIntermOutput[];
 GPU_EXPORT extern const char kEmulateShaderPrecision[];
 
-GPU_EXPORT extern const char* kGpuSwitches[];
-GPU_EXPORT extern const int kNumGpuSwitches;
-
 }  // namespace switches
 
 #endif  // GPU_COMMAND_BUFFER_SERVICE_GPU_SWITCHES_H_
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index 995f15a0..325a1e6 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
 {
   "name": "gpu driver bug list",
   // Please update the version number whenever you change this file.
-  "version": "8.46",
+  "version": "8.47",
   "entries": [
     {
       "id": 1,
@@ -190,7 +190,11 @@
       "id": 12,
       "description": "Limit max cube map texure size to 1024 on Macs with Intel GPUs",
       "os": {
-        "type": "macosx"
+        "type": "macosx",
+        "version": {
+          "op": "<",
+          "value": "10.10"
+        }
       },
       "vendor_id": "0x8086",
       "features": [
diff --git a/headless/lib/browser/headless_url_request_context_getter.cc b/headless/lib/browser/headless_url_request_context_getter.cc
index 4e8a1954..de1ad37 100644
--- a/headless/lib/browser/headless_url_request_context_getter.cc
+++ b/headless/lib/browser/headless_url_request_context_getter.cc
@@ -12,6 +12,7 @@
 #include "content/public/browser/cookie_store_factory.h"
 #include "content/public/common/content_switches.h"
 #include "net/cert/cert_verifier.h"
+#include "net/cookies/cookie_store.h"
 #include "net/dns/host_resolver.h"
 #include "net/dns/mapped_host_resolver.h"
 #include "net/http/http_auth_handler_factory.h"
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.h b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.h
index 28f7e77..77f75bc 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.h
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.h
@@ -19,6 +19,7 @@
 }
 
 namespace net {
+class CookieStore;
 class HttpNetworkSession;
 class HttpServerPropertiesManager;
 class HttpTransactionFactory;
@@ -141,6 +142,8 @@
   // maintain destruction ordering.
   mutable net::HttpServerPropertiesManager* http_server_properties_manager_;
 
+  mutable scoped_ptr<net::CookieStore> main_cookie_store_;
+
   mutable scoped_ptr<net::URLRequestJobFactory> main_job_factory_;
 
   mutable scoped_ptr<net::SdchManager> sdch_manager_;
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
index 82ea94a..91aedf83 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
@@ -32,6 +32,7 @@
 #include "ios/web/public/web_thread.h"
 #include "net/base/cache_type.h"
 #include "net/base/sdch_manager.h"
+#include "net/cookies/cookie_store.h"
 #include "net/extras/sqlite/sqlite_channel_id_store.h"
 #include "net/http/http_cache.h"
 #include "net/http/http_network_session.h"
@@ -339,28 +340,24 @@
   main_context->set_backoff_manager(
       io_thread_globals->url_request_backoff_manager.get());
 
-  scoped_refptr<net::CookieStore> cookie_store = NULL;
   net::ChannelIDService* channel_id_service = NULL;
 
-  // Set up cookie store.
-  if (!cookie_store.get()) {
-    DCHECK(!lazy_params_->cookie_path.empty());
-    cookie_util::CookieStoreConfig ios_cookie_config(
-        lazy_params_->cookie_path,
-        cookie_util::CookieStoreConfig::RESTORED_SESSION_COOKIES,
-        cookie_util::CookieStoreConfig::COOKIE_STORE_IOS,
-        cookie_config::GetCookieCryptoDelegate());
-    cookie_store = cookie_util::CreateCookieStore(ios_cookie_config);
+  DCHECK(!lazy_params_->cookie_path.empty());
+  cookie_util::CookieStoreConfig ios_cookie_config(
+      lazy_params_->cookie_path,
+      cookie_util::CookieStoreConfig::RESTORED_SESSION_COOKIES,
+      cookie_util::CookieStoreConfig::COOKIE_STORE_IOS,
+      cookie_config::GetCookieCryptoDelegate());
+  main_cookie_store_ = cookie_util::CreateCookieStore(ios_cookie_config);
 
-    if (profile_params->path.BaseName().value() ==
-        kIOSChromeInitialBrowserState) {
-      // Enable metrics on the default profile, not secondary profiles.
-      static_cast<net::CookieStoreIOS*>(cookie_store.get())
-          ->SetMetricsEnabled();
-    }
+  if (profile_params->path.BaseName().value() ==
+      kIOSChromeInitialBrowserState) {
+    // Enable metrics on the default profile, not secondary profiles.
+    static_cast<net::CookieStoreIOS*>(main_cookie_store_.get())
+        ->SetMetricsEnabled();
   }
 
-  main_context->set_cookie_store(cookie_store.get());
+  main_context->set_cookie_store(main_cookie_store_.get());
 
   // Set up server bound cert service.
   if (!channel_id_service) {
@@ -430,11 +427,11 @@
       base::FilePath(),
       cookie_util::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
       cookie_util::CookieStoreConfig::COOKIE_STORE_IOS, nullptr);
-  scoped_refptr<net::CookieStore> cookie_store =
+  scoped_ptr<net::CookieStore> cookie_store =
       cookie_util::CreateCookieStore(ios_cookie_config);
 
   // Transfer ownership of the cookies and cache to AppRequestContext.
-  context->SetCookieStore(cookie_store.get());
+  context->SetCookieStore(std::move(cookie_store));
   context->SetHttpTransactionFactory(std::move(app_http_cache));
 
   scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
index 56f3eba..f29cd00 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
@@ -133,9 +133,9 @@
 ChromeBrowserStateIOData::AppRequestContext::AppRequestContext() {}
 
 void ChromeBrowserStateIOData::AppRequestContext::SetCookieStore(
-    net::CookieStore* cookie_store) {
-  cookie_store_ = cookie_store;
-  set_cookie_store(cookie_store);
+    scoped_ptr<net::CookieStore> cookie_store) {
+  cookie_store_ = std::move(cookie_store);
+  set_cookie_store(cookie_store_.get());
 }
 
 void ChromeBrowserStateIOData::AppRequestContext::SetHttpTransactionFactory(
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h
index 3e31231e..038f288 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h
@@ -131,7 +131,7 @@
    public:
     AppRequestContext();
 
-    void SetCookieStore(net::CookieStore* cookie_store);
+    void SetCookieStore(scoped_ptr<net::CookieStore> cookie_store);
     void SetHttpTransactionFactory(
         scoped_ptr<net::HttpTransactionFactory> http_factory);
     void SetJobFactory(scoped_ptr<net::URLRequestJobFactory> job_factory);
@@ -139,7 +139,7 @@
    private:
     ~AppRequestContext() override;
 
-    scoped_refptr<net::CookieStore> cookie_store_;
+    scoped_ptr<net::CookieStore> cookie_store_;
     scoped_ptr<net::HttpTransactionFactory> http_factory_;
     scoped_ptr<net::URLRequestJobFactory> job_factory_;
   };
diff --git a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.h b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.h
index b83c0ec..65995f0 100644
--- a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.h
+++ b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.h
@@ -21,6 +21,7 @@
 }
 
 namespace net {
+class CookieStore;
 class HttpNetworkSession;
 class HttpTransactionFactory;
 class SdchManager;
@@ -104,6 +105,8 @@
   mutable scoped_ptr<net::HttpNetworkSession> http_network_session_;
   mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
 
+  mutable scoped_ptr<net::CookieStore> main_cookie_store_;
+
   mutable scoped_ptr<net::URLRequestJobFactory> main_job_factory_;
 
   // Server bound certificates and cookies are persisted to the disk on iOS.
diff --git a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
index b420e0e..26b3d2b 100644
--- a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
+++ b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
@@ -25,6 +25,7 @@
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/web/public/web_thread.h"
 #include "net/base/sdch_manager.h"
+#include "net/cookies/cookie_store.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/extras/sqlite/sqlite_channel_id_store.h"
 #include "net/ftp/ftp_network_layer.h"
@@ -196,11 +197,12 @@
   set_channel_id_service(channel_id_service);
   main_context->set_channel_id_service(channel_id_service);
 
-  main_context->set_cookie_store(
+  main_cookie_store_ =
       cookie_util::CreateCookieStore(cookie_util::CookieStoreConfig(
           cookie_path_,
           cookie_util::CookieStoreConfig::RESTORED_SESSION_COOKIES,
-          cookie_util::CookieStoreConfig::COOKIE_STORE_IOS, nullptr)));
+          cookie_util::CookieStoreConfig::COOKIE_STORE_IOS, nullptr));
+  main_context->set_cookie_store(main_cookie_store_.get());
 
   http_network_session_ = CreateHttpNetworkSession(*profile_params);
   main_http_factory_ = CreateMainHttpFactory(
diff --git a/ios/chrome/browser/ios_chrome_io_thread.h b/ios/chrome/browser/ios_chrome_io_thread.h
index 67faf2d0..f300a7f 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.h
+++ b/ios/chrome/browser/ios_chrome_io_thread.h
@@ -127,7 +127,7 @@
     scoped_ptr<net::URLRequestJobFactory> system_url_request_job_factory;
     scoped_ptr<net::URLRequestContext> system_request_context;
     SystemRequestContextLeakChecker system_request_context_leak_checker;
-    scoped_refptr<net::CookieStore> system_cookie_store;
+    scoped_ptr<net::CookieStore> system_cookie_store;
     scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings;
     scoped_ptr<net::NetworkQualityEstimator> network_quality_estimator;
     uint16_t testing_fixed_http_port;
diff --git a/ios/chrome/browser/ios_chrome_io_thread.mm b/ios/chrome/browser/ios_chrome_io_thread.mm
index 61dfa99..ef492dc 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.mm
+++ b/ios/chrome/browser/ios_chrome_io_thread.mm
@@ -429,7 +429,7 @@
   CreateDefaultAuthHandlerFactory();
   globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl());
   // In-memory cookie store.
-  globals_->system_cookie_store = new net::CookieMonster(nullptr, nullptr);
+  globals_->system_cookie_store.reset(new net::CookieMonster(nullptr, nullptr));
   // In-memory channel ID store.
   globals_->system_channel_id_service.reset(
       new net::ChannelIDService(new net::DefaultChannelIDStore(nullptr),
diff --git a/ios/chrome/browser/net/cookie_util.h b/ios/chrome/browser/net/cookie_util.h
index 1b85e04..1f21f08c 100644
--- a/ios/chrome/browser/net/cookie_util.h
+++ b/ios/chrome/browser/net/cookie_util.h
@@ -74,7 +74,7 @@
 
 // Creates a cookie store wich is internally either a CookieMonster or a
 // CookieStoreIOS.
-net::CookieStore* CreateCookieStore(const CookieStoreConfig& config);
+scoped_ptr<net::CookieStore> CreateCookieStore(const CookieStoreConfig& config);
 
 // Returns true if the cookies should be cleared.
 // Current implementation returns true if the device has rebooted since the
diff --git a/ios/chrome/browser/net/cookie_util.mm b/ios/chrome/browser/net/cookie_util.mm
index d422adba..6b2520fd 100644
--- a/ios/chrome/browser/net/cookie_util.mm
+++ b/ios/chrome/browser/net/cookie_util.mm
@@ -44,10 +44,11 @@
 }
 
 // Creates a CookieMonster configured by |config|.
-net::CookieMonster* CreateCookieMonster(const CookieStoreConfig& config) {
+scoped_ptr<net::CookieMonster> CreateCookieMonster(
+    const CookieStoreConfig& config) {
   if (config.path.empty()) {
     // Empty path means in-memory store.
-    return new net::CookieMonster(nullptr, nullptr);
+    return make_scoped_ptr(new net::CookieMonster(nullptr, nullptr));
   }
 
   const bool restore_old_session_cookies =
@@ -55,8 +56,8 @@
   scoped_refptr<net::SQLitePersistentCookieStore> persistent_store =
       CreatePersistentCookieStore(config.path, restore_old_session_cookies,
                                   config.crypto_delegate);
-  net::CookieMonster* cookie_monster =
-      new net::CookieMonster(persistent_store.get(), nullptr);
+  scoped_ptr<net::CookieMonster> cookie_monster(
+      new net::CookieMonster(persistent_store.get(), nullptr));
   if (restore_old_session_cookies)
     cookie_monster->SetPersistSessionCookies(true);
   return cookie_monster;
@@ -77,7 +78,8 @@
 
 CookieStoreConfig::~CookieStoreConfig() {}
 
-net::CookieStore* CreateCookieStore(const CookieStoreConfig& config) {
+scoped_ptr<net::CookieStore> CreateCookieStore(
+    const CookieStoreConfig& config) {
   if (config.cookie_store_type == CookieStoreConfig::COOKIE_MONSTER)
     return CreateCookieMonster(config);
 
@@ -89,7 +91,7 @@
         config.path, true /* restore_old_session_cookies */,
         config.crypto_delegate);
   }
-  return new net::CookieStoreIOS(persistent_store.get());
+  return make_scoped_ptr(new net::CookieStoreIOS(persistent_store.get()));
 }
 
 bool ShouldClearSessionCookies() {
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service.cc b/ios/chrome/browser/safe_browsing/safe_browsing_service.cc
index 5372c4a..37244926 100644
--- a/ios/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/ios/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -90,6 +90,8 @@
 
   scoped_refptr<net::URLRequestContextGetter> system_context_getter_;
 
+  scoped_ptr<net::CookieStore> safe_browsing_cookie_store_;
+
   scoped_ptr<net::URLRequestContext> safe_browsing_request_context_;
 
   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
@@ -126,9 +128,10 @@
             web::WebThread::GetBlockingPool()->GetSequencedTaskRunner(
                 web::WebThread::GetBlockingPool()->GetSequenceToken()),
             false, nullptr));
-
-    safe_browsing_request_context_->set_cookie_store(
+    safe_browsing_cookie_store_.reset(
         new net::CookieMonster(sqlite_store.get(), nullptr));
+    safe_browsing_request_context_->set_cookie_store(
+        safe_browsing_cookie_store_.get());
   }
 
   return safe_browsing_request_context_.get();
diff --git a/ios/chrome/browser/web/resubmit_data_controller.h b/ios/chrome/browser/web/resubmit_data_controller.h
new file mode 100644
index 0000000..0f847d7
--- /dev/null
+++ b/ios/chrome/browser/web/resubmit_data_controller.h
@@ -0,0 +1,30 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_WEB_RESUBMIT_DATA_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_WEB_RESUBMIT_DATA_CONTROLLER_H_
+
+#import <UIKit/UIKit.h>
+
+#import "base/ios/block_types.h"
+
+// Handles the action sheet that is presenting to confirm POST data
+// resubmission.
+@interface ResubmitDataController : NSObject
+
+- (instancetype)initWithContinueBlock:(ProceduralBlock)continueBlock
+                          cancelBlock:(ProceduralBlock)cancelBlock
+    NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+// Presents the action sheet. On regular horizontal size class, it is presented
+// in a popover from |rect| in |view|.
+- (void)presentActionSheetFromRect:(CGRect)rect inView:(UIView*)view;
+
+// Dismisses the action sheet.
+- (void)dismissActionSheet;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_WEB_RESUBMIT_DATA_CONTROLLER_H_
diff --git a/ios/chrome/browser/web/resubmit_data_controller.mm b/ios/chrome/browser/web/resubmit_data_controller.mm
new file mode 100644
index 0000000..4092bd38
--- /dev/null
+++ b/ios/chrome/browser/web/resubmit_data_controller.mm
@@ -0,0 +1,88 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/web/resubmit_data_controller.h"
+
+#import "base/logging.h"
+#include "base/mac/scoped_block.h"
+#import "base/mac/scoped_nsobject.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+@interface ResubmitDataController () {
+  base::scoped_nsobject<UIAlertController> _alertController;
+}
+@end
+
+@implementation ResubmitDataController
+
+- (instancetype)init {
+  NOTREACHED();
+  return nil;
+}
+
+- (instancetype)initWithContinueBlock:(ProceduralBlock)continueBlock
+                          cancelBlock:(ProceduralBlock)cancelBlock {
+  DCHECK(continueBlock);
+  DCHECK(cancelBlock);
+  self = [super init];
+  if (self) {
+    NSString* message = [NSString
+        stringWithFormat:@"%@\n\n%@",
+                         l10n_util::GetNSString(IDS_HTTP_POST_WARNING_TITLE),
+                         l10n_util::GetNSString(IDS_HTTP_POST_WARNING)];
+    NSString* buttonTitle =
+        l10n_util::GetNSString(IDS_HTTP_POST_WARNING_RESEND);
+    NSString* cancelTitle = l10n_util::GetNSString(IDS_CANCEL);
+
+    _alertController.reset([[UIAlertController
+        alertControllerWithTitle:nil
+                         message:message
+                  preferredStyle:UIAlertControllerStyleActionSheet] retain]);
+
+    // Make sure the blocks are located on the heap.
+    base::mac::ScopedBlock<ProceduralBlock> guaranteeOnHeap;
+    guaranteeOnHeap.reset([continueBlock copy]);
+    guaranteeOnHeap.reset([cancelBlock copy]);
+
+    UIAlertAction* cancelAction =
+        [UIAlertAction actionWithTitle:cancelTitle
+                                 style:UIAlertActionStyleCancel
+                               handler:^(UIAlertAction* _Nonnull action) {
+                                 cancelBlock();
+                               }];
+    [_alertController addAction:cancelAction];
+    UIAlertAction* continueAction =
+        [UIAlertAction actionWithTitle:buttonTitle
+                                 style:UIAlertActionStyleDefault
+                               handler:^(UIAlertAction* _Nonnull action) {
+                                 continueBlock();
+                               }];
+    [_alertController addAction:continueAction];
+  }
+  return self;
+}
+
+- (void)presentActionSheetFromRect:(CGRect)rect inView:(UIView*)view {
+  _alertController.get().modalPresentationStyle = UIModalPresentationPopover;
+  UIPopoverPresentationController* popPresenter =
+      _alertController.get().popoverPresentationController;
+  popPresenter.sourceView = view;
+  popPresenter.sourceRect = rect;
+
+  UIViewController* topController = view.window.rootViewController;
+  while (topController.presentedViewController)
+    topController = topController.presentedViewController;
+  [topController presentViewController:_alertController
+                              animated:YES
+                            completion:nil];
+}
+
+- (void)dismissActionSheet {
+  [_alertController.get().presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:nil];
+}
+
+@end
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index c117524..5b2fb99 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -655,6 +655,8 @@
         'browser/web/dom_altering_lock.mm',
         'browser/web/web_view_type_util.h',
         'browser/web/web_view_type_util.mm',
+        'browser/web/resubmit_data_controller.h',
+        'browser/web/resubmit_data_controller.mm',
         'browser/web_data_service_factory.cc',
         'browser/web_data_service_factory.h',
         'browser/web_resource/web_resource_util.cc',
diff --git a/ios/crnet/crnet_environment.h b/ios/crnet/crnet_environment.h
index 6091ee0..a0b49c1 100644
--- a/ios/crnet/crnet_environment.h
+++ b/ios/crnet/crnet_environment.h
@@ -17,6 +17,7 @@
 class JsonPrefStore;
 
 namespace net {
+class CookieStore;
 class HttpCache;
 class NetworkChangeNotifier;
 class NetLog;
@@ -155,6 +156,7 @@
   scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
   scoped_ptr<net::ProxyConfigService> proxy_config_service_;
   scoped_ptr<net::HttpServerProperties> http_server_properties_;
+  scoped_ptr<net::CookieStore> cookie_store_;
   scoped_refptr<net::URLRequestContextGetter> main_context_getter_;
   scoped_ptr<net::URLRequestContext> main_context_;
   scoped_ptr<CrNetHttpProtocolHandlerDelegate> http_protocol_handler_delegate_;
diff --git a/ios/crnet/crnet_environment.mm b/ios/crnet/crnet_environment.mm
index da988756..128d76b 100644
--- a/ios/crnet/crnet_environment.mm
+++ b/ios/crnet/crnet_environment.mm
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/at_exit.h"
+#include "base/atomicops.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -38,6 +39,7 @@
 #include "net/base/sdch_manager.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert_net/nss_ocsp.h"
+#include "net/cookies/cookie_store.h"
 #include "net/http/http_auth_handler_factory.h"
 #include "net/http/http_cache.h"
 #include "net/http/http_server_properties_impl.h"
@@ -286,13 +288,14 @@
   proxy_config_service_ = net::ProxyService::CreateSystemProxyConfigService(
       network_io_thread_->task_runner(), nullptr);
 
+  net::SetURLRequestContextForNSSHttpIO(main_context_.get());
+  main_context_getter_ = new CrNetURLRequestContextGetter(
+      main_context_.get(), network_io_thread_->task_runner());
+  base::subtle::MemoryBarrier();
   PostToNetworkThread(FROM_HERE,
       base::Bind(&CrNetEnvironment::InitializeOnNetworkThread,
                  base::Unretained(this)));
 
-  net::SetURLRequestContextForNSSHttpIO(main_context_.get());
-  main_context_getter_ = new CrNetURLRequestContextGetter(
-      main_context_.get(), network_io_thread_->task_runner());
   SetRequestFilterBlock(nil);
 }
 
@@ -465,10 +468,9 @@
   main_context_->set_http_transaction_factory(main_cache);
 
   // Cookies
-  scoped_refptr<net::CookieStore> cookie_store =
-  net::CookieStoreIOS::CreateCookieStore(
+  cookie_store_ = net::CookieStoreIOS::CreateCookieStore(
       [NSHTTPCookieStorage sharedHTTPCookieStorage]);
-  main_context_->set_cookie_store(cookie_store.get());
+  main_context_->set_cookie_store(cookie_store_.get());
 
   net::URLRequestJobFactoryImpl* job_factory =
       new net::URLRequestJobFactoryImpl;
diff --git a/ios/net/cookies/cookie_store_ios.h b/ios/net/cookies/cookie_store_ios.h
index 94bfc7c..914804d1 100644
--- a/ios/net/cookies/cookie_store_ios.h
+++ b/ios/net/cookies/cookie_store_ios.h
@@ -14,6 +14,7 @@
 #include "base/cancelable_callback.h"
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "ios/net/cookies/cookie_cache.h"
@@ -72,6 +73,8 @@
       net::CookieMonster::PersistentCookieStore* persistent_store,
       NSHTTPCookieStorage* system_store);
 
+  ~CookieStoreIOS() override;
+
   enum CookiePolicy { ALLOW, BLOCK };
 
   // Must be called on the thread where CookieStoreIOS instances live.
@@ -84,7 +87,8 @@
   // as its default backend and is initially synchronized with it.
   // Apple does not persist the cookies' creation dates in NSHTTPCookieStorage,
   // so callers should not expect these values to be populated.
-  static CookieStoreIOS* CreateCookieStore(NSHTTPCookieStorage* cookie_storage);
+  static scoped_ptr<CookieStoreIOS> CreateCookieStore(
+      NSHTTPCookieStorage* cookie_storage);
 
   // As there is only one system store, only one CookieStoreIOS at a time may
   // be synchronized with it.
@@ -157,9 +161,6 @@
       const std::string& name,
       const CookieChangedCallback& callback) override;
 
- protected:
-  ~CookieStoreIOS() override;
-
  private:
   // For tests.
   friend struct CookieStoreIOSTestTraits;
@@ -200,7 +201,7 @@
   void DeleteCookiesWithFilter(const CookieFilterFunction& filter,
                                const DeleteCallback& callback);
 
-  scoped_refptr<net::CookieMonster> cookie_monster_;
+  scoped_ptr<net::CookieMonster> cookie_monster_;
   NSHTTPCookieStorage* system_store_;
   scoped_ptr<CookieCreationTimeManager> creation_time_manager_;
   bool metrics_enabled_;
@@ -324,6 +325,8 @@
       CookieChangedHookMap;
   CookieChangedHookMap hook_map_;
 
+  base::WeakPtrFactory<CookieStoreIOS> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(CookieStoreIOS);
 };
 
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm
index 8be649ae..2d3ebda 100644
--- a/ios/net/cookies/cookie_store_ios.mm
+++ b/ios/net/cookies/cookie_store_ios.mm
@@ -292,20 +292,27 @@
 CookieStoreIOS::CookieStoreIOS(
     net::CookieMonster::PersistentCookieStore* persistent_store,
     NSHTTPCookieStorage* system_store)
-    : system_store_(system_store),
+    : cookie_monster_(new net::CookieMonster(persistent_store, nullptr)),
+      system_store_(system_store),
       creation_time_manager_(new CookieCreationTimeManager),
       metrics_enabled_(false),
       flush_delay_(base::TimeDelta::FromSeconds(10)),
       synchronization_state_(NOT_SYNCHRONIZED),
-      cookie_cache_(new CookieCache()) {
+      cookie_cache_(new CookieCache()),
+      weak_factory_(this) {
   DCHECK(system_store);
 
   NotificationTrampoline::GetInstance()->AddObserver(this);
-  cookie_monster_ = new net::CookieMonster(persistent_store, nullptr);
+
   cookie_monster_->SetPersistSessionCookies(true);
   cookie_monster_->SetForceKeepSessionState();
 }
 
+CookieStoreIOS::~CookieStoreIOS() {
+  NotificationTrampoline::GetInstance()->RemoveObserver(this);
+  STLDeleteContainerPairSecondPointers(hook_map_.begin(), hook_map_.end());
+}
+
 // static
 void CookieStoreIOS::SetCookiePolicy(CookiePolicy setting) {
   NSHTTPCookieAcceptPolicy policy = (setting == ALLOW)
@@ -320,7 +327,7 @@
 }
 
 // static
-CookieStoreIOS* CookieStoreIOS::CreateCookieStore(
+scoped_ptr<CookieStoreIOS> CookieStoreIOS::CreateCookieStore(
     NSHTTPCookieStorage* cookie_storage) {
   DCHECK(cookie_storage);
   // TODO(huey): Update this when CrNet supports multiple cookie jars.
@@ -328,7 +335,8 @@
 
   // Create a cookie store with no persistent store backing. Then, populate
   // it from the system's cookie jar.
-  CookieStoreIOS* cookie_store = new CookieStoreIOS(nullptr, cookie_storage);
+  scoped_ptr<CookieStoreIOS> cookie_store(
+      new CookieStoreIOS(nullptr, cookie_storage));
   cookie_store->synchronization_state_ = SYNCHRONIZED;
   cookie_store->FlushStore(base::Closure());
   return cookie_store;
@@ -378,8 +386,9 @@
       break;
     case SYNCHRONIZING:
       tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::SetCookieWithOptionsAsync, this, url,
-                     cookie_line, options, WrapSetCallback(callback)));
+          base::Bind(&CookieStoreIOS::SetCookieWithOptionsAsync,
+                     weak_factory_.GetWeakPtr(), url, cookie_line, options,
+                     WrapSetCallback(callback)));
       break;
     case SYNCHRONIZED:
       // The exclude_httponly() option would only be used by a javascript
@@ -454,11 +463,12 @@
           priority, WrapSetCallback(callback));
       break;
     case SYNCHRONIZING:
-      tasks_pending_synchronization_.push_back(base::Bind(
-          &CookieStoreIOS::SetCookieWithDetailsAsync, this, url, name, value,
-          domain, path, creation_time, expiration_time, last_access_time,
-          secure, http_only, same_site, enforce_strict_secure, priority,
-          WrapSetCallback(callback)));
+      tasks_pending_synchronization_.push_back(
+          base::Bind(&CookieStoreIOS::SetCookieWithDetailsAsync,
+                     weak_factory_.GetWeakPtr(), url, name, value, domain, path,
+                     creation_time, expiration_time, last_access_time, secure,
+                     http_only, same_site, enforce_strict_secure, priority,
+                     WrapSetCallback(callback)));
       break;
     case SYNCHRONIZED:
       // If cookies are not allowed, they are stashed in the CookieMonster, and
@@ -509,8 +519,8 @@
       break;
     case SYNCHRONIZING:
       tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::GetCookiesWithOptionsAsync, this, url,
-                     options, callback));
+          base::Bind(&CookieStoreIOS::GetCookiesWithOptionsAsync,
+                     weak_factory_.GetWeakPtr(), url, options, callback));
       break;
     case SYNCHRONIZED:
       // If cookies are not allowed, they are stashed in the CookieMonster, and
@@ -542,8 +552,8 @@
       break;
     case SYNCHRONIZING:
       tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::GetCookieListWithOptionsAsync, this, url,
-                     options, callback));
+          base::Bind(&CookieStoreIOS::GetCookieListWithOptionsAsync,
+                     weak_factory_.GetWeakPtr(), url, options, callback));
       break;
     case SYNCHRONIZED:
       if (!SystemCookiesAllowed()) {
@@ -573,8 +583,9 @@
       cookie_monster_->GetAllCookiesAsync(callback);
       break;
     case SYNCHRONIZING:
-      tasks_pending_synchronization_.push_back(base::Bind(
-          &CookieStoreIOS::GetAllCookiesAsync, this, callback));
+      tasks_pending_synchronization_.push_back(
+          base::Bind(&CookieStoreIOS::GetAllCookiesAsync,
+                     weak_factory_.GetWeakPtr(), callback));
       break;
     case SYNCHRONIZED:
       if (!SystemCookiesAllowed()) {
@@ -606,9 +617,9 @@
                                          WrapClosure(callback));
       break;
     case SYNCHRONIZING:
-      tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::DeleteCookieAsync, this, url, cookie_name,
-                     WrapClosure(callback)));
+      tasks_pending_synchronization_.push_back(base::Bind(
+          &CookieStoreIOS::DeleteCookieAsync, weak_factory_.GetWeakPtr(), url,
+          cookie_name, WrapClosure(callback)));
       break;
     case SYNCHRONIZED:
       NSArray* cookies = GetCookiesForURL(system_store_,
@@ -637,9 +648,9 @@
                                                   WrapDeleteCallback(callback));
       break;
     case SYNCHRONIZING:
-      tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::DeleteCanonicalCookieAsync, this, cookie,
-                     WrapDeleteCallback(callback)));
+      tasks_pending_synchronization_.push_back(base::Bind(
+          &CookieStoreIOS::DeleteCanonicalCookieAsync,
+          weak_factory_.GetWeakPtr(), cookie, WrapDeleteCallback(callback)));
       break;
     case SYNCHRONIZED:
       // This relies on the fact cookies are given unique creation dates.
@@ -665,8 +676,9 @@
       break;
     case SYNCHRONIZING:
       tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::DeleteAllCreatedBetweenAsync, this,
-                     delete_begin, delete_end, WrapDeleteCallback(callback)));
+          base::Bind(&CookieStoreIOS::DeleteAllCreatedBetweenAsync,
+                     weak_factory_.GetWeakPtr(), delete_begin, delete_end,
+                     WrapDeleteCallback(callback)));
       break;
     case SYNCHRONIZED:
       CookieFilterFunction filter =
@@ -692,9 +704,10 @@
           delete_begin, delete_end, url, WrapDeleteCallback(callback));
       break;
     case SYNCHRONIZING:
-      tasks_pending_synchronization_.push_back(base::Bind(
-          &CookieStoreIOS::DeleteAllCreatedBetweenForHostAsync, this,
-          delete_begin, delete_end, url, WrapDeleteCallback(callback)));
+      tasks_pending_synchronization_.push_back(
+          base::Bind(&CookieStoreIOS::DeleteAllCreatedBetweenForHostAsync,
+                     weak_factory_.GetWeakPtr(), delete_begin, delete_end, url,
+                     WrapDeleteCallback(callback)));
       break;
     case SYNCHRONIZED:
       NSString* host = base::SysUTF8ToNSString(url.host());
@@ -717,8 +730,8 @@
       break;
     case SYNCHRONIZING:
       tasks_pending_synchronization_.push_back(
-          base::Bind(&CookieStoreIOS::DeleteSessionCookiesAsync, this,
-                     WrapDeleteCallback(callback)));
+          base::Bind(&CookieStoreIOS::DeleteSessionCookiesAsync,
+                     weak_factory_.GetWeakPtr(), WrapDeleteCallback(callback)));
       break;
     case SYNCHRONIZED:
       CookieFilterFunction filter = base::Bind(&IsCookieSessionCookie);
@@ -740,14 +753,6 @@
 }
 
 #pragma mark -
-#pragma mark Protected methods
-
-CookieStoreIOS::~CookieStoreIOS() {
-  NotificationTrampoline::GetInstance()->RemoveObserver(this);
-  STLDeleteContainerPairSecondPointers(hook_map_.begin(), hook_map_.end());
-}
-
-#pragma mark -
 #pragma mark Private methods
 
 void CookieStoreIOS::ClearSystemStore() {
@@ -777,8 +782,8 @@
     DCHECK(![[system_store_ cookies] count]);
     DCHECK(synchronization_state_ != SYNCHRONIZING);
     synchronization_state_ = SYNCHRONIZING;
-    cookie_monster_->GetAllCookiesAsync(
-        base::Bind(&CookieStoreIOS::AddCookiesToSystemStore, this));
+    cookie_monster_->GetAllCookiesAsync(base::Bind(
+        &CookieStoreIOS::AddCookiesToSystemStore, weak_factory_.GetWeakPtr()));
   } else {
     DCHECK_EQ(NSHTTPCookieAcceptPolicyNever, policy);
     // FlushStore() does not write the cookies to disk when they are disabled.
@@ -832,7 +837,8 @@
       synchronization_state_ = SYNCHRONIZING;
       ClearSystemStore();
       cookie_monster_->GetAllCookiesAsync(
-          base::Bind(&CookieStoreIOS::AddCookiesToSystemStore, this));
+          base::Bind(&CookieStoreIOS::AddCookiesToSystemStore,
+                     weak_factory_.GetWeakPtr()));
       return;
     } else {
       // Copy the cookies from the global store to |cookie_monster_|.
@@ -970,7 +976,7 @@
     return;
 
   flush_closure_.Reset(base::Bind(&CookieStoreIOS::FlushStore,
-                                  base::Unretained(this), base::Closure()));
+                                  weak_factory_.GetWeakPtr(), base::Closure()));
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, flush_closure_.callback(), flush_delay_);
 }
@@ -1065,8 +1071,9 @@
   DCHECK(client);
   auto sequenced_task_runner = client->GetTaskRunner();
   DCHECK(sequenced_task_runner);
-  auto callback = base::Bind(&CookieStoreIOS::DidClearBinaryCookiesFileCookies,
-                             this, delete_callback, num_deleted);
+  auto callback =
+      base::Bind(&CookieStoreIOS::DidClearBinaryCookiesFileCookies,
+                 weak_factory_.GetWeakPtr(), delete_callback, num_deleted);
   sequenced_task_runner.get()->PostTaskAndReply(
       FROM_HERE, base::Bind(&ClearAllCookiesFromBinaryCookiesFile), callback);
 }
@@ -1087,8 +1094,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   for (const auto& hook_map_entry : hook_map_) {
     std::pair<GURL, std::string> key = hook_map_entry.first;
-    GetCookieListCallback callback =
-        base::Bind(&CookieStoreIOS::GotCookieListFor, this, key);
+    GetCookieListCallback callback = base::Bind(
+        &CookieStoreIOS::GotCookieListFor, weak_factory_.GetWeakPtr(), key);
     cookie_monster_->GetAllCookiesForURLAsync(key.first, callback);
   }
 }
@@ -1131,18 +1138,21 @@
 CookieStoreIOS::SetCookiesCallback CookieStoreIOS::WrapSetCallback(
     const SetCookiesCallback& callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  return base::Bind(&CookieStoreIOS::UpdateCachesAfterSet, this, callback);
+  return base::Bind(&CookieStoreIOS::UpdateCachesAfterSet,
+                    weak_factory_.GetWeakPtr(), callback);
 }
 
 CookieStoreIOS::DeleteCallback CookieStoreIOS::WrapDeleteCallback(
     const DeleteCallback& callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  return base::Bind(&CookieStoreIOS::UpdateCachesAfterDelete, this, callback);
+  return base::Bind(&CookieStoreIOS::UpdateCachesAfterDelete,
+                    weak_factory_.GetWeakPtr(), callback);
 }
 
 base::Closure CookieStoreIOS::WrapClosure(const base::Closure& callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure, this, callback);
+  return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure,
+                    weak_factory_.GetWeakPtr(), callback);
 }
 
 }  // namespace net
diff --git a/ios/net/cookies/cookie_store_ios_unittest.mm b/ios/net/cookies/cookie_store_ios_unittest.mm
index 4b5beb2..e37c5e9 100644
--- a/ios/net/cookies/cookie_store_ios_unittest.mm
+++ b/ios/net/cookies/cookie_store_ios_unittest.mm
@@ -7,6 +7,8 @@
 #import <Foundation/Foundation.h>
 
 #include "base/bind_helpers.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/sys_string_conversions.h"
 #import "net/base/mac/url_conversions.h"
@@ -28,11 +30,11 @@
 namespace net {
 
 struct CookieStoreIOSTestTraits {
-  static net::CookieStore* Create() {
+  static scoped_ptr<net::CookieStore> Create() {
     ClearCookies();
-    CookieStoreIOS* store = new CookieStoreIOS(nullptr);
+    scoped_ptr<CookieStoreIOS> store(new CookieStoreIOS(nullptr));
     store->synchronization_state_ = CookieStoreIOS::SYNCHRONIZED;
-    return store;
+    return std::move(store);
   }
 
   static const bool supports_http_only = false;
@@ -47,8 +49,8 @@
 };
 
 struct InactiveCookieStoreIOSTestTraits {
-  static scoped_refptr<net::CookieStore> Create() {
-    return new CookieStoreIOS(nullptr);
+  static scoped_ptr<net::CookieStore> Create() {
+    return make_scoped_ptr(new CookieStoreIOS(nullptr));
   }
 
   static const bool is_cookie_monster = false;
@@ -77,6 +79,8 @@
     CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
   }
 
+  ~RoundTripTestCookieStore() override { store_->UnSynchronize(); }
+
   // Inherited CookieStore methods.
   void SetCookieWithOptionsAsync(const GURL& url,
                                  const std::string& cookie_line,
@@ -175,9 +179,6 @@
     return scoped_ptr<CookieStore::CookieChangedSubscription>();
   }
 
- protected:
-  ~RoundTripTestCookieStore() override { store_->UnSynchronize(); }
-
  private:
   void RoundTrip() {
     CookieStoreIOS::SwitchSynchronizedStore(store_.get(), dummy_store_.get());
@@ -188,16 +189,16 @@
     CookieStoreIOS::SwitchSynchronizedStore(dummy_store_.get(), store_.get());
   }
 
-  scoped_refptr<CookieStoreIOS> store_;
+  scoped_ptr<CookieStoreIOS> store_;
   // |dummy_store_| is not directly used, but is needed to make |store_|
   // inactive.
-  scoped_refptr<CookieStoreIOS> dummy_store_;
+  scoped_ptr<CookieStoreIOS> dummy_store_;
 };
 
 struct RoundTripTestCookieStoreTraits {
-  static scoped_refptr<net::CookieStore> Create() {
+  static scoped_ptr<net::CookieStore> Create() {
     ClearCookies();
-    return new RoundTripTestCookieStore();
+    return make_scoped_ptr(new RoundTripTestCookieStore());
   }
 
   static const bool is_cookie_monster = false;
@@ -362,9 +363,9 @@
       : kTestCookieURL("http://foo.google.com/bar"),
         kTestCookieURL2("http://foo.google.com/baz"),
         kTestCookieURL3("http://foo.google.com"),
-        kTestCookieURL4("http://bar.google.com/bar") {
-    backend_ = new TestPersistentCookieStore;
-    store_ = new net::CookieStoreIOS(backend_.get());
+        kTestCookieURL4("http://bar.google.com/bar"),
+        backend_(new TestPersistentCookieStore),
+        store_(new net::CookieStoreIOS(backend_.get())) {
     net::CookieStoreIOS::SetCookiePolicy(net::CookieStoreIOS::ALLOW);
     cookie_changed_callback_ = store_->AddCallbackForCookie(
         kTestCookieURL, "abc",
@@ -429,7 +430,7 @@
 
   base::MessageLoop loop_;
   scoped_refptr<TestPersistentCookieStore> backend_;
-  scoped_refptr<net::CookieStoreIOS> store_;
+  scoped_ptr<net::CookieStoreIOS> store_;
   scoped_ptr<net::CookieStore::CookieChangedSubscription>
       cookie_changed_callback_;
   std::vector<net::CanonicalCookie> cookies_changed_;
@@ -529,7 +530,7 @@
   base::MessageLoop loop;
   const GURL kTestCookieURL("http://foo.google.com/bar");
   ClearCookies();
-  scoped_refptr<CookieStoreIOS> cookie_store(new CookieStoreIOS(nullptr));
+  scoped_ptr<CookieStoreIOS> cookie_store(new CookieStoreIOS(nullptr));
   CookieStoreIOS::SwitchSynchronizedStore(nullptr, cookie_store.get());
   // Add a cookie.
   net::CookieOptions options;
@@ -607,7 +608,7 @@
 // unsynchronized while synchronization is in progress).
 TEST_F(CookieStoreIOSWithBackend, SyncThenUnsync) {
   ClearCookies();
-  scoped_refptr<CookieStoreIOS> dummy_store = new CookieStoreIOS(nullptr);
+  scoped_ptr<CookieStoreIOS> dummy_store(new CookieStoreIOS(nullptr));
   // Switch back and forth before synchronization can complete.
   CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
   CookieStoreIOS::SwitchSynchronizedStore(store_.get(), dummy_store.get());
@@ -628,7 +629,7 @@
 // and there are pending tasks).
 TEST_F(CookieStoreIOSWithBackend, SyncThenUnsyncWithPendingTasks) {
   ClearCookies();
-  scoped_refptr<CookieStoreIOS> dummy_store = new CookieStoreIOS(nullptr);
+  scoped_ptr<CookieStoreIOS> dummy_store(new CookieStoreIOS(nullptr));
   // Start synchornization.
   CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
   // Create a pending task while synchronization is in progress.
@@ -726,7 +727,7 @@
 }
 
 TEST_F(CookieStoreIOSWithBackend, FlushOnSwitch) {
-  scoped_refptr<CookieStoreIOS> dummy_store = new CookieStoreIOS(nullptr);
+  scoped_ptr<CookieStoreIOS> dummy_store(new CookieStoreIOS(nullptr));
   CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
   EXPECT_FALSE(backend_->flushed());
   CookieStoreIOS::SwitchSynchronizedStore(store_.get(), dummy_store.get());
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index cf8b14c..bf1b54bd 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -217,8 +217,6 @@
     "web_state/page_viewport_state.mm",
     "web_state/ui/crw_context_menu_provider.h",
     "web_state/ui/crw_context_menu_provider.mm",
-    "web_state/ui/crw_debug_web_view.h",
-    "web_state/ui/crw_debug_web_view.mm",
     "web_state/ui/crw_generic_content_view.mm",
     "web_state/ui/crw_simple_web_view_controller.h",
     "web_state/ui/crw_static_file_web_view.h",
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp
index 97c4e9c..008c807 100644
--- a/ios/web/ios_web.gyp
+++ b/ios/web/ios_web.gyp
@@ -253,8 +253,6 @@
         'web_state/page_viewport_state.mm',
         'web_state/ui/crw_context_menu_provider.h',
         'web_state/ui/crw_context_menu_provider.mm',
-        'web_state/ui/crw_debug_web_view.h',
-        'web_state/ui/crw_debug_web_view.mm',
         'web_state/ui/crw_generic_content_view.mm',
         'web_state/ui/crw_simple_web_view_controller.h',
         'web_state/ui/crw_static_file_web_view.h',
diff --git a/ios/web/shell/shell_url_request_context_getter.mm b/ios/web/shell/shell_url_request_context_getter.mm
index 6fc3e7a7..02ad8d7 100644
--- a/ios/web/shell/shell_url_request_context_getter.mm
+++ b/ios/web/shell/shell_url_request_context_getter.mm
@@ -77,10 +77,10 @@
             web::WebThread::GetBlockingPool()->GetSequencedTaskRunner(
                 web::WebThread::GetBlockingPool()->GetSequenceToken()),
             true, nullptr);
-    scoped_refptr<net::CookieStoreIOS> cookie_store =
-        new net::CookieStoreIOS(persistent_store.get());
-    storage_->set_cookie_store(cookie_store.get());
+    scoped_ptr<net::CookieStoreIOS> cookie_store(
+        new net::CookieStoreIOS(persistent_store.get()));
     net::CookieStoreIOS::SwitchSynchronizedStore(nullptr, cookie_store.get());
+    storage_->set_cookie_store(std::move(cookie_store));
 
     std::string user_agent = web::GetWebClient()->GetUserAgent(false);
     storage_->set_http_user_agent_settings(make_scoped_ptr(
diff --git a/ios/web/web_state/ui/crw_debug_web_view.h b/ios/web/web_state/ui/crw_debug_web_view.h
deleted file mode 100644
index 872d18f..0000000
--- a/ios/web/web_state/ui/crw_debug_web_view.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef IOS_WEB_WEB_STATE_UI_CRW_DEBUG_WEB_VIEW_H_
-#define IOS_WEB_WEB_STATE_UI_CRW_DEBUG_WEB_VIEW_H_
-
-// This class is only available in debug mode. It uses private API.
-#if !defined(NDEBUG)
-
-#import <UIKit/UIKit.h>
-
-// All part of webkit API, but it is private on iOS.
-@class WebFrame;
-@class WebScriptCallFrame;
-@class WebView;
-
-@protocol CRWDebugWebView_WebViewScriptDelegate
-@optional
-// Called when a javascript statement want to write on the console.
-- (void)webView:(WebView*)webView addMessageToConsole:(NSDictionary*)dict;
-
-// Some source was parsed, establishing a "source ID" (>= 0) for future
-// reference
-- (void)webView:(WebView*)webView
-    didParseSource:(NSString*)source
-    baseLineNumber:(NSUInteger)lineNumber
-           fromURL:(NSURL*)url
-          sourceId:(int)sid
-       forWebFrame:(WebFrame*)webFrame;
-
-// Called if a loaded javascript file fail to parse.
-- (void)webView:(WebView*)webView
-    failedToParseSource:(NSString*)source
-         baseLineNumber:(unsigned)lineNumber
-                fromURL:(NSURL*)url
-              withError:(NSError*)error
-            forWebFrame:(WebFrame*)webFrame;
-
-// Called if an exception is raised in Javascript.
-- (void)webView:(WebView*)webView
-    exceptionWasRaised:(WebScriptCallFrame*)frame
-              sourceId:(int)sid
-                  line:(int)lineno
-           forWebFrame:(WebFrame*)webFrame;
-
-@end
-
-// Simply use like a regular UIWebView. It just logs javascript information on
-// the console.
-@interface CRWDebugWebView : UIWebView
-
-// Webview delegate API, which the superclass is. Used to set the script
-// delegate on the same webview the superclass is delegate of.
-- (void)webView:(id)sender
-    didClearWindowObject:(id)windowObject
-                forFrame:(WebFrame*)frame;
-
-@end
-
-#endif  // !defined(NDEBUG)
-#endif  // IOS_WEB_WEB_STATE_UI_CRW_DEBUG_WEB_VIEW_H_
diff --git a/ios/web/web_state/ui/crw_debug_web_view.mm b/ios/web/web_state/ui/crw_debug_web_view.mm
deleted file mode 100644
index 4fdb439..0000000
--- a/ios/web/web_state/ui/crw_debug_web_view.mm
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#if !defined(NDEBUG)
-#import "ios/web/web_state/ui/crw_debug_web_view.h"
-
-#include "base/mac/scoped_nsobject.h"
-
-// These categories define private API in iOS, in reality part of WebKit.
-@interface NSObject (CRWDebugWebView_WebScriptCallFrame_methods)
-- (id)functionName;
-- (id)caller;
-- (id)exception;
-@end
-
-@interface NSObject (CRWDebugWebView_WebView_methods)
-- (void)setScriptDebugDelegate:
-    (id<CRWDebugWebView_WebViewScriptDelegate>)delegate;
-@end
-
-@interface NSObject (CRWDebugWebView_WebScriptObject_methods)
-- (id)callWebScriptMethod:(NSString*)name withArguments:(NSArray*)args;
-@end
-
-#pragma mark -
-
-// The debug implementation of the webscript delegate.
-@interface CRWDebugWebDelegate :
-NSObject<CRWDebugWebView_WebViewScriptDelegate> {
-  base::scoped_nsobject<NSMutableDictionary> _sidsToURLs;
-}
-@end
-
-@implementation CRWDebugWebDelegate
-
-- (id)init {
-  if ((self = [super init])) {
-    _sidsToURLs.reset([[NSMutableDictionary alloc] init]);
-  }
-  return self;
-}
-
-- (void)webView:(WebView*)webView addMessageToConsole:(NSDictionary*)dict {
-  NSLog(@"JS: %@", dict);
-}
-
-- (void)webView:(WebView*)webView
-    didParseSource:(NSString*)source
-    baseLineNumber:(NSUInteger)lineNumber
-           fromURL:(NSURL*)url
-          sourceId:(int)sid
-       forWebFrame:(WebFrame*)webFrame {
-  if (url && sid)
-    [_sidsToURLs setObject:url forKey:[NSNumber numberWithInt:sid]];
-}
-
-- (void)webView:(WebView*)webView
-    failedToParseSource:(NSString*)source
-         baseLineNumber:(unsigned)lineNumber
-                fromURL:(NSURL*)url
-              withError:(NSError*)error
-            forWebFrame:(WebFrame*)webFrame {
-  NSLog(@"JS Failed to parse: url=%@ line=%d error=%@\nsource=%@",
-        url, lineNumber, error, source);
-}
-
-- (void)webView:(WebView*)webView
-    exceptionWasRaised:(WebScriptCallFrame*)frame
-              sourceId:(int)sid
-                  line:(int)lineno
-           forWebFrame:(WebFrame*)webFrame {
-  NSURL* url = [_sidsToURLs objectForKey:[NSNumber numberWithInt:sid]];
-  id representation = [frame exception];
-  if ([representation isKindOfClass:NSClassFromString(@"WebScriptObject")]) {
-    representation =
-        [representation callWebScriptMethod:@"toString" withArguments:nil];
-  }
-  base::scoped_nsobject<NSMutableArray> message([[NSMutableArray alloc] init]);
-
-  [message addObject:
-      [NSString stringWithFormat:@"JS Exception: sid=%d url=%@ exception=%@",
-          sid, url, representation]];
-
-  if ([frame respondsToSelector:@selector(caller)]) {
-    while (frame) {
-      frame = [frame caller];
-      [message addObject:[NSString stringWithFormat:@"line=%d function=%@",
-          lineno, [frame functionName]]];
-    }
-  }
-
-  NSLog(@"%@", [message componentsJoinedByString:@"\n\t"]);
-}
-
-@end
-
-#pragma mark -
-
-@implementation CRWDebugWebView {
-  base::scoped_nsobject<CRWDebugWebDelegate> _webDelegate;
-}
-
-- (void)webView:(id)sender
-    didClearWindowObject:(id)windowObject
-                forFrame:(WebFrame*)frame {
-  if (!_webDelegate)
-    _webDelegate.reset([[CRWDebugWebDelegate alloc] init]);
-  [sender setScriptDebugDelegate:_webDelegate];
-}
-
-@end
-
-#endif  // !defined(NDEBUG)
diff --git a/ios/web/web_state/web_view_internal_creation_util.mm b/ios/web/web_state/web_view_internal_creation_util.mm
index cbf01d64..cde2176 100644
--- a/ios/web/web_state/web_view_internal_creation_util.mm
+++ b/ios/web/web_state/web_view_internal_creation_util.mm
@@ -26,10 +26,6 @@
 #import "ios/web/web_view_counter_impl.h"
 
 #if !defined(NDEBUG)
-#import "ios/web/web_state/ui/crw_debug_web_view.h"
-#endif
-
-#if !defined(NDEBUG)
 
 namespace {
 // Returns the counter of all the active WKWebViews.
@@ -137,16 +133,7 @@
   DCHECK(web::GetWebClient());
   web::GetWebClient()->PreWebViewCreation();
 
-  UIWebView* result = nil;
-#if defined(NDEBUG)
-  result = [[UIWebView alloc] initWithFrame:frame];
-#else
-  // TODO(eugenebut): create constant for @"LogJavascript" (crbug.com/391807).
-  if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LogJavascript"])
-    result = [[CRWDebugWebView alloc] initWithFrame:frame];
-  else
-    result = [[UIWebView alloc] initWithFrame:frame];
-#endif  // defined(NDEBUG)
+  UIWebView* result = [[UIWebView alloc] initWithFrame:frame];
 
   // Disable data detector types. Safari does the same.
   [result setDataDetectorTypes:UIDataDetectorTypeNone];
diff --git a/ios/web/web_state/web_view_internal_creation_util_unittest.mm b/ios/web/web_state/web_view_internal_creation_util_unittest.mm
index b00d01c..cd18bfc 100644
--- a/ios/web/web_state/web_view_internal_creation_util_unittest.mm
+++ b/ios/web/web_state/web_view_internal_creation_util_unittest.mm
@@ -17,7 +17,6 @@
 #include "ios/web/public/test/web_test_util.h"
 #import "ios/web/public/web_view_creation_util.h"
 #import "ios/web/test/web_test.h"
-#import "ios/web/web_state/ui/crw_debug_web_view.h"
 #import "ios/web/web_state/ui/crw_simple_web_view_controller.h"
 #import "ios/web/web_state/ui/crw_static_file_web_view.h"
 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
@@ -171,21 +170,6 @@
 
 #if !defined(NDEBUG)
 
-// Tests web::CreateWebView function that it correctly returns a CRWDebugWebView
-// with the correct frame and calls WebClient::PreWebViewCreation/
-// WebClient::PostWebViewCreation methods.
-TEST_F(WebViewCreationUtilsTest, DebugCreation) {
-  [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"LogJavascript"];
-
-  UIWebView* captured_web_view = nil;
-  ExpectWebClientCalls(&captured_web_view);
-
-  base::scoped_nsobject<UIWebView> web_view(CreateWebView(kTestFrame));
-  EXPECT_TRUE([web_view isMemberOfClass:[CRWDebugWebView class]]);
-  EXPECT_TRUE(CGRectEqualToRect(kTestFrame, [web_view frame]));
-  EXPECT_NSEQ(web_view, captured_web_view);
-}
-
 // Tests that getting a WKWebView from the util methods correctly maintains
 // the global active wkwebview count (which is debug-only).
 TEST_F(WebViewCreationUtilsTest, GetActiveWKWebViewsCount) {
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
index dd882bb..0747172 100644
--- a/ipc/ipc_channel.h
+++ b/ipc/ipc_channel.h
@@ -223,6 +223,7 @@
   // message from client to server we need to send the PID from the global
   // PID namespace.
   static void SetGlobalPid(int pid);
+  static int GetGlobalPid();
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index f53a8fe3..b0a8c38 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -613,6 +613,10 @@
 void ChannelPosix::SetGlobalPid(int pid) {
   global_pid_ = pid;
 }
+// static
+int ChannelPosix::GetGlobalPid() {
+  return global_pid_;
+}
 #endif  // OS_LINUX
 
 // Called by libevent when we can read from the pipe without blocking.
@@ -1125,6 +1129,9 @@
 void Channel::SetGlobalPid(int pid) {
   ChannelPosix::SetGlobalPid(pid);
 }
+int Channel::GetGlobalPid() {
+  return ChannelPosix::GetGlobalPid();
+}
 #endif  // OS_LINUX
 
 }  // namespace IPC
diff --git a/ipc/ipc_channel_posix.h b/ipc/ipc_channel_posix.h
index ddeb60e..14bb95c4 100644
--- a/ipc/ipc_channel_posix.h
+++ b/ipc/ipc_channel_posix.h
@@ -65,6 +65,7 @@
   static bool IsNamedServerInitialized(const std::string& channel_id);
 #if defined(OS_LINUX)
   static void SetGlobalPid(int pid);
+  static int GetGlobalPid();
 #endif  // OS_LINUX
 
  private:
diff --git a/ipc/ipc_perftest_support.cc b/ipc/ipc_perftest_support.cc
index 1ecc7c74..5cd2b1d 100644
--- a/ipc/ipc_perftest_support.cc
+++ b/ipc/ipc_perftest_support.cc
@@ -227,6 +227,9 @@
   scoped_ptr<base::PerfTimeLogger> perf_logger_;
 };
 
+IPCChannelPerfTestBase::IPCChannelPerfTestBase() = default;
+IPCChannelPerfTestBase::~IPCChannelPerfTestBase() = default;
+
 std::vector<PingPongTestParams>
 IPCChannelPerfTestBase::GetDefaultTestParams() {
   // Test several sizes. We use 12^N for message size, and limit the message
@@ -281,14 +284,14 @@
 
 void IPCChannelPerfTestBase::RunTestChannelProxyPingPong(
     const std::vector<PingPongTestParams>& params) {
+  io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
   InitWithCustomMessageLoop("PerformanceClient",
                             make_scoped_ptr(new base::MessageLoop()));
 
-  base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
 
   // Set up IPC channel and start client.
   PerformanceChannelListener listener("ChannelProxy");
-  CreateChannelProxy(&listener, io_thread.task_runner());
+  CreateChannelProxy(&listener, io_thread_->task_runner());
   listener.Init(channel_proxy());
   ASSERT_TRUE(StartClient());
 
@@ -318,6 +321,8 @@
 
   EXPECT_TRUE(WaitForClientShutdown());
   DestroyChannelProxy();
+
+  io_thread_.reset();
 }
 
 
diff --git a/ipc/ipc_perftest_support.h b/ipc/ipc_perftest_support.h
index 80c58d1..82eb1eef 100644
--- a/ipc/ipc_perftest_support.h
+++ b/ipc/ipc_perftest_support.h
@@ -10,6 +10,8 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/test/test_io_thread.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "ipc/ipc_test_base.h"
 
@@ -34,12 +36,24 @@
 
 class IPCChannelPerfTestBase : public IPCTestBase {
  public:
+  IPCChannelPerfTestBase();
+  ~IPCChannelPerfTestBase() override;
+
   static std::vector<PingPongTestParams> GetDefaultTestParams();
 
   void RunTestChannelPingPong(
       const std::vector<PingPongTestParams>& params_list);
   void RunTestChannelProxyPingPong(
       const std::vector<PingPongTestParams>& params_list);
+
+  scoped_refptr<base::TaskRunner> io_task_runner() {
+    if (io_thread_)
+      return io_thread_->task_runner();
+    return base::ThreadTaskRunnerHandle::Get();
+  }
+
+ private:
+  scoped_ptr<base::TestIOThread> io_thread_;
 };
 
 class PingPongTestClient {
diff --git a/ipc/ipc_test_base.h b/ipc/ipc_test_base.h
index 360188f6..86178b0 100644
--- a/ipc/ipc_test_base.h
+++ b/ipc/ipc_test_base.h
@@ -48,8 +48,9 @@
   // message loop on the main thread. As IPCTestBase creates IO message loop by
   // default, such tests need to provide a custom message loop for the main
   // thread.
-  void InitWithCustomMessageLoop(const std::string& test_client_name,
-                                 scoped_ptr<base::MessageLoop> message_loop);
+  virtual void InitWithCustomMessageLoop(
+      const std::string& test_client_name,
+      scoped_ptr<base::MessageLoop> message_loop);
 
   // Creates a channel with the given listener and connects to the channel
   // (returning true if successful), respectively. Use these to use a channel
@@ -80,7 +81,7 @@
 
   // Starts the client process, returning true if successful; this should be
   // done after connecting to the channel.
-  bool StartClient();
+  virtual bool StartClient();
 
 #if defined(OS_POSIX)
   // A StartClient() variant that allows caller to pass the FD of IPC pipe
@@ -91,7 +92,7 @@
   // this does not initiate client shutdown; that must be done by the test
   // (somehow). This must be called before the end of the test whenever
   // StartClient() was called successfully.
-  bool WaitForClientShutdown();
+  virtual bool WaitForClientShutdown();
 
   IPC::ChannelHandle GetTestChannelHandle();
 
diff --git a/ipc/mojo/BUILD.gn b/ipc/mojo/BUILD.gn
index 5555141..4966b90 100644
--- a/ipc/mojo/BUILD.gn
+++ b/ipc/mojo/BUILD.gn
@@ -5,17 +5,14 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//testing/test.gni")
 
-mojom("client_channel") {
+mojom("mojom") {
   sources = [
-    "client_channel.mojom",
+    "ipc.mojom",
   ]
 }
 
 component("mojo") {
   sources = [
-    "async_handle_waiter.cc",
-    "async_handle_waiter.h",
-    "client_channel.mojom",
     "ipc_channel_mojo.cc",
     "ipc_channel_mojo.h",
     "ipc_message_pipe_reader.cc",
@@ -35,7 +32,7 @@
   defines = [ "IPC_MOJO_IMPLEMENTATION" ]
 
   deps = [
-    ":client_channel",
+    ":mojom",
     "//base",
     "//base/third_party/dynamic_annotations",
     "//ipc",
@@ -48,8 +45,6 @@
 
 test("ipc_mojo_unittests") {
   sources = [
-    "async_handle_waiter_unittest.cc",
-
     # TODO(rockot): Re-enable these when we're ready to start using ChannelMojo
     # again. They need to be updated to support multiprocess testing with the
     # current Mojo EDK implementation.
@@ -59,13 +54,15 @@
   ]
 
   deps = [
+    ":mojo",
+    ":mojom",
     "//base",
     "//base/test:test_support",
     "//base/third_party/dynamic_annotations",
     "//ipc",
     "//ipc:test_support",
-    "//ipc/mojo",
     "//mojo/edk/system",
+    "//mojo/edk/test:test_support",
     "//mojo/environment:chromium",
     "//testing/gtest",
     "//url",
@@ -75,18 +72,25 @@
 test("ipc_mojo_perftests") {
   sources = [
     "ipc_mojo_perftest.cc",
+    "run_all_perftests.cc",
   ]
 
   deps = [
+    ":mojo",
+    ":mojom",
     "//base",
     "//base/test:test_support",
-    "//base/test:test_support_perf",
     "//base/third_party/dynamic_annotations",
     "//ipc",
     "//ipc:test_support",
-    "//ipc/mojo",
     "//mojo/edk/system",
+    "//mojo/edk/test:test_support",
+    "//mojo/edk/test:test_support_impl",
     "//mojo/environment:chromium",
     "//url",
   ]
+
+  if (is_linux && !is_component_build) {
+    public_configs = [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
+  }
 }
diff --git a/ipc/mojo/DEPS b/ipc/mojo/DEPS
index 348fd9f..00f925a0 100644
--- a/ipc/mojo/DEPS
+++ b/ipc/mojo/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+mojo/edk/embedder",
+  "+mojo/edk/test",
   "+mojo/public",
 ]
diff --git a/ipc/mojo/async_handle_waiter.cc b/ipc/mojo/async_handle_waiter.cc
deleted file mode 100644
index a4247fd0..0000000
--- a/ipc/mojo/async_handle_waiter.cc
+++ /dev/null
@@ -1,171 +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 "ipc/mojo/async_handle_waiter.h"
-
-#include "base/atomic_ref_count.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "mojo/edk/embedder/embedder.h"
-
-namespace IPC {
-namespace internal {
-
-class AsyncHandleWaiterContextTraits {
- public:
-  static void Destruct(const AsyncHandleWaiter::Context* context);
-};
-
-// The thread-safe part of |AsyncHandleWaiter|.
-// As |AsyncWait()| invokes the given callback from an arbitrary thread,
-// |HandleIsReady()| and the bound |this| have to be thread-safe.
-class AsyncHandleWaiter::Context
-    : public base::RefCountedThreadSafe<AsyncHandleWaiter::Context,
-                                        AsyncHandleWaiterContextTraits>,
-      public base::MessageLoopForIO::IOObserver {
- public:
-  Context(base::WeakPtr<AsyncHandleWaiter> waiter)
-      : io_runner_(base::MessageLoopForIO::current()->task_runner()),
-        waiter_(waiter),
-        last_result_(MOJO_RESULT_INTERNAL),
-        io_loop_level_(0),
-        should_invoke_callback_(false) {
-    base::MessageLoopForIO::current()->AddIOObserver(this);
-  }
-
-  void HandleIsReady(MojoResult result) {
-    last_result_ = result;
-
-    // If the signaling happens in the IO handler, use |IOObserver| callback
-    // to invoke the callback.
-    if (IsCalledFromIOHandler()) {
-      should_invoke_callback_ = true;
-      return;
-    }
-
-    io_runner_->PostTask(FROM_HERE,
-                         base::Bind(&Context::InvokeWaiterCallback, this));
-  }
-
- private:
-  friend void base::DeletePointer<const Context>(const Context* self);
-  friend class AsyncHandleWaiterContextTraits;
-  friend class base::RefCountedThreadSafe<Context>;
-
-  ~Context() override {
-    DCHECK(base::MessageLoopForIO::current()->task_runner() == io_runner_);
-    base::MessageLoopForIO::current()->RemoveIOObserver(this);
-  }
-
-  bool IsCalledFromIOHandler() const {
-    base::MessageLoop* loop = base::MessageLoop::current();
-    if (!loop)
-      return false;
-    if (loop->task_runner() != io_runner_)
-      return false;
-    return io_loop_level_ > 0;
-  }
-
-  // Called from |io_runner_| thus safe to touch |waiter_|.
-  void InvokeWaiterCallback() {
-    MojoResult result = last_result_;
-    last_result_ = MOJO_RESULT_INTERNAL;
-    if (waiter_)
-      waiter_->InvokeCallback(result);
-  }
-
-  // IOObserver implementation:
-
-  void WillProcessIOEvent() override {
-    DCHECK(io_loop_level_ != 0 || !should_invoke_callback_);
-    DCHECK_GE(io_loop_level_, 0);
-    io_loop_level_++;
-  }
-
-  void DidProcessIOEvent() override {
-    // This object could have been constructed in another's class's
-    // DidProcessIOEvent.
-    if (io_loop_level_== 0)
-      return;
-
-    DCHECK_GE(io_loop_level_, 1);
-
-    // Leaving a nested loop.
-    if (io_loop_level_ > 1) {
-      io_loop_level_--;
-      return;
-    }
-
-    // The zero |waiter_| indicates that |this| have lost the owner and can be
-    // under destruction. So we cannot wrap it with a |scoped_refptr| anymore.
-    if (!waiter_) {
-      should_invoke_callback_ = false;
-      io_loop_level_--;
-      return;
-    }
-
-    // We have to protect |this| because |AsyncHandleWaiter| can be
-    // deleted during the callback.
-    scoped_refptr<Context> protect(this);
-    while (should_invoke_callback_) {
-      should_invoke_callback_ = false;
-      InvokeWaiterCallback();
-    }
-
-    io_loop_level_--;
-  }
-
-  // Only |io_runner_| is accessed from arbitrary threads.  Others are touched
-  // only from the IO thread.
-  const scoped_refptr<base::TaskRunner> io_runner_;
-
-  const base::WeakPtr<AsyncHandleWaiter> waiter_;
-  MojoResult last_result_;
-  int io_loop_level_;
-  bool should_invoke_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(Context);
-};
-
-AsyncHandleWaiter::AsyncHandleWaiter(base::Callback<void(MojoResult)> callback)
-    : callback_(callback),
-      weak_factory_(this) {
-  context_ = new Context(weak_factory_.GetWeakPtr());
-}
-
-AsyncHandleWaiter::~AsyncHandleWaiter() {
-}
-
-MojoResult AsyncHandleWaiter::Wait(MojoHandle handle,
-                                   MojoHandleSignals signals) {
-  return mojo::edk::AsyncWait(handle, signals,
-                              base::Bind(&Context::HandleIsReady, context_));
-}
-
-void AsyncHandleWaiter::InvokeCallback(MojoResult result) {
-  callback_.Run(result);
-}
-
-base::MessageLoopForIO::IOObserver* AsyncHandleWaiter::GetIOObserverForTest() {
-  return context_.get();
-}
-
-base::Callback<void(MojoResult)> AsyncHandleWaiter::GetWaitCallbackForTest() {
-  return base::Bind(&Context::HandleIsReady, context_);
-}
-
-// static
-void AsyncHandleWaiterContextTraits::Destruct(
-    const AsyncHandleWaiter::Context* context) {
-  context->io_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&base::DeletePointer<const AsyncHandleWaiter::Context>,
-                 base::Unretained(context)));
-}
-
-}  // namespace internal
-}  // namespace IPC
diff --git a/ipc/mojo/async_handle_waiter.h b/ipc/mojo/async_handle_waiter.h
deleted file mode 100644
index e82c27a..0000000
--- a/ipc/mojo/async_handle_waiter.h
+++ /dev/null
@@ -1,53 +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 IPC_MOJO_ASYNC_HANDLE_WAITER_H_
-#define IPC_MOJO_ASYNC_HANDLE_WAITER_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "ipc/ipc_export.h"
-#include "mojo/public/c/system/types.h"
-
-namespace IPC {
-namespace internal {
-
-// |AsyncHandleWaiter| waits on a mojo handle asynchronously and
-// invokes the given |callback| through |runner| when it is signaled.
-//  * To start waiting, the client must call |AsyncHandleWaiter::Wait()|.
-//    The client can call |Wait()| again once it is signaled and
-//    the |callback| is invoked.
-//  * To cancel waiting, delete the instance.
-//
-// |AsyncHandleWaiter| must be created, used and deleted only from the IO
-// |thread.
-class IPC_MOJO_EXPORT AsyncHandleWaiter {
- public:
-  class Context;
-
-  explicit AsyncHandleWaiter(base::Callback<void(MojoResult)> callback);
-  ~AsyncHandleWaiter();
-
-  MojoResult Wait(MojoHandle handle, MojoHandleSignals signals);
-
-  base::MessageLoopForIO::IOObserver* GetIOObserverForTest();
-  base::Callback<void(MojoResult)> GetWaitCallbackForTest();
-
- private:
-  void InvokeCallback(MojoResult result);
-
-  scoped_refptr<Context> context_;
-  base::Callback<void(MojoResult)> callback_;
-  base::WeakPtrFactory<AsyncHandleWaiter> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AsyncHandleWaiter);
-};
-
-}  // namespace internal
-}  // namespace IPC
-
-#endif  // IPC_MOJO_ASYNC_HANDLE_WAITER_H_
diff --git a/ipc/mojo/async_handle_waiter_unittest.cc b/ipc/mojo/async_handle_waiter_unittest.cc
deleted file mode 100644
index e17b4fd3..0000000
--- a/ipc/mojo/async_handle_waiter_unittest.cc
+++ /dev/null
@@ -1,260 +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 "ipc/mojo/async_handle_waiter.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread.h"
-#include "mojo/public/cpp/system/message_pipe.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace IPC {
-namespace internal {
-namespace {
-
-void ReadOneByteOfX(MojoHandle pipe) {
-  uint32_t size = 1;
-  char buffer = ' ';
-  MojoResult rv = MojoReadMessage(pipe, &buffer, &size, nullptr, nullptr,
-                                  MOJO_READ_MESSAGE_FLAG_NONE);
-  CHECK_EQ(rv, MOJO_RESULT_OK);
-  CHECK_EQ(size, 1U);
-  CHECK_EQ(buffer, 'X');
-}
-
-class AsyncHandleWaiterTest : public testing::Test {
- public:
-  AsyncHandleWaiterTest() : worker_("test_worker") {
-    worker_.StartWithOptions(
-        base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-  }
-
-  void SetUp() override {
-    message_loop_.reset(new base::MessageLoopForIO());
-    ResetSignaledStates();
-    mojo::CreateMessagePipe(nullptr, &pipe_to_write_, &pipe_to_read_);
-    target_.reset(new AsyncHandleWaiter(base::Bind(
-        &AsyncHandleWaiterTest::HandleIsReady, base::Unretained(this))));
-  }
-
- protected:
-  MojoResult Start() {
-    return target_->Wait(pipe_to_read_.get().value(),
-                         MOJO_HANDLE_SIGNAL_READABLE);
-  }
-
-  void ResetSignaledStates() {
-    signaled_result_ = MOJO_RESULT_UNKNOWN;
-    run_loop_.reset(new base::RunLoop());
-  }
-
-  void WriteToPipe() {
-    MojoResult rv = MojoWriteMessage(pipe_to_write_.get().value(), "X", 1,
-                                     nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
-    CHECK_EQ(rv, MOJO_RESULT_OK);
-  }
-
-  void WriteToPipeFromWorker() {
-    worker_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&AsyncHandleWaiterTest::WriteToPipe,
-                              base::Unretained(this)));
-  }
-
-  void WaitAndAssertSignaledAndMessageIsArrived() {
-    run_loop_->Run();
-    EXPECT_EQ(MOJO_RESULT_OK, signaled_result_);
-
-    ReadOneByteOfX(pipe_to_read_.get().value());
-  }
-
-  void WaitAndAssertNotSignaled() {
-    run_loop_->RunUntilIdle();
-    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(pipe_to_read_.get().value(),
-                                       MOJO_HANDLE_SIGNAL_READABLE, 0,
-                                       nullptr));
-    EXPECT_EQ(MOJO_RESULT_UNKNOWN, signaled_result_);
-  }
-
-  void HandleIsReady(MojoResult result) {
-    CHECK_EQ(base::MessageLoop::current(), message_loop_.get());
-    CHECK_EQ(signaled_result_, MOJO_RESULT_UNKNOWN);
-    signaled_result_ = result;
-    run_loop_->Quit();
-  }
-
-  base::Thread worker_;
-  scoped_ptr<base::MessageLoop> message_loop_;
-  scoped_ptr<base::RunLoop> run_loop_;
-  mojo::ScopedMessagePipeHandle pipe_to_write_;
-  mojo::ScopedMessagePipeHandle pipe_to_read_;
-
-  scoped_ptr<AsyncHandleWaiter> target_;
-  MojoResult signaled_result_;
-};
-
-TEST_F(AsyncHandleWaiterTest, SignalFromSameThread) {
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-  WriteToPipe();
-  WaitAndAssertSignaledAndMessageIsArrived();
-
-  // Ensures that the waiter is reusable.
-  ResetSignaledStates();
-
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-  WriteToPipe();
-  WaitAndAssertSignaledAndMessageIsArrived();
-}
-
-TEST_F(AsyncHandleWaiterTest, SignalFromDifferentThread) {
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-  WriteToPipeFromWorker();
-  WaitAndAssertSignaledAndMessageIsArrived();
-
-  // Ensures that the waiter is reusable.
-  ResetSignaledStates();
-
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-  WriteToPipeFromWorker();
-  WaitAndAssertSignaledAndMessageIsArrived();
-}
-
-TEST_F(AsyncHandleWaiterTest, DeleteWaiterBeforeWrite) {
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-
-  target_.reset();
-
-  WriteToPipe();
-  WaitAndAssertNotSignaled();
-}
-
-TEST_F(AsyncHandleWaiterTest, DeleteWaiterBeforeSignal) {
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-  WriteToPipe();
-
-  target_.reset();
-
-  WaitAndAssertNotSignaled();
-}
-
-class HandlerThatReenters {
- public:
-  HandlerThatReenters(base::RunLoop* loop, MojoHandle handle)
-      : target_(nullptr), handle_(handle), loop_(loop), step_(0) {}
-
-  void set_target(AsyncHandleWaiter* target) { target_ = target; }
-
-  void HandleIsReady(MojoResult result) {
-    switch (step_) {
-      case 0:
-        RestartAndClose(result);
-        break;
-      case 1:
-        HandleClosingSignal(result);
-        break;
-      default:
-        NOTREACHED();
-        break;
-    }
-  }
-
-  void RestartAndClose(MojoResult result) {
-    CHECK_EQ(step_, 0);
-    CHECK_EQ(result, MOJO_RESULT_OK);
-    step_ = 1;
-
-    ReadOneByteOfX(handle_);
-    target_->Wait(handle_, MOJO_HANDLE_SIGNAL_READABLE);
-
-    // This signals the |AsyncHandleWaiter|.
-    MojoResult rv = MojoClose(handle_);
-    CHECK_EQ(rv, MOJO_RESULT_OK);
-  }
-
-  void HandleClosingSignal(MojoResult result) {
-    CHECK_EQ(step_, 1);
-    CHECK_EQ(result, MOJO_RESULT_CANCELLED);
-    step_ = 2;
-    loop_->Quit();
-  }
-
-  bool IsClosingHandled() const { return step_ == 2; }
-
-  AsyncHandleWaiter* target_;
-  MojoHandle handle_;
-  base::RunLoop* loop_;
-  int step_;
-};
-
-TEST_F(AsyncHandleWaiterTest, RestartWaitingWhileSignaled) {
-  HandlerThatReenters handler(run_loop_.get(), pipe_to_read_.get().value());
-  target_.reset(new AsyncHandleWaiter(base::Bind(
-      &HandlerThatReenters::HandleIsReady, base::Unretained(&handler))));
-  handler.set_target(target_.get());
-
-  EXPECT_EQ(MOJO_RESULT_OK, Start());
-  WriteToPipe();
-  run_loop_->Run();
-
-  EXPECT_TRUE(handler.IsClosingHandled());
-
-  // |HandlerThatReenters::RestartAndClose| already closed it.
-  ::ignore_result(pipe_to_read_.release());
-}
-
-class AsyncHandleWaiterIOObserverTest : public testing::Test {
- public:
-  void SetUp() override {
-    message_loop_.reset(new base::MessageLoopForIO());
-    target_.reset(new AsyncHandleWaiter(
-        base::Bind(&AsyncHandleWaiterIOObserverTest::HandleIsReady,
-                   base::Unretained(this))));
-    invocation_count_ = 0;
-  }
-
-  void HandleIsReady(MojoResult result) { invocation_count_++; }
-
-  scoped_ptr<base::MessageLoop> message_loop_;
-  scoped_ptr<AsyncHandleWaiter> target_;
-  size_t invocation_count_;
-};
-
-TEST_F(AsyncHandleWaiterIOObserverTest, OutsideIOEvnet) {
-  target_->GetWaitCallbackForTest().Run(MOJO_RESULT_OK);
-  EXPECT_EQ(0U, invocation_count_);
-  message_loop_->RunUntilIdle();
-  EXPECT_EQ(1U, invocation_count_);
-}
-
-TEST_F(AsyncHandleWaiterIOObserverTest, InsideIOEvnet) {
-  target_->GetIOObserverForTest()->WillProcessIOEvent();
-  target_->GetWaitCallbackForTest().Run(MOJO_RESULT_OK);
-  EXPECT_EQ(0U, invocation_count_);
-  target_->GetIOObserverForTest()->DidProcessIOEvent();
-  EXPECT_EQ(1U, invocation_count_);
-}
-
-TEST_F(AsyncHandleWaiterIOObserverTest, Reenter) {
-  target_->GetIOObserverForTest()->WillProcessIOEvent();
-  target_->GetWaitCallbackForTest().Run(MOJO_RESULT_OK);
-  EXPECT_EQ(0U, invocation_count_);
-
-  // As if some other io handler start nested loop.
-  target_->GetIOObserverForTest()->WillProcessIOEvent();
-  target_->GetWaitCallbackForTest().Run(MOJO_RESULT_OK);
-  target_->GetIOObserverForTest()->DidProcessIOEvent();
-  EXPECT_EQ(0U, invocation_count_);
-
-  target_->GetIOObserverForTest()->DidProcessIOEvent();
-  EXPECT_EQ(1U, invocation_count_);
-}
-
-}  // namespace
-}  // namespace internal
-}  // namespace IPC
diff --git a/ipc/mojo/client_channel.mojom b/ipc/mojo/client_channel.mojom
deleted file mode 100644
index fd909d4a..0000000
--- a/ipc/mojo/client_channel.mojom
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module IPC;
-
-interface ClientChannel {
-  Init(handle<message_pipe> pipe, int32 peer_pid) => (int32 pid);
-};
diff --git a/ipc/mojo/ipc.mojom b/ipc/mojo/ipc.mojom
new file mode 100644
index 0000000..dfc5770
--- /dev/null
+++ b/ipc/mojo/ipc.mojom
@@ -0,0 +1,24 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module IPC.mojom;
+
+struct Message {
+  array<uint8> data;
+  array<handle>? handles;
+};
+
+interface Channel {
+  Receive(Message message);
+};
+
+// An interface for connecting a pair of Channel interfaces representing a
+// bidirectional IPC channel.
+interface Bootstrap {
+  // Initializes a Chrome IPC channel over |to_client_channel| and
+  // |to_server_channel|. Each side also sends its PID to the other side.
+  Init(associated Channel& to_client_channel,
+       associated Channel to_server_channel,
+       int32 pid) => (int32 pid);
+};
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index 872fa74..69936481 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -20,7 +20,6 @@
 #include "ipc/ipc_logging.h"
 #include "ipc/ipc_message_attachment_set.h"
 #include "ipc/ipc_message_macros.h"
-#include "ipc/mojo/client_channel.mojom.h"
 #include "ipc/mojo/ipc_mojo_bootstrap.h"
 #include "ipc/mojo/ipc_mojo_handle_attachment.h"
 #include "mojo/edk/embedder/embedder.h"
@@ -34,135 +33,24 @@
 
 namespace {
 
-// TODO(jam): do more tests on using channel on same thread if it supports it (
-// i.e. with use-new-edk and Windows). Also see message_pipe_dispatcher.cc
-bool g_use_channel_on_io_thread_only = true;
-
 class MojoChannelFactory : public ChannelFactory {
  public:
-  MojoChannelFactory(scoped_refptr<base::TaskRunner> io_runner,
-                     ChannelHandle channel_handle,
-                     Channel::Mode mode)
-      : io_runner_(io_runner), channel_handle_(channel_handle), mode_(mode) {}
+  MojoChannelFactory(const std::string& token, Channel::Mode mode)
+      : token_(token), mode_(mode) {}
 
   std::string GetName() const override {
-    return channel_handle_.name;
+    return token_;
   }
 
   scoped_ptr<Channel> BuildChannel(Listener* listener) override {
-    return ChannelMojo::Create(io_runner_, channel_handle_, mode_, listener);
+    return ChannelMojo::Create(token_, mode_, listener);
   }
 
  private:
-  scoped_refptr<base::TaskRunner> io_runner_;
-  ChannelHandle channel_handle_;
-  Channel::Mode mode_;
-};
+  const std::string token_;
+  const Channel::Mode mode_;
 
-//------------------------------------------------------------------------------
-
-class ClientChannelMojo : public ChannelMojo, public ClientChannel {
- public:
-  ClientChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
-                    const ChannelHandle& handle,
-                    Listener* listener)
-      : ChannelMojo(io_runner, handle, Channel::MODE_CLIENT, listener),
-        binding_(this),
-        weak_factory_(this) {
-  }
-  ~ClientChannelMojo() override {}
-
-  // MojoBootstrap::Delegate implementation
-  void OnPipeAvailable(mojo::edk::ScopedPlatformHandle handle,
-                       int32_t peer_pid) override {
-    BindPipe(mojo::edk::CreateMessagePipe(std::move(handle)));
-  }
-
-  // ClientChannel implementation
-  void Init(
-      mojo::ScopedMessagePipeHandle pipe,
-      int32_t peer_pid,
-      const mojo::Callback<void(int32_t)>& callback) override {
-    InitMessageReader(std::move(pipe), static_cast<base::ProcessId>(peer_pid));
-   callback.Run(GetSelfPID());
-  }
-
- private:
-  void BindPipe(mojo::ScopedMessagePipeHandle handle) {
-    binding_.Bind(std::move(handle));
-  }
-  void OnConnectionError() {
-    listener()->OnChannelError();
-  }
-
-  mojo::Binding<ClientChannel> binding_;
-  base::WeakPtrFactory<ClientChannelMojo> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo);
-};
-
-//------------------------------------------------------------------------------
-
-class ServerChannelMojo : public ChannelMojo {
- public:
-  ServerChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
-                    const ChannelHandle& handle,
-                    Listener* listener)
-      : ChannelMojo(io_runner, handle, Channel::MODE_SERVER, listener),
-        weak_factory_(this) {
-  }
-  ~ServerChannelMojo() override {
-    Close();
-  }
-
-  // MojoBootstrap::Delegate implementation
-  void OnPipeAvailable(mojo::edk::ScopedPlatformHandle handle,
-                       int32_t peer_pid) override {
-    mojo::ScopedMessagePipeHandle peer;
-    MojoResult create_result =
-        mojo::CreateMessagePipe(nullptr, &message_pipe_, &peer);
-    if (create_result != MOJO_RESULT_OK) {
-      LOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result;
-      listener()->OnChannelError();
-      return;
-    }
-    InitClientChannel(std::move(peer),
-                      mojo::edk::CreateMessagePipe(std::move(handle)));
-  }
-  // Channel override
-  void Close() override {
-    client_channel_.reset();
-    message_pipe_.reset();
-    ChannelMojo::Close();
-  }
-
- private:
-  void InitClientChannel(mojo::ScopedMessagePipeHandle peer_handle,
-                         mojo::ScopedMessagePipeHandle handle) {
-    client_channel_.Bind(
-        mojo::InterfacePtrInfo<ClientChannel>(std::move(handle), 0u));
-    client_channel_.set_connection_error_handler(base::Bind(
-        &ServerChannelMojo::OnConnectionError, base::Unretained(this)));
-    client_channel_->Init(
-        std::move(peer_handle), static_cast<int32_t>(GetSelfPID()),
-        base::Bind(&ServerChannelMojo::ClientChannelWasInitialized,
-                   base::Unretained(this)));
-  }
-
-  void OnConnectionError() {
-    listener()->OnChannelError();
-  }
-
-  // ClientChannelClient implementation
-  void ClientChannelWasInitialized(int32_t peer_pid) {
-    InitMessageReader(std::move(message_pipe_), peer_pid);
-  }
-
-  mojo::InterfacePtr<ClientChannel> client_channel_;
-  mojo::ScopedMessagePipeHandle message_pipe_;
-  base::WeakPtrFactory<ServerChannelMojo> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo);
+  DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory);
 };
 
 #if defined(OS_POSIX) && !defined(OS_NACL)
@@ -186,140 +74,101 @@
 }
 
 // static
-scoped_ptr<ChannelMojo> ChannelMojo::Create(
-    scoped_refptr<base::TaskRunner> io_runner,
-    const ChannelHandle& channel_handle,
-    Mode mode,
-    Listener* listener) {
-  switch (mode) {
-    case Channel::MODE_CLIENT:
-      return make_scoped_ptr(
-          new ClientChannelMojo(io_runner, channel_handle, listener));
-    case Channel::MODE_SERVER:
-      return make_scoped_ptr(
-          new ServerChannelMojo(io_runner, channel_handle, listener));
-    default:
-      NOTREACHED();
-      return nullptr;
-  }
+scoped_ptr<ChannelMojo> ChannelMojo::Create(const std::string& token,
+                                            Mode mode,
+                                            Listener* listener) {
+  return make_scoped_ptr(
+      new ChannelMojo(token, mode, listener));
 }
 
 // static
 scoped_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
-    scoped_refptr<base::TaskRunner> io_runner,
-    const ChannelHandle& channel_handle) {
+    const std::string& token) {
   return make_scoped_ptr(
-      new MojoChannelFactory(io_runner, channel_handle, Channel::MODE_SERVER));
+      new MojoChannelFactory(token, Channel::MODE_SERVER));
 }
 
 // static
 scoped_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
-    scoped_refptr<base::TaskRunner> io_runner,
-    const ChannelHandle& channel_handle) {
+    const std::string& token) {
   return make_scoped_ptr(
-      new MojoChannelFactory(io_runner, channel_handle, Channel::MODE_CLIENT));
+      new MojoChannelFactory(token, Channel::MODE_CLIENT));
 }
 
-ChannelMojo::ChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
-                         const ChannelHandle& handle,
+ChannelMojo::ChannelMojo(const std::string& token,
                          Mode mode,
                          Listener* listener)
     : listener_(listener),
       peer_pid_(base::kNullProcessId),
-      io_runner_(io_runner),
       waiting_connect_(true),
       weak_factory_(this) {
   // Create MojoBootstrap after all members are set as it touches
   // ChannelMojo from a different thread.
-  bootstrap_ = MojoBootstrap::Create(handle, mode, this);
-  if (!g_use_channel_on_io_thread_only ||
-      io_runner == base::MessageLoop::current()->task_runner()) {
-    InitOnIOThread();
-  } else {
-    io_runner->PostTask(FROM_HERE, base::Bind(&ChannelMojo::InitOnIOThread,
-                                              base::Unretained(this)));
-  }
+  bootstrap_ = MojoBootstrap::Create(token, mode, this);
 }
 
 ChannelMojo::~ChannelMojo() {
   Close();
 }
 
-void ChannelMojo::InitOnIOThread() {
-  ipc_support_.reset(
-      new ScopedIPCSupport(base::MessageLoop::current()->task_runner()));
+scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>
+ChannelMojo::CreateMessageReader(mojom::ChannelAssociatedPtrInfo sender,
+                                 mojom::ChannelAssociatedRequest receiver) {
+  mojom::ChannelAssociatedPtr sender_ptr;
+  sender_ptr.Bind(std::move(sender));
+  return scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>(
+      new internal::MessagePipeReader(std::move(sender_ptr),
+                                      std::move(receiver), this));
 }
 
 bool ChannelMojo::Connect() {
   DCHECK(!message_reader_);
-  return bootstrap_->Connect();
+  bootstrap_->Connect();
+  return true;
 }
 
 void ChannelMojo::Close() {
-  scoped_ptr<internal::MessagePipeReader, ReaderDeleter> to_be_deleted;
+  message_reader_.reset();
+  // We might Close() before we Connect().
+  waiting_connect_ = false;
+}
 
-  {
-    // |message_reader_| has to be cleared inside the lock,
-    // but the instance has to be deleted outside.
-    base::AutoLock l(lock_);
-    to_be_deleted = std::move(message_reader_);
-    // We might Close() before we Connect().
-    waiting_connect_ = false;
-  }
-
-  ipc_support_.reset();
-  to_be_deleted.reset();
+// MojoBootstrap::Delegate implementation
+void ChannelMojo::OnPipesAvailable(
+    mojom::ChannelAssociatedPtrInfo send_channel,
+    mojom::ChannelAssociatedRequest receive_channel,
+    int32_t peer_pid) {
+  set_peer_pid(peer_pid);
+  InitMessageReader(std::move(send_channel), std::move(receive_channel));
 }
 
 void ChannelMojo::OnBootstrapError() {
   listener_->OnChannelError();
 }
 
-namespace {
+void ChannelMojo::InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
+                                    mojom::ChannelAssociatedRequest receiver) {
+  scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter> reader =
+      CreateMessageReader(std::move(sender), std::move(receiver));
 
-// ClosingDeleter calls |CloseWithErrorIfPending| before deleting the
-// |MessagePipeReader|.
-struct ClosingDeleter {
-  typedef std::default_delete<internal::MessagePipeReader> DefaultType;
-
-  void operator()(internal::MessagePipeReader* ptr) const {
-    ptr->CloseWithErrorIfPending();
-    delete ptr;
-  }
-};
-
-} // namespace
-
-void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe,
-                                    int32_t peer_pid) {
-  scoped_ptr<internal::MessagePipeReader, ClosingDeleter> reader(
-      new internal::MessagePipeReader(std::move(pipe), this));
-
-  {
-    base::AutoLock l(lock_);
-    for (size_t i = 0; i < pending_messages_.size(); ++i) {
-      bool sent = reader->Send(make_scoped_ptr(pending_messages_[i]));
-      pending_messages_[i] = nullptr;
-      if (!sent) {
-        // OnChannelError() is notified through ClosingDeleter.
-        pending_messages_.clear();
-        LOG(ERROR)  << "Failed to flush pending messages";
-        return;
-      }
+  for (size_t i = 0; i < pending_messages_.size(); ++i) {
+    bool sent = reader->Send(std::move(pending_messages_[i]));
+    if (!sent) {
+      // OnChannelError() is notified by OnPipeError().
+      pending_messages_.clear();
+      LOG(ERROR) << "Failed to flush pending messages";
+      return;
     }
-
-    // We set |message_reader_| here and won't get any |pending_messages_|
-    // hereafter. Although we might have some if there is an error, we don't
-    // care. They cannot be sent anyway.
-    message_reader_.reset(reader.release());
-    pending_messages_.clear();
-    waiting_connect_ = false;
   }
 
-  set_peer_pid(peer_pid);
+  // We set |message_reader_| here and won't get any |pending_messages_|
+  // hereafter. Although we might have some if there is an error, we don't
+  // care. They cannot be sent anyway.
+  message_reader_ = std::move(reader);
+  pending_messages_.clear();
+  waiting_connect_ = false;
+
   listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID()));
-  if (message_reader_)
-    message_reader_->ReadMessagesThenWait();
 }
 
 void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) {
@@ -331,11 +180,9 @@
 }
 
 
-// Warning: Keep the implementation thread-safe.
 bool ChannelMojo::Send(Message* message) {
-  base::AutoLock l(lock_);
   if (!message_reader_) {
-    pending_messages_.push_back(message);
+    pending_messages_.push_back(make_scoped_ptr(message));
     // Counts as OK before the connection is established, but it's an
     // error otherwise.
     return waiting_connect_;
@@ -344,10 +191,6 @@
   return message_reader_->Send(make_scoped_ptr(message));
 }
 
-bool ChannelMojo::IsSendThreadSafe() const {
-  return true;
-}
-
 base::ProcessId ChannelMojo::GetPeerPID() const {
   return peer_pid_;
 }
@@ -356,7 +199,7 @@
   return bootstrap_->GetSelfPID();
 }
 
-void ChannelMojo::OnMessageReceived(Message& message) {
+void ChannelMojo::OnMessageReceived(const Message& message) {
   TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
                "class", IPC_MESSAGE_ID_CLASS(message.type()),
                "line", IPC_MESSAGE_ID_LINE(message.type()));
@@ -367,18 +210,18 @@
 
 #if defined(OS_POSIX) && !defined(OS_NACL)
 int ChannelMojo::GetClientFileDescriptor() const {
-  return bootstrap_->GetClientFileDescriptor();
+  return -1;
 }
 
 base::ScopedFD ChannelMojo::TakeClientFileDescriptor() {
-  return bootstrap_->TakeClientFileDescriptor();
+  return base::ScopedFD(GetClientFileDescriptor());
 }
 #endif  // defined(OS_POSIX) && !defined(OS_NACL)
 
 // static
 MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
     Message* message,
-    std::vector<MojoHandle>* handles) {
+    mojo::Array<mojo::ScopedHandle>* handles) {
   // We dup() the handles in IPC::Message to transmit.
   // IPC::MessageAttachmentSet has intricate lifecycle semantics
   // of FDs, so just to dup()-and-own them is the safest option.
@@ -412,7 +255,8 @@
             return wrap_result;
           }
 
-          handles->push_back(wrapped_handle);
+          handles->push_back(
+              mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)));
         }
 #else
           NOTREACHED();
@@ -422,7 +266,7 @@
           mojo::ScopedHandle handle =
               static_cast<IPC::internal::MojoHandleAttachment*>(
                   attachment.get())->TakeHandle();
-          handles->push_back(handle.release().value());
+          handles->push_back(std::move(handle));
         } break;
         case MessageAttachment::TYPE_BROKERABLE_ATTACHMENT:
           // Brokerable attachments are handled by the AttachmentBroker so
@@ -440,12 +284,11 @@
 
 // static
 MojoResult ChannelMojo::WriteToMessageAttachmentSet(
-    const std::vector<MojoHandle>& handle_buffer,
+    mojo::Array<mojo::ScopedHandle> handle_buffer,
     Message* message) {
   for (size_t i = 0; i < handle_buffer.size(); ++i) {
     bool ok = message->attachment_set()->AddAttachment(
-        new IPC::internal::MojoHandleAttachment(
-            mojo::MakeScopedHandle(mojo::Handle(handle_buffer[i]))));
+        new IPC::internal::MojoHandleAttachment(std::move(handle_buffer[i])));
     DCHECK(ok);
     if (!ok) {
       LOG(ERROR) << "Failed to add new Mojo handle.";
diff --git a/ipc/mojo/ipc_channel_mojo.h b/ipc/mojo/ipc_channel_mojo.h
index ccd28c2..a996790 100644
--- a/ipc/mojo/ipc_channel_mojo.h
+++ b/ipc/mojo/ipc_channel_mojo.h
@@ -13,39 +13,22 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
 #include "build/build_config.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_channel_factory.h"
 #include "ipc/ipc_export.h"
 #include "ipc/mojo/ipc_message_pipe_reader.h"
 #include "ipc/mojo/ipc_mojo_bootstrap.h"
-#include "ipc/mojo/scoped_ipc_support.h"
+#include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/public/cpp/system/core.h"
 
 namespace IPC {
 
-// Mojo-based IPC::Channel implementation over a platform handle.
+// Mojo-based IPC::Channel implementation over a Mojo message pipe.
 //
-// ChannelMojo builds Mojo MessagePipe using underlying pipe given by
-// "bootstrap" IPC::Channel which creates and owns platform pipe like
-// named socket. The bootstrap Channel is used only for establishing
-// the underlying connection. ChannelMojo takes its handle over once
-// the it is made and puts MessagePipe on it.
+// ChannelMojo builds a Mojo MessagePipe using the provided token and builds an
+// associated interface for each direction on the channel.
 //
-// ChannelMojo has a couple of MessagePipes:
-//
-// * The first MessagePipe, which is built on top of bootstrap handle,
-//   is the "control" pipe. It is used to communicate out-of-band
-//   control messages that aren't visible from IPC::Listener.
-//
-// * The second MessagePipe, which is created by the server channel
-//   and sent to client Channel over the control pipe, is used
-//   to send IPC::Messages as an IPC::Sender.
-//
-// TODO(morrita): Extract handle creation part of IPC::Channel into
-//                separate class to clarify what ChannelMojo relies
-//                on.
 // TODO(morrita): Add APIs to create extra MessagePipes to let
 //                Mojo-based objects talk over this Channel.
 //
@@ -58,22 +41,18 @@
   static bool ShouldBeUsed();
 
   // Create ChannelMojo. A bootstrap channel is created as well.
-  static scoped_ptr<ChannelMojo> Create(
-      scoped_refptr<base::TaskRunner> io_runner,
-      const ChannelHandle& channel_handle,
-      Mode mode,
-      Listener* listener);
+  static scoped_ptr<ChannelMojo> Create(const std::string& token,
+                                        Mode mode,
+                                        Listener* listener);
 
   // Create a factory object for ChannelMojo.
   // The factory is used to create Mojo-based ChannelProxy family.
   // |host| must not be null.
   static scoped_ptr<ChannelFactory> CreateServerFactory(
-      scoped_refptr<base::TaskRunner> io_runner,
-      const ChannelHandle& channel_handle);
+      const std::string& token);
 
   static scoped_ptr<ChannelFactory> CreateClientFactory(
-      scoped_refptr<base::TaskRunner> io_runner,
-      const ChannelHandle& channel_handle);
+      const std::string& token);
 
   ~ChannelMojo() override;
 
@@ -81,7 +60,6 @@
   bool Connect() override;
   void Close() override;
   bool Send(Message* message) override;
-  bool IsSendThreadSafe() const override;
   base::ProcessId GetPeerPID() const override;
   base::ProcessId GetSelfPID() const override;
 
@@ -93,56 +71,50 @@
   // These access protected API of IPC::Message, which has ChannelMojo
   // as a friend class.
   static MojoResult WriteToMessageAttachmentSet(
-      const std::vector<MojoHandle>& handle_buffer,
+      mojo::Array<mojo::ScopedHandle> handle_buffer,
       Message* message);
   static MojoResult ReadFromMessageAttachmentSet(
       Message* message,
-      std::vector<MojoHandle>* handles);
+      mojo::Array<mojo::ScopedHandle>* handles);
 
   // MojoBootstrapDelegate implementation
+  void OnPipesAvailable(mojom::ChannelAssociatedPtrInfo send_channel,
+                        mojom::ChannelAssociatedRequest receive_channel,
+                        int32_t peer_pid) override;
   void OnBootstrapError() override;
 
   // MessagePipeReader::Delegate
-  void OnMessageReceived(Message& message) override;
+  void OnMessageReceived(const Message& message) override;
   void OnPipeClosed(internal::MessagePipeReader* reader) override;
   void OnPipeError(internal::MessagePipeReader* reader) override;
 
- protected:
-  ChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
-              const ChannelHandle& channel_handle,
+ private:
+  ChannelMojo(const std::string& token,
               Mode mode,
               Listener* listener);
 
-  void InitMessageReader(mojo::ScopedMessagePipeHandle pipe, int32_t peer_pid);
+  void InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
+                         mojom::ChannelAssociatedRequest receiver);
 
-  Listener* listener() const { return listener_; }
   void set_peer_pid(base::ProcessId pid) { peer_pid_ = pid; }
 
- private:
   // ChannelMojo needs to kill its MessagePipeReader in delayed manner
   // because the channel wants to kill these readers during the
   // notifications invoked by them.
   typedef internal::MessagePipeReader::DelayedDeleter ReaderDeleter;
 
-  void InitOnIOThread();
+  scoped_ptr<internal::MessagePipeReader, ReaderDeleter> CreateMessageReader(
+      mojom::ChannelAssociatedPtrInfo sender,
+      mojom::ChannelAssociatedRequest receiver);
 
   scoped_ptr<MojoBootstrap> bootstrap_;
   Listener* listener_;
   base::ProcessId peer_pid_;
-  scoped_refptr<base::TaskRunner> io_runner_;
 
-  // Guards |message_reader_|, |waiting_connect_| and |pending_messages_|
-  //
-  // * The contents of |pending_messages_| can be modified from any thread.
-  // * |message_reader_| is modified only from the IO thread,
-  //   but they can be referenced from other threads.
-  base::Lock lock_;
   scoped_ptr<internal::MessagePipeReader, ReaderDeleter> message_reader_;
-  ScopedVector<Message> pending_messages_;
+  std::vector<scoped_ptr<Message>> pending_messages_;
   bool waiting_connect_;
 
-  scoped_ptr<ScopedIPCSupport> ipc_support_;
-
   base::WeakPtrFactory<ChannelMojo> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ChannelMojo);
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc
index ed1e459..ec5efa6 100644
--- a/ipc/mojo/ipc_channel_mojo_unittest.cc
+++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -25,7 +25,6 @@
 #include "ipc/mojo/ipc_mojo_handle_attachment.h"
 #include "ipc/mojo/ipc_mojo_message_helper.h"
 #include "ipc/mojo/ipc_mojo_param_traits.h"
-#include "ipc/mojo/scoped_ipc_support.h"
 
 #if defined(OS_POSIX)
 #include "base/file_descriptor_posix.h"
diff --git a/ipc/mojo/ipc_message_pipe_reader.cc b/ipc/mojo/ipc_message_pipe_reader.cc
index 19d9e30..ab5466e3 100644
--- a/ipc/mojo/ipc_message_pipe_reader.cc
+++ b/ipc/mojo/ipc_message_pipe_reader.cc
@@ -13,58 +13,42 @@
 #include "base/logging.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
-#include "ipc/mojo/async_handle_waiter.h"
 #include "ipc/mojo/ipc_channel_mojo.h"
 
 namespace IPC {
 namespace internal {
 
-MessagePipeReader::MessagePipeReader(mojo::ScopedMessagePipeHandle handle,
-                                     MessagePipeReader::Delegate* delegate)
-    : pipe_(std::move(handle)),
-      handle_copy_(pipe_.get().value()),
-      delegate_(delegate),
-      async_waiter_(new AsyncHandleWaiter(
-          base::Bind(&MessagePipeReader::PipeIsReady, base::Unretained(this)))),
-      pending_send_error_(MOJO_RESULT_OK) {}
+MessagePipeReader::MessagePipeReader(
+    mojom::ChannelAssociatedPtr sender,
+    mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
+    MessagePipeReader::Delegate* delegate)
+    : delegate_(delegate),
+      sender_(std::move(sender)),
+      binding_(this, std::move(receiver)) {
+  sender_.set_connection_error_handler(
+      base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
+                 MOJO_RESULT_FAILED_PRECONDITION));
+  binding_.set_connection_error_handler(
+      base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
+                 MOJO_RESULT_FAILED_PRECONDITION));
+}
 
 MessagePipeReader::~MessagePipeReader() {
   DCHECK(thread_checker_.CalledOnValidThread());
   // The pipe should be closed before deletion.
-  CHECK(!IsValid());
 }
 
 void MessagePipeReader::Close() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  async_waiter_.reset();
-  pipe_.reset();
+  sender_.reset();
+  if (binding_.is_bound())
+    binding_.Close();
   OnPipeClosed();
 }
 
 void MessagePipeReader::CloseWithError(MojoResult error) {
   DCHECK(thread_checker_.CalledOnValidThread());
   OnPipeError(error);
-  Close();
-}
-
-void MessagePipeReader::CloseWithErrorIfPending() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  MojoResult pending_error = base::subtle::NoBarrier_Load(&pending_send_error_);
-  if (pending_error == MOJO_RESULT_OK)
-    return;
-  // NOTE: This races with Send(), and therefore the value of
-  // pending_send_error() can change.
-  CloseWithError(pending_error);
-  return;
-}
-
-void MessagePipeReader::CloseWithErrorLater(MojoResult error) {
-  DCHECK_NE(error, MOJO_RESULT_OK);
-  // NOTE: No assumptions about the value of |pending_send_error_| or whether or
-  // not the error has been signaled can be made. If Send() is called
-  // immediately before Close() and errors, it's possible for the error to not
-  // be signaled.
-  base::subtle::NoBarrier_Store(&pending_send_error_, error);
 }
 
 bool MessagePipeReader::Send(scoped_ptr<Message> message) {
@@ -72,39 +56,32 @@
                          "MessagePipeReader::Send",
                          message->flags(),
                          TRACE_EVENT_FLAG_FLOW_OUT);
-  std::vector<MojoHandle> handles;
+  mojom::MessagePtr ipc_message = mojom::Message::New();
   MojoResult result = MOJO_RESULT_OK;
-  result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles);
-  if (result == MOJO_RESULT_OK) {
-    result = MojoWriteMessage(handle(),
-                              message->data(),
-                              static_cast<uint32_t>(message->size()),
-                              handles.empty() ? nullptr : &handles[0],
-                              static_cast<uint32_t>(handles.size()),
-                              MOJO_WRITE_MESSAGE_FLAG_NONE);
-  }
-
+  result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(),
+                                                     &ipc_message->handles);
   if (result != MOJO_RESULT_OK) {
-    std::for_each(handles.begin(), handles.end(), &MojoClose);
-    // We cannot call CloseWithError() here as Send() is protected by
-    // ChannelMojo's lock and CloseWithError() could re-enter ChannelMojo. We
-    // cannot call CloseWithError() also because Send() can be called from
-    // non-UI thread while OnPipeError() expects to be called on IO thread.
-    CloseWithErrorLater(result);
+    CloseWithError(result);
     return false;
   }
-
+  ipc_message->data.resize(message->size());
+  std::copy(reinterpret_cast<const uint8_t*>(message->data()),
+            reinterpret_cast<const uint8_t*>(message->data()) + message->size(),
+            &ipc_message->data[0]);
+  sender_->Receive(std::move(ipc_message));
+  DVLOG(4) << "Send " << message->type() << ": " << message->size();
   return true;
 }
 
-void MessagePipeReader::OnMessageReceived() {
-  Message message(data_buffer().empty() ? "" : &data_buffer()[0],
-                  static_cast<uint32_t>(data_buffer().size()));
+void MessagePipeReader::Receive(mojom::MessagePtr ipc_message) {
+  Message message(ipc_message->data.size() == 0
+                      ? ""
+                      : reinterpret_cast<const char*>(&ipc_message->data[0]),
+                  static_cast<uint32_t>(ipc_message->data.size()));
 
-  std::vector<MojoHandle> handle_buffer;
-  TakeHandleBuffer(&handle_buffer);
-  MojoResult write_result =
-      ChannelMojo::WriteToMessageAttachmentSet(handle_buffer, &message);
+  DVLOG(4) << "Receive " << message.type() << ": " << message.size();
+  MojoResult write_result = ChannelMojo::WriteToMessageAttachmentSet(
+      std::move(ipc_message->handles), &message);
   if (write_result != MOJO_RESULT_OK) {
     CloseWithError(write_result);
     return;
@@ -127,110 +104,9 @@
 
 void MessagePipeReader::OnPipeError(MojoResult error) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (!delegate_)
-    return;
-  delegate_->OnPipeError(this);
-}
-
-MojoResult MessagePipeReader::ReadMessageBytes() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(handle_buffer_.empty());
-
-  uint32_t num_bytes = static_cast<uint32_t>(data_buffer_.size());
-  uint32_t num_handles = 0;
-  MojoResult result = MojoReadMessage(pipe_.get().value(),
-                                      num_bytes ? &data_buffer_[0] : nullptr,
-                                      &num_bytes,
-                                      nullptr,
-                                      &num_handles,
-                                      MOJO_READ_MESSAGE_FLAG_NONE);
-  data_buffer_.resize(num_bytes);
-  handle_buffer_.resize(num_handles);
-  if (result == MOJO_RESULT_RESOURCE_EXHAUSTED) {
-    // MOJO_RESULT_RESOURCE_EXHAUSTED was asking the caller that
-    // it needs more bufer. So we re-read it with resized buffers.
-    result = MojoReadMessage(pipe_.get().value(),
-                             num_bytes ? &data_buffer_[0] : nullptr,
-                             &num_bytes,
-                             num_handles ? &handle_buffer_[0] : nullptr,
-                             &num_handles,
-                             MOJO_READ_MESSAGE_FLAG_NONE);
-  }
-
-  DCHECK(0 == num_bytes || data_buffer_.size() == num_bytes);
-  DCHECK(0 == num_handles || handle_buffer_.size() == num_handles);
-  return result;
-}
-
-void MessagePipeReader::ReadAvailableMessages() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  while (pipe_.is_valid()) {
-    MojoResult read_result = ReadMessageBytes();
-    if (read_result == MOJO_RESULT_SHOULD_WAIT)
-      break;
-    if (read_result != MOJO_RESULT_OK) {
-      DLOG(WARNING)
-          << "Pipe got error from ReadMessage(). Closing: " << read_result;
-      OnPipeError(read_result);
-      Close();
-      break;
-    }
-
-    OnMessageReceived();
-  }
-
-}
-
-void MessagePipeReader::ReadMessagesThenWait() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  while (true) {
-    ReadAvailableMessages();
-    if (!pipe_.is_valid())
-      break;
-    // |Wait()| is safe to call only after all messages are read.
-    // If can fail with |MOJO_RESULT_ALREADY_EXISTS| otherwise.
-    // Also, we don't use MOJO_HANDLE_SIGNAL_WRITABLE here, expecting buffer in
-    // MessagePipe.
-    MojoResult result =
-        async_waiter_->Wait(pipe_.get().value(), MOJO_HANDLE_SIGNAL_READABLE);
-    // If the result is |MOJO_RESULT_ALREADY_EXISTS|, there could be messages
-    // that have been arrived after the last |ReadAvailableMessages()|.
-    // We have to consume then and retry in that case.
-    if (result != MOJO_RESULT_ALREADY_EXISTS) {
-      if (result != MOJO_RESULT_OK) {
-        LOG(ERROR) << "Failed to wait on the pipe. Result is " << result;
-        OnPipeError(result);
-        Close();
-      }
-
-      break;
-    }
-  }
-}
-
-void MessagePipeReader::PipeIsReady(MojoResult wait_result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  CloseWithErrorIfPending();
-  if (!IsValid()) {
-    // There was a pending error and it closed the pipe.
-    // We cannot do the work anymore.
-    return;
-  }
-
-  if (wait_result != MOJO_RESULT_OK) {
-    if (wait_result != MOJO_RESULT_ABORTED) {
-      // FAILED_PRECONDITION happens every time the peer is dead so
-      // it isn't worth polluting the log message.
-      LOG_IF(WARNING, wait_result != MOJO_RESULT_FAILED_PRECONDITION)
-          << "Pipe got error from the waiter. Closing: " << wait_result;
-      OnPipeError(wait_result);
-    }
-
-    Close();
-    return;
-  }
-
-  ReadMessagesThenWait();
+  if (delegate_)
+    delegate_->OnPipeError(this);
+  Close();
 }
 
 void MessagePipeReader::DelayedDeleter::operator()(
diff --git a/ipc/mojo/ipc_message_pipe_reader.h b/ipc/mojo/ipc_message_pipe_reader.h
index 37581230..7120fc60 100644
--- a/ipc/mojo/ipc_message_pipe_reader.h
+++ b/ipc/mojo/ipc_message_pipe_reader.h
@@ -16,7 +16,9 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "ipc/ipc_message.h"
+#include "ipc/mojo/ipc.mojom.h"
 #include "mojo/public/c/environment/async_waiter.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/system/core.h"
 
 namespace IPC {
@@ -40,11 +42,11 @@
 // be called on any thread. All |Delegate| functions will be called on the IO
 // thread.
 //
-class MessagePipeReader {
+class MessagePipeReader : public mojom::Channel {
  public:
   class Delegate {
    public:
-    virtual void OnMessageReceived(Message& message) = 0;
+    virtual void OnMessageReceived(const Message& message) = 0;
     virtual void OnPipeClosed(MessagePipeReader* reader) = 0;
     virtual void OnPipeError(MessagePipeReader* reader) = 0;
   };
@@ -65,60 +67,35 @@
   };
 
   // Both parameters must be non-null.
-  // Build a reader that reads messages from |handle| and lets |delegate| know.
-  // Note that MessagePipeReader doesn't delete |delete|.
-  MessagePipeReader(mojo::ScopedMessagePipeHandle handle, Delegate* delegate);
-  virtual ~MessagePipeReader();
-
-  MojoHandle handle() const { return handle_copy_; }
-
-  // Returns received bytes.
-  const std::vector<char>& data_buffer() const {
-    return data_buffer_;
-  }
-
-  // Delegate received handles ownership. The subclass should take the
-  // ownership over in its OnMessageReceived(). They will leak otherwise.
-  void TakeHandleBuffer(std::vector<MojoHandle>* handle_buffer) {
-    handle_buffer_.swap(*handle_buffer);
-  }
+  // Build a reader that reads messages from |receive_handle| and lets
+  // |delegate| know.
+  // Note that MessagePipeReader doesn't delete |delegate|.
+  MessagePipeReader(mojom::ChannelAssociatedPtr sender,
+                    mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
+                    Delegate* delegate);
+  ~MessagePipeReader() override;
 
   // Close and destroy the MessagePipe.
   void Close();
   // Close the mesage pipe with notifying the client with the error.
   void CloseWithError(MojoResult error);
-  void CloseWithErrorLater(MojoResult error);
-  void CloseWithErrorIfPending();
 
   // Return true if the MessagePipe is alive.
-  bool IsValid() { return pipe_.is_valid(); }
+  bool IsValid() { return sender_; }
 
   bool Send(scoped_ptr<Message> message);
-  void ReadMessagesThenWait();
 
- private:
-  void OnMessageReceived();
+ protected:
   void OnPipeClosed();
   void OnPipeError(MojoResult error);
 
-  MojoResult ReadMessageBytes();
-  void PipeIsReady(MojoResult wait_result);
-  void ReadAvailableMessages();
+ private:
+  void Receive(mojom::MessagePtr message) override;
 
-  std::vector<char>  data_buffer_;
-  std::vector<MojoHandle> handle_buffer_;
-  mojo::ScopedMessagePipeHandle pipe_;
-  // Constant copy of the message pipe handle. For use by Send(), which can run
-  // concurrently on non-IO threads.
-  // TODO(amistry): This isn't quite right because handles can be re-used and
-  // using this can run into the ABA problem. Currently, this is highly unlikely
-  // because Mojo internally uses an increasing uint32_t as handle values, but
-  // this could change. See crbug.com/524894.
-  const MojoHandle handle_copy_;
-  // |delegate_| and |async_waiter_| are null once the message pipe is closed.
+  // |delegate_| is null once the message pipe is closed.
   Delegate* delegate_;
-  scoped_ptr<AsyncHandleWaiter> async_waiter_;
-  base::subtle::Atomic32 pending_send_error_;
+  mojom::ChannelAssociatedPtr sender_;
+  mojo::AssociatedBinding<mojom::Channel> binding_;
   base::ThreadChecker thread_checker_;
 
   DISALLOW_COPY_AND_ASSIGN(MessagePipeReader);
diff --git a/ipc/mojo/ipc_mojo.gyp b/ipc/mojo/ipc_mojo.gyp
index 59255460..c471d37 100644
--- a/ipc/mojo/ipc_mojo.gyp
+++ b/ipc/mojo/ipc_mojo.gyp
@@ -27,9 +27,6 @@
         '../../mojo/mojo_public.gyp:mojo_cpp_bindings',
       ],
       'sources': [
-        'client_channel.mojom',
-        'async_handle_waiter.cc',
-        'async_handle_waiter.h',
         'ipc_channel_mojo.cc',
         'ipc_channel_mojo.h',
         'ipc_mojo_bootstrap.cc',
@@ -42,6 +39,7 @@
         'ipc_mojo_param_traits.h',
         'ipc_message_pipe_reader.cc',
         'ipc_message_pipe_reader.h',
+        'ipc.mojom',
         'scoped_ipc_support.cc',
         'scoped_ipc_support.h',
       ],
@@ -63,6 +61,7 @@
         '../../base/base.gyp:base_i18n',
         '../../base/base.gyp:test_support_base',
         '../../mojo/mojo_base.gyp:mojo_environment_chromium',
+        '../../mojo/mojo_edk.gyp:mojo_common_test_support',
         '../../mojo/mojo_edk.gyp:mojo_system_impl',
         '../../mojo/mojo_public.gyp:mojo_cpp_bindings',
         '../../testing/gtest.gyp:gtest',
@@ -72,14 +71,12 @@
         '..'
       ],
       'sources': [
-        'async_handle_waiter_unittest.cc',
         'run_all_unittests.cc',
 
         # TODO(rockot): Re-enable these when we're ready to start using
         # ChannelMojo again. They need to be updated to support multiprocess
         # testing with the current Mojo EDK implementation.
         #"ipc_channel_mojo_unittest.cc",
-        'ipc_channel_mojo_unittest.cc',
         'ipc_mojo_bootstrap_unittest.cc',
       ],
       'conditions': [
@@ -96,6 +93,7 @@
         '../../base/base.gyp:test_support_base',
         '../../base/base.gyp:test_support_perf',
         '../../mojo/mojo_base.gyp:mojo_environment_chromium',
+        '../../mojo/mojo_edk.gyp:mojo_common_test_support',
         '../../mojo/mojo_edk.gyp:mojo_system_impl',
         '../../mojo/mojo_public.gyp:mojo_cpp_bindings',
         '../../testing/gtest.gyp:gtest',
diff --git a/ipc/mojo/ipc_mojo_bootstrap.cc b/ipc/mojo/ipc_mojo_bootstrap.cc
index 74b3009c..6ace754 100644
--- a/ipc/mojo/ipc_mojo_bootstrap.cc
+++ b/ipc/mojo/ipc_mojo_bootstrap.cc
@@ -13,7 +13,9 @@
 #include "build/build_config.h"
 #include "ipc/ipc_message_utils.h"
 #include "ipc/ipc_platform_file.h"
+#include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/public/cpp/bindings/binding.h"
 
 namespace IPC {
 
@@ -26,124 +28,97 @@
   MojoServerBootstrap();
 
  private:
-  void SendClientPipe(int32_t peer_pid);
+  // MojoBootstrap implementation.
+  void Connect() override;
 
-  // Listener implementations
-  bool OnMessageReceived(const Message& message) override;
-  void OnChannelConnected(int32_t peer_pid) override;
+  void OnInitDone(int32_t peer_pid);
 
-  mojo::edk::ScopedPlatformHandle server_pipe_;
-  bool connected_;
-  int32_t peer_pid_;
+  mojom::BootstrapPtr bootstrap_;
+  IPC::mojom::ChannelAssociatedPtrInfo send_channel_;
+  IPC::mojom::ChannelAssociatedRequest receive_channel_request_;
 
   DISALLOW_COPY_AND_ASSIGN(MojoServerBootstrap);
 };
 
-MojoServerBootstrap::MojoServerBootstrap() : connected_(false), peer_pid_(0) {
-}
+MojoServerBootstrap::MojoServerBootstrap() = default;
 
-void MojoServerBootstrap::SendClientPipe(int32_t peer_pid) {
+void MojoServerBootstrap::Connect() {
   DCHECK_EQ(state(), STATE_INITIALIZED);
-  DCHECK(connected_);
 
-  mojo::edk::PlatformChannelPair channel_pair;
-  server_pipe_ = channel_pair.PassServerHandle();
+  bootstrap_.Bind(
+      mojom::BootstrapPtrInfo(mojo::edk::CreateParentMessagePipe(token()), 0));
+  bootstrap_.set_connection_error_handler(
+      base::Bind(&MojoServerBootstrap::Fail, base::Unretained(this)));
 
-  base::Process peer_process =
-#if defined(OS_WIN)
-      base::Process::OpenWithAccess(peer_pid, PROCESS_DUP_HANDLE);
-#else
-      base::Process::Open(peer_pid);
-#endif
-  PlatformFileForTransit client_pipe = GetFileHandleForProcess(
-      channel_pair.PassClientHandle().release().handle,
-      peer_process.Handle(), true);
-  if (client_pipe == IPC::InvalidPlatformFileForTransit()) {
-#if !defined(OS_WIN)
-    // GetFileHandleForProcess() only fails on Windows.
-    NOTREACHED();
-#endif
-    LOG(WARNING) << "Failed to translate file handle for client process.";
-    Fail();
-    return;
-  }
+  IPC::mojom::ChannelAssociatedRequest send_channel_request;
+  IPC::mojom::ChannelAssociatedPtrInfo receive_channel;
 
-  scoped_ptr<Message> message(new Message());
-  ParamTraits<PlatformFileForTransit>::Write(message.get(), client_pipe);
-  Send(message.release());
+  bootstrap_.associated_group()->CreateAssociatedInterface(
+      mojo::AssociatedGroup::WILL_PASS_REQUEST, &send_channel_,
+      &send_channel_request);
+  bootstrap_.associated_group()->CreateAssociatedInterface(
+      mojo::AssociatedGroup::WILL_PASS_PTR, &receive_channel,
+      &receive_channel_request_);
+
+  bootstrap_->Init(
+      std::move(send_channel_request), std::move(receive_channel),
+      GetSelfPID(),
+      base::Bind(&MojoServerBootstrap::OnInitDone, base::Unretained(this)));
 
   set_state(STATE_WAITING_ACK);
 }
 
-void MojoServerBootstrap::OnChannelConnected(int32_t peer_pid) {
-  DCHECK_EQ(state(), STATE_INITIALIZED);
-  connected_ = true;
-  peer_pid_ = peer_pid;
-  SendClientPipe(peer_pid);
-}
-
-bool MojoServerBootstrap::OnMessageReceived(const Message&) {
+void MojoServerBootstrap::OnInitDone(int32_t peer_pid) {
   if (state() != STATE_WAITING_ACK) {
     set_state(STATE_ERROR);
     LOG(ERROR) << "Got inconsistent message from client.";
-    return false;
+    return;
   }
 
   set_state(STATE_READY);
-  CHECK(server_pipe_.is_valid());
-  delegate()->OnPipeAvailable(
-      mojo::edk::ScopedPlatformHandle(server_pipe_.release()), peer_pid_);
-
-  return true;
+  bootstrap_.set_connection_error_handler(mojo::Closure());
+  delegate()->OnPipesAvailable(std::move(send_channel_),
+                               std::move(receive_channel_request_), peer_pid);
 }
 
 // MojoBootstrap for client processes. You should create the instance
 // using MojoBootstrap::Create().
-class MojoClientBootstrap : public MojoBootstrap {
+class MojoClientBootstrap : public MojoBootstrap, public mojom::Bootstrap {
  public:
   MojoClientBootstrap();
 
  private:
-  // Listener implementations
-  bool OnMessageReceived(const Message& message) override;
-  void OnChannelConnected(int32_t peer_pid) override;
+  // MojoBootstrap implementation.
+  void Connect() override;
 
-  int32_t peer_pid_;
+  // mojom::Bootstrap implementation.
+  void Init(mojom::ChannelAssociatedRequest receive_channel,
+            mojom::ChannelAssociatedPtrInfo send_channel,
+            int32_t peer_pid,
+            const mojo::Callback<void(int32_t)>& callback) override;
+
+  mojo::Binding<mojom::Bootstrap> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(MojoClientBootstrap);
 };
 
-MojoClientBootstrap::MojoClientBootstrap() : peer_pid_(0) {
+MojoClientBootstrap::MojoClientBootstrap() : binding_(this) {}
+
+void MojoClientBootstrap::Connect() {
+  binding_.Bind(mojo::edk::CreateChildMessagePipe(token()));
+  binding_.set_connection_error_handler(
+      base::Bind(&MojoClientBootstrap::Fail, base::Unretained(this)));
 }
 
-bool MojoClientBootstrap::OnMessageReceived(const Message& message) {
-  if (state() != STATE_INITIALIZED) {
-    set_state(STATE_ERROR);
-    LOG(ERROR) << "Got inconsistent message from server.";
-    return false;
-  }
-
-  PlatformFileForTransit pipe;
-  base::PickleIterator iter(message);
-  if (!ParamTraits<PlatformFileForTransit>::Read(&message, &iter, &pipe)) {
-    LOG(WARNING) << "Failed to read a file handle from bootstrap channel.";
-    message.set_dispatch_error();
-    return false;
-  }
-
-  // Sends ACK back.
-  Send(new Message());
+void MojoClientBootstrap::Init(mojom::ChannelAssociatedRequest receive_channel,
+                               mojom::ChannelAssociatedPtrInfo send_channel,
+                               int32_t peer_pid,
+                               const mojo::Callback<void(int32_t)>& callback) {
+  callback.Run(GetSelfPID());
   set_state(STATE_READY);
-  delegate()->OnPipeAvailable(
-      mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(
-          PlatformFileForTransitToPlatformFile(pipe))),
-      peer_pid_);
-
-  return true;
-}
-
-void MojoClientBootstrap::OnChannelConnected(int32_t peer_pid) {
-  peer_pid_ = peer_pid;
+  binding_.set_connection_error_handler(mojo::Closure());
+  delegate()->OnPipesAvailable(std::move(send_channel),
+                               std::move(receive_channel), peer_pid);
 }
 
 }  // namespace
@@ -151,7 +126,7 @@
 // MojoBootstrap
 
 // static
-scoped_ptr<MojoBootstrap> MojoBootstrap::Create(ChannelHandle handle,
+scoped_ptr<MojoBootstrap> MojoBootstrap::Create(const std::string& token,
                                                 Channel::Mode mode,
                                                 Delegate* delegate) {
   CHECK(mode == Channel::MODE_CLIENT || mode == Channel::MODE_SERVER);
@@ -160,40 +135,26 @@
           ? scoped_ptr<MojoBootstrap>(new MojoClientBootstrap())
           : scoped_ptr<MojoBootstrap>(new MojoServerBootstrap());
 
-  scoped_ptr<Channel> bootstrap_channel =
-      Channel::Create(handle, mode, self.get());
-  self->Init(std::move(bootstrap_channel), delegate);
+  self->Init(token, delegate);
   return self;
 }
 
 MojoBootstrap::MojoBootstrap() : delegate_(NULL), state_(STATE_INITIALIZED) {
 }
 
-MojoBootstrap::~MojoBootstrap() {
-}
+MojoBootstrap::~MojoBootstrap() {}
 
-void MojoBootstrap::Init(scoped_ptr<Channel> channel, Delegate* delegate) {
-  channel_ = std::move(channel);
+void MojoBootstrap::Init(const std::string& token, Delegate* delegate) {
+  token_ = token;
   delegate_ = delegate;
 }
 
-bool MojoBootstrap::Connect() {
-  return channel_->Connect();
-}
-
 base::ProcessId MojoBootstrap::GetSelfPID() const {
-  return channel_->GetSelfPID();
-}
-
-void MojoBootstrap::OnBadMessageReceived(const Message& message) {
-  Fail();
-}
-
-void MojoBootstrap::OnChannelError() {
-  if (state_ == STATE_READY || state_ == STATE_ERROR)
-    return;
-  DLOG(WARNING) << "Detected error on Mojo bootstrap channel.";
-  Fail();
+#if defined(OS_LINUX)
+  if (int global_pid = Channel::GetGlobalPid())
+    return global_pid;
+#endif  // OS_LINUX
+  return base::GetCurrentProcId();
 }
 
 void MojoBootstrap::Fail() {
@@ -205,18 +166,4 @@
   return state() == STATE_ERROR;
 }
 
-bool MojoBootstrap::Send(Message* message) {
-  return channel_->Send(message);
-}
-
-#if defined(OS_POSIX) && !defined(OS_NACL)
-int MojoBootstrap::GetClientFileDescriptor() const {
-  return channel_->GetClientFileDescriptor();
-}
-
-base::ScopedFD MojoBootstrap::TakeClientFileDescriptor() {
-  return channel_->TakeClientFileDescriptor();
-}
-#endif  // defined(OS_POSIX) && !defined(OS_NACL)
-
 }  // namespace IPC
diff --git a/ipc/mojo/ipc_mojo_bootstrap.h b/ipc/mojo/ipc_mojo_bootstrap.h
index e4d2d277..4c97850 100644
--- a/ipc/mojo/ipc_mojo_bootstrap.h
+++ b/ipc/mojo/ipc_mojo_bootstrap.h
@@ -13,50 +13,46 @@
 #include "build/build_config.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_listener.h"
+#include "ipc/mojo/ipc.mojom.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
+#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace IPC {
 
-// MojoBootstrap establishes a bootstrap pipe between two processes in
-// Chrome. It creates a native IPC::Channel first, then sends one
-// side of a newly created pipe to peer process. The pipe is intended
-// to be wrapped by Mojo MessagePipe.
+// MojoBootstrap establishes a pair of associated interfaces between two
+// processes in Chrome.
 //
-// Clients should implement MojoBootstrapDelegate to get the pipe
+// Clients should implement MojoBootstrap::Delegate to get the associated pipes
 // from MojoBootstrap object.
 //
 // This lives on IO thread other than Create(), which can be called from
 // UI thread as Channel::Create() can be.
-class IPC_MOJO_EXPORT MojoBootstrap : public Listener {
+class IPC_MOJO_EXPORT MojoBootstrap {
  public:
   class Delegate {
    public:
-    virtual void OnPipeAvailable(mojo::edk::ScopedPlatformHandle handle,
-                                 int32_t peer_pid) = 0;
+    virtual void OnPipesAvailable(
+        mojom::ChannelAssociatedPtrInfo send_channel,
+        mojom::ChannelAssociatedRequest receive_channel,
+        int32_t peer_pid) = 0;
     virtual void OnBootstrapError() = 0;
   };
 
-  // Create the MojoBootstrap instance.
-  // Instead of creating IPC::Channel, passs its ChannelHandle as |handle|,
-  // mode as |mode|. The result is notified to passed |delegate|.
-  static scoped_ptr<MojoBootstrap> Create(ChannelHandle handle,
+  // Create the MojoBootstrap instance, using |token| to create the message
+  // pipe, in mode as specified by |mode|. The result is passed to |delegate|.
+  static scoped_ptr<MojoBootstrap> Create(const std::string& token,
                                           Channel::Mode mode,
                                           Delegate* delegate);
 
   MojoBootstrap();
-  ~MojoBootstrap() override;
+  virtual ~MojoBootstrap();
 
-  // Start the handshake over the underlying platform channel.
-  bool Connect();
+  // Start the handshake over the underlying message pipe.
+  virtual void Connect() = 0;
 
-  // GetSelfPID returns the PID associated with |channel_|.
+  // GetSelfPID returns our PID.
   base::ProcessId GetSelfPID() const;
 
-#if defined(OS_POSIX) && !defined(OS_NACL)
-  int GetClientFileDescriptor() const;
-  base::ScopedFD TakeClientFileDescriptor();
-#endif  // defined(OS_POSIX) && !defined(OS_NACL)
-
  protected:
   // On MojoServerBootstrap: INITIALIZED -> WAITING_ACK -> READY
   // On MojoClientBootstrap: INITIALIZED -> READY
@@ -64,21 +60,18 @@
   enum State { STATE_INITIALIZED, STATE_WAITING_ACK, STATE_READY, STATE_ERROR };
 
   Delegate* delegate() const { return delegate_; }
-  bool Send(Message* message);
   void Fail();
   bool HasFailed() const;
 
   State state() const { return state_; }
   void set_state(State state) { state_ = state; }
 
+  const std::string& token() { return token_; }
+
  private:
-  void Init(scoped_ptr<Channel> channel, Delegate* delegate);
+  void Init(const std::string& token, Delegate* delegate);
 
-  // Listener implementations
-  void OnBadMessageReceived(const Message& message) override;
-  void OnChannelError() override;
-
-  scoped_ptr<Channel> channel_;
+  std::string token_;
   Delegate* delegate_;
   State state_;
 
diff --git a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
index 8ee5556a..efd2b809 100644
--- a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
+++ b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
@@ -9,8 +9,14 @@
 #include "base/base_paths.h"
 #include "base/files/file.h"
 #include "base/message_loop/message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "ipc/ipc_test_base.h"
+#include "ipc/mojo/ipc.mojom.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/test/mojo_test_base.h"
+#include "mojo/edk/test/multiprocess_test_helper.h"
+#include "mojo/edk/test/scoped_ipc_support.h"
 
 #if defined(OS_POSIX)
 #include "base/file_descriptor_posix.h"
@@ -18,34 +24,41 @@
 
 namespace {
 
-class IPCMojoBootstrapTest : public IPCTestBase {
+class IPCMojoBootstrapTest : public mojo::edk::test::MojoTestBase {
  protected:
 };
 
 class TestingDelegate : public IPC::MojoBootstrap::Delegate {
  public:
-  TestingDelegate() : passed_(false) {}
+  explicit TestingDelegate(const base::Closure& quit_callback)
+      : passed_(false), quit_callback_(quit_callback) {}
 
-  void OnPipeAvailable(mojo::edk::ScopedPlatformHandle handle,
-                       int32_t peer_pid) override;
+  void OnPipesAvailable(IPC::mojom::ChannelAssociatedPtrInfo send_channel,
+                        IPC::mojom::ChannelAssociatedRequest receive_channel,
+                        int32_t peer_pid) override;
   void OnBootstrapError() override;
 
   bool passed() const { return passed_; }
 
  private:
   bool passed_;
+  const base::Closure quit_callback_;
 };
 
-void TestingDelegate::OnPipeAvailable(mojo::edk::ScopedPlatformHandle handle,
-                                      int32_t peer_pid) {
+void TestingDelegate::OnPipesAvailable(
+    IPC::mojom::ChannelAssociatedPtrInfo send_channel,
+    IPC::mojom::ChannelAssociatedRequest receive_channel,
+    int32_t peer_pid) {
   passed_ = true;
-  base::MessageLoop::current()->QuitWhenIdle();
+  quit_callback_.Run();
 }
 
 void TestingDelegate::OnBootstrapError() {
-  base::MessageLoop::current()->QuitWhenIdle();
+  quit_callback_.Run();
 }
 
+const char kMojoChannelToken[] = "IPCMojoBootstrapTest token";
+
 // Times out on Android; see http://crbug.com/502290
 #if defined(OS_ANDROID)
 #define MAYBE_Connect DISABLED_Connect
@@ -53,41 +66,47 @@
 #define MAYBE_Connect Connect
 #endif
 TEST_F(IPCMojoBootstrapTest, MAYBE_Connect) {
-  Init("IPCMojoBootstrapTestClient");
-
-  TestingDelegate delegate;
+  base::MessageLoop message_loop;
+  base::RunLoop run_loop;
+  TestingDelegate delegate(run_loop.QuitClosure());
   scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create(
-      GetTestChannelHandle(), IPC::Channel::MODE_SERVER, &delegate);
+      kMojoChannelToken, IPC::Channel::MODE_SERVER, &delegate);
+  RUN_CHILD_ON_PIPE(IPCMojoBootstrapTestClient, unused_pipe)
 
-  ASSERT_TRUE(bootstrap->Connect());
-#if defined(OS_POSIX)
-  ASSERT_TRUE(StartClientWithFD(bootstrap->GetClientFileDescriptor()));
-#else
-  ASSERT_TRUE(StartClient());
-#endif
-
-  base::MessageLoop::current()->Run();
+  bootstrap->Connect();
+  run_loop.Run();
 
   EXPECT_TRUE(delegate.passed());
-  EXPECT_TRUE(WaitForClientShutdown());
+  END_CHILD()
 }
 
-// A long running process that connects to us.
-MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCMojoBootstrapTestClient) {
-  base::MessageLoopForIO main_message_loop;
+class IPCMojoBootstrapTestClient {
 
-  TestingDelegate delegate;
+};
+
+}  // namespace
+
+namespace mojo {
+namespace edk {
+namespace {
+
+// A long running process that connects to us.
+DEFINE_TEST_CLIENT_TEST_WITH_PIPE(IPCMojoBootstrapTestClient,
+                             IPCMojoBootstrapTest,
+                             unused_pipe) {
+  base::MessageLoop message_loop;
+  base::RunLoop run_loop;
+  TestingDelegate delegate(run_loop.QuitClosure());
   scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create(
-      IPCTestBase::GetChannelName("IPCMojoBootstrapTestClient"),
-      IPC::Channel::MODE_CLIENT, &delegate);
+      kMojoChannelToken, IPC::Channel::MODE_CLIENT, &delegate);
 
   bootstrap->Connect();
 
-  base::MessageLoop::current()->Run();
+  run_loop.Run();
 
   EXPECT_TRUE(delegate.passed());
-
-  return 0;
 }
 
 }  // namespace
+}  // namespace edk
+}  // namespace mojo
diff --git a/ipc/mojo/ipc_mojo_perftest.cc b/ipc/mojo/ipc_mojo_perftest.cc
index 577c1c4..92b79f8 100644
--- a/ipc/mojo/ipc_mojo_perftest.cc
+++ b/ipc/mojo/ipc_mojo_perftest.cc
@@ -4,54 +4,65 @@
 
 #include <stddef.h>
 
-#include "base/lazy_instance.h"
 #include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "ipc/ipc_perftest_support.h"
 #include "ipc/mojo/ipc_channel_mojo.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/edk/test/multiprocess_test_helper.h"
+#include "mojo/edk/test/scoped_ipc_support.h"
 
+namespace IPC {
 namespace {
 
-// This is needed because we rely on //base/test:test_support_perf and
-// it provides main() which doesn't have Mojo initialization.  We need
-// some way to call Init() only once before using Mojo.
-struct MojoInitialier {
-  MojoInitialier() { mojo::edk::Init(); }
-};
+const char kPerftestToken[] = "perftest-token";
 
-base::LazyInstance<MojoInitialier> g_mojo_initializer
-    = LAZY_INSTANCE_INITIALIZER;
-
-class MojoChannelPerfTest : public IPC::test::IPCChannelPerfTestBase {
-public:
-  typedef IPC::test::IPCChannelPerfTestBase Super;
-
-  MojoChannelPerfTest();
+class MojoChannelPerfTest : public test::IPCChannelPerfTestBase {
+ public:
+  MojoChannelPerfTest() { token_ = mojo::edk::GenerateRandomToken(); }
 
   void TearDown() override {
-    IPC::test::IPCChannelPerfTestBase::TearDown();
+    {
+      base::AutoLock l(ipc_support_lock_);
+      ipc_support_.reset();
+    }
+    test::IPCChannelPerfTestBase::TearDown();
   }
 
-  scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
-      const IPC::ChannelHandle& handle,
+  scoped_ptr<ChannelFactory> CreateChannelFactory(
+      const ChannelHandle& handle,
       base::SequencedTaskRunner* runner) override {
-    return IPC::ChannelMojo::CreateServerFactory(runner, handle);
+    EnsureIpcSupport();
+    return ChannelMojo::CreateServerFactory(token_);
   }
 
-  bool DidStartClient() override {
-    bool ok = IPCTestBase::DidStartClient();
-    DCHECK(ok);
-    return ok;
+  bool StartClient() override {
+    EnsureIpcSupport();
+    helper_.StartChildWithExtraSwitch("MojoPerfTestClient", kPerftestToken,
+                                      token_);
+    return true;
   }
+
+  bool WaitForClientShutdown() override {
+    return helper_.WaitForChildTestShutdown();
+  }
+
+  void EnsureIpcSupport() {
+    base::AutoLock l(ipc_support_lock_);
+    if (!ipc_support_) {
+      ipc_support_.reset(
+          new mojo::edk::test::ScopedIPCSupport(io_task_runner()));
+    }
+  }
+
+  mojo::edk::test::MultiprocessTestHelper helper_;
+  std::string token_;
+  base::Lock ipc_support_lock_;
+  scoped_ptr<mojo::edk::test::ScopedIPCSupport> ipc_support_;
 };
 
-MojoChannelPerfTest::MojoChannelPerfTest() {
-  g_mojo_initializer.Get();
-}
-
-
 TEST_F(MojoChannelPerfTest, ChannelPingPong) {
   RunTestChannelPingPong(GetDefaultTestParams());
 
@@ -80,28 +91,33 @@
   }
 }
 
-class MojoTestClient : public IPC::test::PingPongTestClient {
+class MojoPerfTestClient : public test::PingPongTestClient {
  public:
-  typedef IPC::test::PingPongTestClient SuperType;
+  typedef test::PingPongTestClient SuperType;
 
-  MojoTestClient();
+  MojoPerfTestClient();
 
-  scoped_ptr<IPC::Channel> CreateChannel(IPC::Listener* listener) override;
+  scoped_ptr<Channel> CreateChannel(Listener* listener) override;
+
+ private:
+  mojo::edk::test::ScopedIPCSupport ipc_support_;
 };
 
-MojoTestClient::MojoTestClient() {
-  g_mojo_initializer.Get();
+MojoPerfTestClient::MojoPerfTestClient()
+    : ipc_support_(base::ThreadTaskRunnerHandle::Get()) {
+  mojo::edk::test::MultiprocessTestHelper::ChildSetup();
 }
 
-scoped_ptr<IPC::Channel> MojoTestClient::CreateChannel(
-    IPC::Listener* listener) {
-  return scoped_ptr<IPC::Channel>(IPC::ChannelMojo::Create(
-      task_runner(), IPCTestBase::GetChannelName("PerformanceClient"),
-      IPC::Channel::MODE_CLIENT, listener));
+scoped_ptr<Channel> MojoPerfTestClient::CreateChannel(Listener* listener) {
+  return scoped_ptr<Channel>(ChannelMojo::Create(
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          kPerftestToken),
+      Channel::MODE_CLIENT, listener));
 }
 
-MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) {
-  MojoTestClient client;
+MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {
+  MojoPerfTestClient client;
+
   int rv = client.RunMain();
 
   base::RunLoop run_loop;
@@ -111,3 +127,4 @@
 }
 
 }  // namespace
+}  // namespace IPC
diff --git a/ipc/mojo/run_all_perftests.cc b/ipc/mojo/run_all_perftests.cc
new file mode 100644
index 0000000..a942b8b5
--- /dev/null
+++ b/ipc/mojo/run_all_perftests.cc
@@ -0,0 +1,17 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Copied from mojo/edk/test/run_all_perftests.cc.
+
+#include "base/command_line.h"
+#include "base/test/perf_test_suite.h"
+#include "mojo/edk/embedder/embedder.h"
+
+int main(int argc, char** argv) {
+  base::PerfTestSuite test(argc, argv);
+
+  mojo::edk::Init();
+
+  return test.Run();
+}
diff --git a/ipc/mojo/run_all_unittests.cc b/ipc/mojo/run_all_unittests.cc
index f0b5dbc..4416932 100644
--- a/ipc/mojo/run_all_unittests.cc
+++ b/ipc/mojo/run_all_unittests.cc
@@ -5,9 +5,11 @@
 #include "base/at_exit.h"
 #include "base/bind.h"
 #include "base/test/launcher/unit_test_launcher.h"
+#include "base/test/test_io_thread.h"
 #include "base/test/test_suite.h"
 #include "build/build_config.h"
 #include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/test/scoped_ipc_support.h"
 
 #if defined(OS_ANDROID)
 #include "base/android/jni_android.h"
@@ -21,6 +23,11 @@
 #endif
   base::TestSuite test_suite(argc, argv);
   mojo::edk::Init();
+  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
+  // Leak this because its destructor calls mojo::edk::ShutdownIPCSupport which
+  // really does nothing in the new EDK but does depend on the current message
+  // loop, which is destructed inside base::LaunchUnitTests.
+  new mojo::edk::test::ScopedIPCSupport(test_io_thread.task_runner());
   return base::LaunchUnitTestsSerially(
       argc, argv,
       base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
diff --git a/ipc/unix_domain_socket_util.cc b/ipc/unix_domain_socket_util.cc
index 6e06fe7..c69c5d8 100644
--- a/ipc/unix_domain_socket_util.cc
+++ b/ipc/unix_domain_socket_util.cc
@@ -82,15 +82,6 @@
                                   int* server_listen_fd) {
   DCHECK(server_listen_fd);
 
-  const std::string socket_name = socket_path.value();
-  struct sockaddr_un unix_addr;
-  size_t unix_addr_len;
-  if (!MakeUnixAddrForPath(socket_name, &unix_addr, &unix_addr_len))
-    return false;
-  base::ScopedFD fd(CreateUnixDomainSocket());
-  if (!fd.is_valid())
-    return false;
-
   // Make sure the path we need exists.
   base::FilePath socket_dir = socket_path.DirName();
   if (!base::CreateDirectory(socket_dir)) {
@@ -98,12 +89,23 @@
     return false;
   }
 
+  const std::string socket_name = socket_path.value();
+
   // Delete any old FS instances.
   if (unlink(socket_name.c_str()) < 0 && errno != ENOENT) {
     PLOG(ERROR) << "unlink " << socket_name;
     return false;
   }
 
+  struct sockaddr_un unix_addr;
+  size_t unix_addr_len;
+  if (!MakeUnixAddrForPath(socket_name, &unix_addr, &unix_addr_len))
+    return false;
+
+  base::ScopedFD fd(CreateUnixDomainSocket());
+  if (!fd.is_valid())
+    return false;
+
   // Bind the socket.
   if (bind(fd.get(), reinterpret_cast<const sockaddr*>(&unix_addr),
            unix_addr_len) < 0) {
@@ -130,6 +132,7 @@
   size_t unix_addr_len;
   if (!MakeUnixAddrForPath(socket_path.value(), &unix_addr, &unix_addr_len))
     return false;
+
   base::ScopedFD fd(CreateUnixDomainSocket());
   if (!fd.is_valid())
     return false;
@@ -189,6 +192,7 @@
   base::ScopedFD accept_fd(HANDLE_EINTR(accept(server_listen_fd, NULL, 0)));
   if (!accept_fd.is_valid())
     return IsRecoverableError();
+
   if (!base::SetNonBlocking(accept_fd.get())) {
     PLOG(ERROR) << "base::SetNonBlocking() failed " << accept_fd.get();
     // It's safe to keep listening on |server_listen_fd| even if the attempt to
diff --git a/mash/wm/frame/default_header_painter.cc b/mash/wm/frame/default_header_painter.cc
index ed2a66d1..dfc1ed1 100644
--- a/mash/wm/frame/default_header_painter.cc
+++ b/mash/wm/frame/default_header_painter.cc
@@ -40,8 +40,6 @@
 const SkColor kDefaultFrameColor = SkColorSetRGB(242, 242, 242);
 // Duration of crossfade animation for activating and deactivating frame.
 const int kActivationCrossfadeDurationMs = 200;
-// Luminance below which to use white caption buttons.
-const int kMaxLuminanceForLightButtons = 125;
 
 // Tiles an image into an area, rounding the top corners.
 void TileRoundRect(gfx::Canvas* canvas,
@@ -269,9 +267,8 @@
 }
 
 bool DefaultHeaderPainter::ShouldUseLightImages() {
-  int luminance = color_utils::GetLuminanceForColor(
+  return color_utils::IsDark(
       mode_ == MODE_INACTIVE ? inactive_frame_color_ : active_frame_color_);
-  return luminance < kMaxLuminanceForLightButtons;
 }
 
 void DefaultHeaderPainter::UpdateAllButtonImages() {
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 8be32f4..da4e210 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -385,6 +385,8 @@
 
     case kSuspended:
       renderer_.reset();
+      statistics_.audio_memory_usage = 0;
+      statistics_.video_memory_usage = 0;
       base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
       return;
 
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
index def4963..6df2463 100644
--- a/media/base/pipeline_impl_unittest.cc
+++ b/media/base/pipeline_impl_unittest.cc
@@ -175,7 +175,8 @@
   // Sets up expectations to allow the video renderer to initialize.
   void SetRendererExpectations() {
     EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
-        .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_),
+        .WillOnce(DoAll(SaveArg<2>(&statistics_cb_),
+                        SaveArg<3>(&buffering_state_cb_),
                         SaveArg<4>(&ended_cb_), PostCallback<1>(PIPELINE_OK)));
     EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream()));
     EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream()));
@@ -371,6 +372,7 @@
   scoped_ptr<FakeTextTrackStream> text_stream_;
   BufferingStateCB buffering_state_cb_;
   base::Closure ended_cb_;
+  StatisticsCB statistics_cb_;
   VideoDecoderConfig video_decoder_config_;
   PipelineMetadata metadata_;
   base::TimeDelta start_time_;
@@ -612,9 +614,22 @@
 
   StartPipelineAndExpect(PIPELINE_OK);
 
+  // Inject some fake memory usage to verify its cleared after suspend.
+  PipelineStatistics stats;
+  stats.audio_memory_usage = 12345;
+  stats.video_memory_usage = 67890;
+  statistics_cb_.Run(stats);
+  EXPECT_EQ(stats.audio_memory_usage,
+            pipeline_->GetStatistics().audio_memory_usage);
+  EXPECT_EQ(stats.video_memory_usage,
+            pipeline_->GetStatistics().video_memory_usage);
+
   ExpectSuspend();
   DoSuspend();
 
+  EXPECT_EQ(pipeline_->GetStatistics().audio_memory_usage, 0);
+  EXPECT_EQ(pipeline_->GetStatistics().video_memory_usage, 0);
+
   base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
   ExpectResume(expected);
   DoResume(expected);
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 2185d931..3d466526 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -57,7 +57,6 @@
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
 using blink::WebCanvas;
@@ -790,12 +789,6 @@
     const std::vector<uint8_t>& init_data) {
   DCHECK(init_data_type != EmeInitDataType::UNKNOWN);
 
-  // Do not fire the "encrypted" event if Encrypted Media is not enabled.
-  // EME may not be enabled on Android Jelly Bean.
-  if (!blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
-    return;
-  }
-
   // TODO(xhwang): Update this UMA name. https://crbug.com/589251
   UMA_HISTOGRAM_COUNTS("Media.EME.NeedKey", 1);
 
@@ -867,6 +860,8 @@
 
   if (delegate_)
     delegate_->PlayerGone(delegate_id_);
+  memory_usage_reporting_timer_.Stop();
+  ReportMemoryUsage();
 
   if (pending_suspend_resume_cycle_) {
     pending_suspend_resume_cycle_ = false;
@@ -1422,6 +1417,9 @@
       (data_source_ ? data_source_->GetMemoryUsage() : 0) +
       demuxer_memory_usage;
 
+  // Note, this isn't entirely accurate, there may be VideoFrames held by the
+  // compositor or other resources that we're unaware of.
+
   DVLOG(2) << "Memory Usage -- Audio: " << stats.audio_memory_usage
            << ", Video: " << stats.video_memory_usage << ", DataSource: "
            << (data_source_ ? data_source_->GetMemoryUsage() : 0)
diff --git a/media/filters/android/media_codec_audio_decoder.cc b/media/filters/android/media_codec_audio_decoder.cc
index aa559cf..8d4a421 100644
--- a/media/filters/android/media_codec_audio_decoder.cc
+++ b/media/filters/android/media_codec_audio_decoder.cc
@@ -11,7 +11,9 @@
 #include "base/thread_task_runner_handle.h"
 #include "media/base/android/sdk_media_codec_bridge.h"
 #include "media/base/audio_buffer.h"
+#include "media/base/audio_timestamp_helper.h"
 #include "media/base/bind_to_current_loop.h"
+#include "media/base/timestamp_constants.h"
 
 namespace media {
 
@@ -116,6 +118,8 @@
   }
 
   config_ = config;
+  timestamp_helper_.reset(
+      new AudioTimestampHelper(config_.samples_per_second()));
   output_cb_ = BindToCurrentLoop(output_cb);
 
   SetState(STATE_READY);
@@ -126,8 +130,15 @@
                                     const DecodeCB& decode_cb) {
   DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb);
 
+  if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp()) {
+    DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString()
+             << ": no timestamp, skipping this buffer";
+    bound_decode_cb.Run(kDecodeError);
+    return;
+  }
+
   if (state_ == STATE_ERROR) {
-    // We get here if an error happens in DecodeOutput() or Reset().
+    // We get here if an error happens in DequeueOutput() or Reset().
     DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString()
              << ": Error state, returning decode error for all buffers";
     ClearInputQueue(kDecodeError);
@@ -171,6 +182,9 @@
     success = !!media_codec_;
   }
 
+  // Reset AudioTimestampHelper.
+  timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
+
   SetState(success ? STATE_READY : STATE_ERROR);
 
   task_runner_->PostTask(FROM_HERE, closure);
@@ -204,6 +218,16 @@
 bool MediaCodecAudioDecoder::QueueInput() {
   DVLOG(2) << __FUNCTION__;
 
+  bool did_work = false;
+  while (QueueOneInputBuffer())
+    did_work = true;
+
+  return did_work;
+}
+
+bool MediaCodecAudioDecoder::QueueOneInputBuffer() {
+  DVLOG(2) << __FUNCTION__;
+
   if (input_queue_.empty())
     return false;
 
@@ -277,6 +301,7 @@
       media_codec_->DequeueInputBuffer(NoWaitTimeout(), &input_buf_index);
   switch (status) {
     case media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER:
+      DVLOG(2) << __FUNCTION__ << ": MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER";
       break;
 
     case media::MEDIA_CODEC_ERROR:
@@ -501,8 +526,17 @@
       kSampleFormatS16, config_.channel_layout(), channel_count,
       config_.samples_per_second(), frame_count);
 
-  // Set timestamp.
-  audio_buffer->set_timestamp(out.pts);
+  // Calculate and set buffer timestamp.
+
+  const bool first_buffer =
+      timestamp_helper_->base_timestamp() == kNoTimestamp();
+  if (first_buffer) {
+    // Clamp the base timestamp to zero.
+    timestamp_helper_->SetBaseTimestamp(std::max(base::TimeDelta(), out.pts));
+  }
+
+  audio_buffer->set_timestamp(timestamp_helper_->GetTimestamp());
+  timestamp_helper_->AddFrames(frame_count);
 
   // Copy data into AudioBuffer.
   CHECK_LE(out.size, audio_buffer->data_size());
diff --git a/media/filters/android/media_codec_audio_decoder.h b/media/filters/android/media_codec_audio_decoder.h
index 39aca8c..d306a21d 100644
--- a/media/filters/android/media_codec_audio_decoder.h
+++ b/media/filters/android/media_codec_audio_decoder.h
@@ -15,12 +15,7 @@
 #include "media/base/android/media_codec_bridge.h"
 #include "media/base/audio_decoder.h"
 #include "media/base/audio_decoder_config.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace media {
+#include "media/base/media_export.h"
 
 // MediaCodecAudioDecoder is based on Android's MediaCodec API.
 // The MediaCodec API is required to play encrypted (as in EME) content on
@@ -97,7 +92,15 @@
 //                 |                          |             |
 //              [Error]                    [Ready]       [Error]
 
-class MediaCodecAudioDecoder : public AudioDecoder {
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace media {
+
+class AudioTimestampHelper;
+
+class MEDIA_EXPORT MediaCodecAudioDecoder : public AudioDecoder {
  public:
   explicit MediaCodecAudioDecoder(
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
@@ -150,10 +153,15 @@
   // dequeues output buffers.
   void DoIOTask();
 
-  // Enqueues one pending input buffer into MediaCodec if MediaCodec has room.
+  // Enqueues pending input buffers into MediaCodec as long as it can happen
+  // without delay in dequeuing and enqueueing input buffers.
   // Returns true if any input was processed.
   bool QueueInput();
 
+  // Enqueues one pending input buffer into MediaCodec if MediaCodec has room.
+  // Returns true if any input was processed.
+  bool QueueOneInputBuffer();
+
   // A helper method for QueueInput(). Dequeues an empty input buffer from the
   // codec and returns the information about it. OutputBufferInfo.buf_index is
   // the index of the dequeued buffer or -1 if the codec is busy or an error
@@ -222,6 +230,8 @@
 
   scoped_ptr<MediaCodecBridge> media_codec_;
 
+  scoped_ptr<AudioTimestampHelper> timestamp_helper_;
+
   // Repeating timer that kicks MediaCodec operation.
   base::RepeatingTimer io_timer_;
 
diff --git a/media/filters/audio_decoder_unittest.cc b/media/filters/audio_decoder_unittest.cc
index 5f3e96d..c4f727b 100644
--- a/media/filters/audio_decoder_unittest.cc
+++ b/media/filters/audio_decoder_unittest.cc
@@ -5,7 +5,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <deque>
 #include <vector>
 
 #include "base/bind.h"
@@ -16,6 +15,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/sys_byteorder.h"
+#include "base/threading/platform_thread.h"
 #include "build/build_config.h"
 #include "media/base/audio_buffer.h"
 #include "media/base/audio_bus.h"
@@ -32,6 +32,32 @@
 #include "media/filters/opus_audio_decoder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+#include "media/base/android/media_codec_util.h"
+#include "media/filters/android/media_codec_audio_decoder.h"
+
+// Helper macro to skip the test if MediaCodec is not available.
+#define SKIP_TEST_IF_NO_MEDIA_CODEC()                                \
+  do {                                                               \
+    if (GetParam().decoder_type == MEDIA_CODEC) {                    \
+      if (!MediaCodecUtil::IsMediaCodecAvailable()) {                \
+        VLOG(0) << "Could not run test - no MediaCodec on device.";  \
+        return;                                                      \
+      }                                                              \
+      if (GetParam().codec == kCodecOpus &&                          \
+          base::android::BuildInfo::GetInstance()->sdk_int() < 21) { \
+        VLOG(0) << "Could not run test - Opus is not supported";     \
+        return;                                                      \
+      }                                                              \
+    }                                                                \
+  } while (0)
+#else
+#define SKIP_TEST_IF_NO_MEDIA_CODEC() \
+  do {                                \
+  } while (0)
+#endif  // !defined(OS_ANDROID)
+
 namespace media {
 
 // The number of packets to read and then decode from each file.
@@ -44,6 +70,9 @@
 enum AudioDecoderType {
   FFMPEG,
   OPUS,
+#if defined(OS_ANDROID)
+  MEDIA_CODEC,
+#endif
 };
 
 struct DecodedBufferExpectations {
@@ -113,6 +142,11 @@
         decoder_.reset(
             new OpusAudioDecoder(message_loop_.task_runner()));
         break;
+#if defined(OS_ANDROID)
+      case MEDIA_CODEC:
+        decoder_.reset(new MediaCodecAudioDecoder(message_loop_.task_runner()));
+        break;
+#endif
     }
   }
 
@@ -126,10 +160,12 @@
     ASSERT_FALSE(pending_decode_);
     pending_decode_ = true;
     last_decode_status_ = AudioDecoder::kDecodeError;
+
+    base::RunLoop run_loop;
     decoder_->Decode(
-        buffer,
-        base::Bind(&AudioDecoderTest::DecodeFinished, base::Unretained(this)));
-    base::RunLoop().RunUntilIdle();
+        buffer, base::Bind(&AudioDecoderTest::DecodeFinished,
+                           base::Unretained(this), run_loop.QuitClosure()));
+    run_loop.Run();
     ASSERT_FALSE(pending_decode_);
   }
 
@@ -225,11 +261,13 @@
     decoded_audio_.push_back(buffer);
   }
 
-  void DecodeFinished(AudioDecoder::Status status) {
+  void DecodeFinished(const base::Closure& quit_closure,
+                      AudioDecoder::Status status) {
     EXPECT_TRUE(pending_decode_);
     EXPECT_FALSE(pending_reset_);
     pending_decode_ = false;
     last_decode_status_ = status;
+    quit_closure.Run();
   }
 
   void ResetFinished() {
@@ -321,31 +359,38 @@
 class FFmpegAudioDecoderBehavioralTest : public AudioDecoderTest {};
 
 TEST_P(AudioDecoderTest, Initialize) {
+  SKIP_TEST_IF_NO_MEDIA_CODEC();
   ASSERT_NO_FATAL_FAILURE(Initialize());
 }
 
 // Verifies decode audio as well as the Decode() -> Reset() sequence.
 TEST_P(AudioDecoderTest, ProduceAudioSamples) {
+  SKIP_TEST_IF_NO_MEDIA_CODEC();
   ASSERT_NO_FATAL_FAILURE(Initialize());
 
   // Run the test multiple times with a seek back to the beginning in between.
   std::vector<std::string> decoded_audio_md5_hashes;
   for (int i = 0; i < 2; ++i) {
-    for (size_t j = 0; j < kDecodeRuns; ++j) {
-      do {
-        Decode();
-        ASSERT_EQ(last_decode_status(), AudioDecoder::kOk);
-        // Some codecs have a multiple buffer delay and require an extra
-        // Decode() step to extract the desired number of output buffers.
-      } while (j == 0 && decoded_audio_size() == 0);
+    // Run decoder until we get at least |kDecodeRuns| output buffers.
+    // Keeping Decode() in a loop seems to be the simplest way to guarantee that
+    // the predefined number of output buffers are produced without draining
+    // (i.e. decoding EOS).
+    do {
+      Decode();
+      ASSERT_EQ(last_decode_status(), AudioDecoder::kOk);
+    } while (decoded_audio_size() < kDecodeRuns);
 
-      // On the first pass record the exact MD5 hash for each decoded buffer.
-      if (i == 0)
+    // With MediaCodecAudioDecoder the output buffers might appear after
+    // some delay. Since we keep decoding in a loop, the number of output
+    // buffers when they eventually appear might exceed |kDecodeRuns|.
+    ASSERT_LE(kDecodeRuns, decoded_audio_size());
+
+    // On the first pass record the exact MD5 hash for each decoded buffer.
+    if (i == 0) {
+      for (size_t j = 0; j < kDecodeRuns; ++j)
         decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
     }
 
-    ASSERT_EQ(kDecodeRuns, decoded_audio_size());
-
     // On the first pass verify the basic audio hash and sample info.  On the
     // second, verify the exact MD5 sum for each packet.  It shouldn't change.
     for (size_t j = 0; j < kDecodeRuns; ++j) {
@@ -354,7 +399,6 @@
     }
 
     SendEndOfStream();
-    ASSERT_EQ(kDecodeRuns, decoded_audio_size());
 
     // Seek back to the beginning.  Calls Reset() on the decoder.
     Seek(start_timestamp());
@@ -362,17 +406,20 @@
 }
 
 TEST_P(AudioDecoderTest, Decode) {
+  SKIP_TEST_IF_NO_MEDIA_CODEC();
   ASSERT_NO_FATAL_FAILURE(Initialize());
   Decode();
   EXPECT_EQ(AudioDecoder::kOk, last_decode_status());
 }
 
 TEST_P(AudioDecoderTest, Reset) {
+  SKIP_TEST_IF_NO_MEDIA_CODEC();
   ASSERT_NO_FATAL_FAILURE(Initialize());
   Reset();
 }
 
 TEST_P(AudioDecoderTest, NoTimestamp) {
+  SKIP_TEST_IF_NO_MEDIA_CODEC();
   ASSERT_NO_FATAL_FAILURE(Initialize());
   scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
   buffer->set_timestamp(kNoTimestamp());
@@ -455,8 +502,20 @@
                         OpusAudioDecoderBehavioralTest,
                         testing::ValuesIn(kOpusBehavioralTest));
 
+#if defined(OS_ANDROID)
+
+const DecoderTestData kMediaCodecTests[] = {
+    {MEDIA_CODEC, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
+     CHANNEL_LAYOUT_STEREO},
+};
+
+INSTANTIATE_TEST_CASE_P(MediaCodecAudioDecoderTest,
+                        AudioDecoderTest,
+                        testing::ValuesIn(kMediaCodecTests));
+
+#else  // !defined(OS_ANDROID)
+
 // Disable all FFmpeg decoder tests on Android. http://crbug.com/570762.
-#if !defined(OS_ANDROID)
 
 #if defined(USE_PROPRIETARY_CODECS)
 const DecodedBufferExpectations kSfxMp3Expectations[] = {
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
index 4d2d4b3..7c2b9d2 100644
--- a/mojo/BUILD.gn
+++ b/mojo/BUILD.gn
@@ -37,6 +37,7 @@
     "//mojo/edk/js/test:js_unittests",
     "//mojo/edk/system:mojo_message_pipe_perftests",
     "//mojo/edk/system:mojo_system_unittests",
+    "//mojo/edk/test:mojo_public_bindings_perftests",
     "//mojo/edk/test:mojo_public_bindings_unittests",
     "//mojo/edk/test:mojo_public_environment_unittests",
     "//mojo/edk/test:mojo_public_system_perftests",
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc
index 375d65ba..958e10c4 100644
--- a/mojo/edk/system/channel.cc
+++ b/mojo/edk/system/channel.cc
@@ -57,7 +57,12 @@
   size_ = sizeof(Header) + extra_header_size + payload_size;
   data_ = static_cast<char*>(base::AlignedAlloc(size_,
                                                 kChannelMessageAlignment));
-  memset(data_, 0, size_);
+  // Only zero out the header and not the payload. Since the payload is going to
+  // be memcpy'd, zeroing the payload is unnecessary work and a significant
+  // performance issue when dealing with large messages. Any sanitizer errors
+  // complaining about an uninitialized read in the payload area should be
+  // treated as an error and fixed.
+  memset(data_, 0, sizeof(Header) + extra_header_size);
   header_ = reinterpret_cast<Header*>(data_);
 
   DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc
index 5b2fea82..2fd6484a 100644
--- a/mojo/edk/system/node_controller.cc
+++ b/mojo/edk/system/node_controller.cc
@@ -193,14 +193,20 @@
     }
   }
 
-  scoped_refptr<NodeChannel> parent = GetParentChannel();
-  if (parent) {
-    parent->RequestPortMerge(port.name(), token);
-    return;
+  scoped_refptr<NodeChannel> parent;
+  {
+    // Hold |pending_port_merges_lock_| while getting |parent|. Otherwise,
+    // there is a race where the parent can be set, and |pending_port_merges_|
+    // be processed between retrieving |parent| and adding the merge to
+    // |pending_port_merges_|.
+    base::AutoLock lock(pending_port_merges_lock_);
+    parent = GetParentChannel();
+    if (!parent) {
+      pending_port_merges_.push_back(std::make_pair(token, port));
+      return;
+    }
   }
-
-  base::AutoLock lock(pending_port_merges_lock_);
-  pending_port_merges_.push_back(std::make_pair(token, port));
+  parent->RequestPortMerge(port.name(), token);
 }
 
 scoped_refptr<PlatformSharedBuffer> NodeController::CreateSharedBuffer(
diff --git a/mojo/edk/test/BUILD.gn b/mojo/edk/test/BUILD.gn
index e84b32e..d81ff02 100644
--- a/mojo/edk/test/BUILD.gn
+++ b/mojo/edk/test/BUILD.gn
@@ -99,6 +99,14 @@
   ]
 }
 
+test("mojo_public_bindings_perftests") {
+  deps = [
+    ":run_all_perftests",
+    "//mojo/edk/test:test_support",
+    "//mojo/public/cpp/bindings/tests:perftests",
+  ]
+}
+
 test("mojo_public_bindings_unittests") {
   deps = [
     ":run_all_unittests",
diff --git a/mojo/mojo_edk_tests.gyp b/mojo/mojo_edk_tests.gyp
index 755ee40d..0ace217 100644
--- a/mojo/mojo_edk_tests.gyp
+++ b/mojo/mojo_edk_tests.gyp
@@ -110,7 +110,7 @@
       'dependencies': [
         '../testing/gtest.gyp:gtest',
         'mojo_base.gyp:mojo_common_lib',
-        'mojo_edk.gyp:mojo_run_all_unittests',
+        'mojo_edk.gyp:mojo_run_all_perftests',
         'mojo_public.gyp:mojo_cpp_bindings',
         'mojo_public.gyp:mojo_environment_standalone',
         'mojo_public.gyp:mojo_message_pump_lib',
diff --git a/mojo/public/cpp/bindings/tests/bindings_perftest.cc b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
index 8162f81..93f00cf 100644
--- a/mojo/public/cpp/bindings/tests/bindings_perftest.cc
+++ b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
@@ -6,11 +6,11 @@
 #include <utility>
 
 #include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/test_support/test_support.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -25,7 +25,7 @@
 
 class PingServiceImpl : public test::PingService {
  public:
-  explicit PingServiceImpl() {}
+  PingServiceImpl() {}
   ~PingServiceImpl() override {}
 
   // |PingService| methods:
@@ -52,6 +52,8 @@
   unsigned int iterations_to_run_;
   unsigned int current_iterations_;
 
+  base::Closure quit_closure_;
+
   DISALLOW_COPY_AND_ASSIGN(PingPongTest);
 };
 
@@ -62,14 +64,16 @@
   iterations_to_run_ = iterations;
   current_iterations_ = 0;
 
+  base::RunLoop run_loop;
+  quit_closure_ = run_loop.QuitClosure();
   service_->Ping([this]() { OnPingDone(); });
-  RunLoop::current()->Run();
+  run_loop.Run();
 }
 
 void PingPongTest::OnPingDone() {
   current_iterations_++;
   if (current_iterations_ >= iterations_to_run_) {
-    RunLoop::current()->Quit();
+    quit_closure_.Run();
     return;
   }
 
diff --git a/mojo/shell/public/cpp/application_test_base.h b/mojo/shell/public/cpp/application_test_base.h
index 958c779..4358c6fd 100644
--- a/mojo/shell/public/cpp/application_test_base.h
+++ b/mojo/shell/public/cpp/application_test_base.h
@@ -70,7 +70,7 @@
   }
   uint32_t test_instance_id() const {
     return test_helper_ ? test_helper_->test_instance_id() :
-        shell::mojom::Connector::kInvalidApplicationID;
+        shell::mojom::kInvalidInstanceID;
   }
 
   // Get the ShellClient for the application to be tested.
diff --git a/mojo/shell/public/cpp/connection.h b/mojo/shell/public/cpp/connection.h
index 066d1a18..ce1401c8 100644
--- a/mojo/shell/public/cpp/connection.h
+++ b/mojo/shell/public/cpp/connection.h
@@ -40,6 +40,19 @@
  public:
   virtual ~Connection() {}
 
+  enum class State {
+    // The shell has not yet processed the connection.
+    PENDING,
+
+    // The shell processed the connection and it was established. GetResult()
+    // returns mojom::shell::ConnectionResult::SUCCESS.
+    CONNECTED,
+
+    // The shell processed the connection and establishment was prevented by
+    // an error, call GetResult().
+    DISCONNECTED
+  };
+
   class TestApi {
    public:
     explicit TestApi(Connection* connection) : connection_(connection) {}
@@ -88,22 +101,21 @@
   // remote application's InterfaceProvider.
   virtual void SetConnectionLostClosure(const Closure& handler) = 0;
 
-  // Returns true if |result| has been modified to include the result of the
-  // connection (see mojo/shell/public/interfaces/connector.mojom for error
-  // codes), false if the connection is still pending and |result| has not been
-  // modified. Call AddConnectionCompletedClosure() to schedule a closure to be
-  // run when the connection is completed and the result is available.
-  virtual bool GetConnectionResult(
-      shell::mojom::ConnectResult* result) const = 0;
+  // Returns the result of the connection. This function should only be called
+  // when the connection state is not pending. Call
+  // AddConnectionCompletedClosure() to schedule a closure to be run when the
+  // connection is processed by the shell.
+  virtual shell::mojom::ConnectResult GetResult() const = 0;
 
-  // Returns true if |remote_id| has been modified to include the instance id of
-  // the remote application. For connections created via Connector::Connect(),
-  // this will not be determined until the connection has been completed by the
-  // shell. Use AddConnectionCompletedClosure() to schedule a closure to be run
-  // when the connection is completed and the remote id is available. Returns
-  // false if the connection has not yet been completed and |remote_id| is not
-  // modified.
-  virtual bool GetRemoteApplicationID(uint32_t* remote_id) const = 0;
+  // Returns true if the connection has not yet been processed by the shell.
+  virtual bool IsPending() const = 0;
+
+  // Returns the instance id of the remote application if it is known at the
+  // time this function is called. When IsPending() returns true, this function
+  // will return shell::mojom::kInvalidInstanceID. Use
+  // AddConnectionCompletedClosure() to schedule a closure to be run when the
+  // connection is processed by the shell and remote id is available.
+  virtual uint32_t GetRemoteInstanceID() const = 0;
 
   // Register a closure to be run when the connection has been completed by the
   // shell and remote metadata is available. Useful only for connections created
diff --git a/mojo/shell/public/cpp/lib/application_test_base.cc b/mojo/shell/public/cpp/lib/application_test_base.cc
index 9e5b99c..7f8f684 100644
--- a/mojo/shell/public/cpp/lib/application_test_base.cc
+++ b/mojo/shell/public/cpp/lib/application_test_base.cc
@@ -20,7 +20,7 @@
 namespace {
 // Share the application name with multiple application tests.
 String g_name;
-uint32_t g_id = shell::mojom::Connector::kInvalidApplicationID;
+uint32_t g_id = shell::mojom::kInvalidInstanceID;
 String g_user_id = shell::mojom::kRootUserID;
 
 // ShellClient request handle passed from the shell in MojoMain, stored in
diff --git a/mojo/shell/public/cpp/lib/connection_impl.cc b/mojo/shell/public/cpp/lib/connection_impl.cc
index e5fd42f..3541f55 100644
--- a/mojo/shell/public/cpp/lib/connection_impl.cc
+++ b/mojo/shell/public/cpp/lib/connection_impl.cc
@@ -26,12 +26,12 @@
     const std::string& remote_user_id,
     shell::mojom::InterfaceProviderPtr remote_interfaces,
     shell::mojom::InterfaceProviderRequest local_interfaces,
-    const std::set<std::string>& allowed_interfaces)
+    const std::set<std::string>& allowed_interfaces,
+    State initial_state)
     : connection_name_(connection_name),
       remote_name_(remote_name),
+      state_(initial_state),
       remote_id_(remote_id),
-      connection_completed_(
-          remote_id != shell::mojom::Connector::kInvalidApplicationID),
       remote_user_id_(remote_user_id),
       local_registry_(std::move(local_interfaces), this),
       remote_interfaces_(std::move(remote_interfaces)),
@@ -71,29 +71,23 @@
   remote_interfaces_.set_connection_error_handler(handler);
 }
 
-bool ConnectionImpl::GetConnectionResult(
-    shell::mojom::ConnectResult* result) const {
-  if (!connection_completed_)
-    return false;
-  *result = result_;
-  return true;
+shell::mojom::ConnectResult ConnectionImpl::GetResult() const {
+  return result_;
 }
 
+bool ConnectionImpl::IsPending() const {
+  return state_ == State::PENDING;
+}
 
-bool ConnectionImpl::GetRemoteApplicationID(uint32_t* remote_id) const {
-  if (!connection_completed_)
-    return false;
-
-  *remote_id = remote_id_;
-  return true;
+uint32_t ConnectionImpl::GetRemoteInstanceID() const {
+  return remote_id_;
 }
 
 void ConnectionImpl::AddConnectionCompletedClosure(const Closure& callback) {
-  if (connection_completed_) {
+  if (IsPending())
+    connection_completed_callbacks_.push_back(callback);
+  else
     callback.Run();
-    return;
-  }
-  connection_completed_callbacks_.push_back(callback);
 }
 
 bool ConnectionImpl::AllowsInterface(const std::string& interface_name) const {
@@ -118,10 +112,11 @@
 void ConnectionImpl::OnConnectionCompleted(shell::mojom::ConnectResult result,
                                            const std::string& target_user_id,
                                            uint32_t target_application_id) {
-  DCHECK(!connection_completed_);
-  connection_completed_ = true;
+  DCHECK(State::PENDING == state_);
 
   result_ = result;
+  state_ = result_ == shell::mojom::ConnectResult::SUCCEEDED ?
+      State::CONNECTED : State::DISCONNECTED;
   remote_id_ = target_application_id;
   remote_user_id_= target_user_id;
   std::vector<Closure> callbacks;
diff --git a/mojo/shell/public/cpp/lib/connection_impl.h b/mojo/shell/public/cpp/lib/connection_impl.h
index c8e66d77..e0a03d4d 100644
--- a/mojo/shell/public/cpp/lib/connection_impl.h
+++ b/mojo/shell/public/cpp/lib/connection_impl.h
@@ -33,7 +33,8 @@
                  const std::string& remote_user_id,
                  shell::mojom::InterfaceProviderPtr remote_interfaces,
                  shell::mojom::InterfaceProviderRequest local_interfaces,
-                 const std::set<std::string>& allowed_interfaces);
+                 const std::set<std::string>& allowed_interfaces,
+                 State initial_state);
   ~ConnectionImpl() override;
 
   shell::mojom::Connector::ConnectCallback GetConnectCallback();
@@ -44,8 +45,9 @@
   const std::string& GetRemoteApplicationName() override;
   const std::string& GetRemoteUserID() const override;
   void SetConnectionLostClosure(const Closure& handler) override;
-  bool GetConnectionResult(shell::mojom::ConnectResult* result) const override;
-  bool GetRemoteApplicationID(uint32_t* remote_id) const override;
+  shell::mojom::ConnectResult GetResult() const override;
+  bool IsPending() const override;
+  uint32_t GetRemoteInstanceID() const override;
   void AddConnectionCompletedClosure(const Closure& callback) override;
   bool AllowsInterface(const std::string& interface_name) const override;
   shell::mojom::InterfaceProvider* GetRemoteInterfaces() override;
@@ -59,9 +61,9 @@
   const std::string connection_name_;
   const std::string remote_name_;
 
-  shell::mojom::ConnectResult result_ = shell::mojom::ConnectResult::OK;
-  uint32_t remote_id_ = shell::mojom::Connector::kInvalidApplicationID;
-  bool connection_completed_ = false;
+  State state_;
+  shell::mojom::ConnectResult result_ = shell::mojom::ConnectResult::SUCCEEDED;
+  uint32_t remote_id_ = shell::mojom::kInvalidInstanceID;
   std::vector<Closure> connection_completed_callbacks_;
   std::string remote_user_id_ = shell::mojom::kInheritUserID;
 
diff --git a/mojo/shell/public/cpp/lib/connector_impl.cc b/mojo/shell/public/cpp/lib/connector_impl.cc
index d6d0e51..9adeebd 100644
--- a/mojo/shell/public/cpp/lib/connector_impl.cc
+++ b/mojo/shell/public/cpp/lib/connector_impl.cc
@@ -58,9 +58,9 @@
   shell::mojom::InterfaceProviderRequest remote_request =
       GetProxy(&remote_interfaces);
   scoped_ptr<internal::ConnectionImpl> registry(new internal::ConnectionImpl(
-      application_name, application_name,
-      shell::mojom::Connector::kInvalidApplicationID, params->user_id(),
-      std::move(remote_interfaces), std::move(local_request), allowed));
+      application_name, application_name, shell::mojom::kInvalidInstanceID,
+      params->user_id(), std::move(remote_interfaces), std::move(local_request),
+      allowed, Connection::State::PENDING));
   connector_->Connect(application_name,
                       params->user_id(),
                       std::move(remote_request),
diff --git a/mojo/shell/public/cpp/lib/shell_connection.cc b/mojo/shell/public/cpp/lib/shell_connection.cc
index c8d206db..0abac7e 100644
--- a/mojo/shell/public/cpp/lib/shell_connection.cc
+++ b/mojo/shell/public/cpp/lib/shell_connection.cc
@@ -56,7 +56,8 @@
   scoped_ptr<Connection> registry(new internal::ConnectionImpl(
       name, requestor_name, requestor_id, requestor_user_id,
       std::move(remote_interfaces), std::move(local_interfaces),
-      allowed_interfaces.To<std::set<std::string>>()));
+      allowed_interfaces.To<std::set<std::string>>(),
+      Connection::State::CONNECTED));
   if (!client_->AcceptConnection(registry.get()))
     return;
 
diff --git a/mojo/shell/public/cpp/shell_test.h b/mojo/shell/public/cpp/shell_test.h
index a839397..aec85a9 100644
--- a/mojo/shell/public/cpp/shell_test.h
+++ b/mojo/shell/public/cpp/shell_test.h
@@ -97,8 +97,7 @@
   Connector* connector_ = nullptr;
   std::string initialize_name_;
   std::string initialize_userid_ = shell::mojom::kInheritUserID;
-  uint32_t initialize_instance_id_ =
-      shell::mojom::Connector::kInvalidApplicationID;
+  uint32_t initialize_instance_id_ = shell::mojom::kInvalidInstanceID;
 
   DISALLOW_COPY_AND_ASSIGN(ShellTest);
 };
diff --git a/mojo/shell/public/interfaces/connector.mojom b/mojo/shell/public/interfaces/connector.mojom
index 94ffa6b2..524047c 100644
--- a/mojo/shell/public/interfaces/connector.mojom
+++ b/mojo/shell/public/interfaces/connector.mojom
@@ -9,9 +9,11 @@
 const string kRootUserID = "505C0EE9-3013-43C0-82B0-A84F50CF8D84";
 const string kInheritUserID = "D26290E4-4485-4EAE-81A2-66D1EEB40A9D";
 
+const uint32 kInvalidInstanceID = 0;
+
 enum ConnectResult {
   // The connection was established successfully.
-  OK,
+  SUCCEEDED,
 
   // The name or user id supplied was malformed, or the application specified
   // by |name| could not be loaded.
@@ -21,13 +23,11 @@
   // forbidden from this app by the CapabilityFilter, or the application
   // attempted to connect using a user id other than its own,
   // kInheritUserID or kRootUserID.
-  PERMISSION_DENIED
+  ACCESS_DENIED
 };
 
 // Encapsulates establishing connections with other Mojo applications.
 interface Connector {
-  const uint32 kInvalidApplicationID = 0;
-
   // Requests a connection with another application. The application originating
   // the request is referred to as the "source" and the one receiving the
   // "target".
diff --git a/mojo/shell/shell.cc b/mojo/shell/shell.cc
index c6e0a43..17e912b6 100644
--- a/mojo/shell/shell.cc
+++ b/mojo/shell/shell.cc
@@ -66,7 +66,7 @@
         shell_->GetLoaderForName(identity_.name())) {
       pid_ = base::Process::Current().Pid();
     }
-    DCHECK_NE(kInvalidApplicationID, id_);
+    DCHECK_NE(mojom::kInvalidInstanceID, id_);
   }
 
   ~Instance() override {}
@@ -80,7 +80,7 @@
   }
 
   void ConnectToClient(scoped_ptr<ConnectParams> params) {
-    params->connect_callback().Run(mojom::ConnectResult::OK,
+    params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED,
                                    identity_.user_id(), id_);
     AllowedInterfaces interfaces;
     interfaces.insert("*");
@@ -88,7 +88,7 @@
       interfaces = GetAllowedInterfaces(params->source().filter(), identity_);
 
     Instance* source = shell_->GetExistingInstance(params->source());
-    uint32_t source_id = source ? source->id() : kInvalidApplicationID;
+    uint32_t source_id = source ? source->id() : mojom::kInvalidInstanceID;
     shell_client_->AcceptConnection(
         params->source().name(), params->source().user_id(), source_id,
         params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(),
@@ -139,13 +139,13 @@
     if (!IsValidName(app_name)) {
       LOG(ERROR) << "Error: invalid Name: " << app_name;
       callback.Run(mojom::ConnectResult::INVALID_ARGUMENT,
-                   mojom::kInheritUserID, kInvalidApplicationID);
+                   mojom::kInheritUserID, mojom::kInvalidInstanceID);
       return;
     }
     if (!base::IsValidGUID(user_id)) {
       LOG(ERROR) << "Error: invalid user_id: " << user_id;
       callback.Run(mojom::ConnectResult::INVALID_ARGUMENT,
-                   mojom::kInheritUserID, kInvalidApplicationID);
+                   mojom::kInheritUserID, mojom::kInvalidInstanceID);
       return;
     }
     // TODO(beng): perform checking on policy of whether this instance is
@@ -162,8 +162,8 @@
     } else {
       LOG(WARNING) << "CapabilityFilter prevented connection from: " <<
           identity_.name() << " to: " << app_name;
-      callback.Run(mojom::ConnectResult::PERMISSION_DENIED,
-                   mojom::kInheritUserID, kInvalidApplicationID);
+      callback.Run(mojom::ConnectResult::ACCESS_DENIED,
+                   mojom::kInheritUserID, mojom::kInvalidInstanceID);
     }
   }
   void Clone(mojom::ConnectorRequest request) override {
@@ -207,7 +207,7 @@
     instance->pid_receiver_binding_.Bind(std::move(pid_receiver));
     instance->factory_ = std::move(factory);
     instance->factory_->CreateShellClient(std::move(request), name);
-    callback.Run(mojom::ConnectResult::OK);
+    callback.Run(mojom::ConnectResult::SUCCEEDED);
   }
   void AddInstanceListener(mojom::InstanceListenerPtr listener) override {
     // TODO(beng): this should only track the instances matching this user, and
@@ -216,9 +216,9 @@
   }
 
   uint32_t GenerateUniqueID() const {
-    static uint32_t id = kInvalidApplicationID;
+    static uint32_t id = mojom::kInvalidInstanceID;
     ++id;
-    CHECK_NE(kInvalidApplicationID, id);
+    CHECK_NE(mojom::kInvalidInstanceID, id);
     return id;
   }
 
@@ -340,11 +340,9 @@
   // is brokered by a policy specific to each caller, managed by the caller's
   // instance. Here we look to see who's calling, and forward to the caller's
   // instance to continue.
-  uint32_t caller_instance_id = mojom::Connector::kInvalidApplicationID;
-  CHECK(connection->GetRemoteApplicationID(&caller_instance_id));
   Instance* instance = nullptr;
   for (const auto& entry : identity_to_instance_) {
-    if (entry.second->id() == caller_instance_id) {
+    if (entry.second->id() == connection->GetRemoteInstanceID()) {
       instance = entry.second;
       break;
     }
diff --git a/mojo/shell/tests/connect/connect_test_app.cc b/mojo/shell/tests/connect/connect_test_app.cc
index 2853c90..b469d165 100644
--- a/mojo/shell/tests/connect/connect_test_app.cc
+++ b/mojo/shell/tests/connect/connect_test_app.cc
@@ -51,8 +51,7 @@
     connection->AddInterface<test::mojom::StandaloneApp>(this);
     connection->AddInterface<test::mojom::BlockedInterface>(this);
 
-    uint32_t remote_id = mojom::Connector::kInvalidApplicationID;
-    connection->GetRemoteApplicationID(&remote_id);
+    uint32_t remote_id = connection->GetRemoteInstanceID();
     test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New());
     state->connection_local_name = connection->GetConnectionName();
     state->connection_remote_name = connection->GetRemoteApplicationName();
@@ -146,7 +145,7 @@
 
   Connector* connector_ = nullptr;
   std::string name_;
-  uint32_t id_ = mojom::Connector::kInvalidApplicationID;
+  uint32_t id_ = shell::mojom::kInvalidInstanceID;
   std::string userid_ = mojom::kRootUserID;
   BindingSet<test::mojom::ConnectTestService> bindings_;
   BindingSet<test::mojom::StandaloneApp> standalone_bindings_;
diff --git a/mojo/shell/tests/connect/connect_test_package.cc b/mojo/shell/tests/connect/connect_test_package.cc
index e672824..e927335 100644
--- a/mojo/shell/tests/connect/connect_test_package.cc
+++ b/mojo/shell/tests/connect/connect_test_package.cc
@@ -63,8 +63,7 @@
     connection->AddInterface<test::mojom::ConnectTestService>(this);
     connection->AddInterface<test::mojom::BlockedInterface>(this);
 
-    uint32_t remote_id = mojom::Connector::kInvalidApplicationID;
-    connection->GetRemoteApplicationID(&remote_id);
+    uint32_t remote_id = connection->GetRemoteInstanceID();
     test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New());
     state->connection_local_name = connection->GetConnectionName();
     state->connection_remote_name = connection->GetRemoteApplicationName();
@@ -114,7 +113,7 @@
   }
 
   std::string name_;
-  uint32_t id_ = mojom::Connector::kInvalidApplicationID;
+  uint32_t id_ = shell::mojom::kInvalidInstanceID;
   std::string userid_ = mojom::kRootUserID;
   const std::string title_;
   mojom::ShellClientRequest request_;
diff --git a/mojo/shell/tests/connect/connect_unittest.cc b/mojo/shell/tests/connect/connect_unittest.cc
index b3bb952..bf04e14 100644
--- a/mojo/shell/tests/connect/connect_unittest.cc
+++ b/mojo/shell/tests/connect/connect_unittest.cc
@@ -117,9 +117,8 @@
   service->GetTitle(base::Bind(&ReceiveTitle, &title, &run_loop));
   run_loop.Run();
   EXPECT_EQ("APP", title);
-  uint32_t id = mojom::Connector::kInvalidApplicationID;
-  EXPECT_TRUE(connection->GetRemoteApplicationID(&id));
-  EXPECT_NE(id, mojom::Connector::kInvalidApplicationID);
+  EXPECT_FALSE(connection->IsPending());
+  EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID());
   EXPECT_EQ(connection->GetRemoteApplicationName(), kTestAppName);
 }
 
@@ -147,9 +146,8 @@
   service_a->GetTitle(base::Bind(&ReceiveTitle, &a_name, &run_loop));
   run_loop.Run();
   EXPECT_EQ("A", a_name);
-  uint32_t id = mojom::Connector::kInvalidApplicationID;
-  EXPECT_TRUE(connection->GetRemoteApplicationID(&id));
-  EXPECT_NE(id, mojom::Connector::kInvalidApplicationID);
+  EXPECT_FALSE(connection->IsPending());
+  EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID());
   EXPECT_EQ(connection->GetRemoteApplicationName(), kTestAppAName);
 }
 
@@ -189,9 +187,9 @@
   base::RunLoop run_loop;
   connection->SetConnectionLostClosure(base::Bind(&QuitLoop, &run_loop));
   run_loop.Run();
-  uint32_t id = mojom::Connector::kInvalidApplicationID;
-  EXPECT_TRUE(connection->GetRemoteApplicationID(&id));
-  EXPECT_EQ(id, mojom::Connector::kInvalidApplicationID);
+  EXPECT_FALSE(connection->IsPending());
+  EXPECT_EQ(mojom::ConnectResult::ACCESS_DENIED, connection->GetResult());
+  EXPECT_EQ(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID());
 }
 
 // Tests that we can expose an interface to targets on outbound connections.
@@ -205,16 +203,17 @@
     connection->GetInterface(&service);
     connection->AddInterface<test::mojom::ExposedInterface>(this);
 
-    uint32_t remote_id = mojom::Connector::kInvalidApplicationID;
+    uint32_t remote_id = shell::mojom::kInvalidInstanceID;
     {
       base::RunLoop run_loop;
-      EXPECT_FALSE(connection->GetRemoteApplicationID(&remote_id));
-      EXPECT_EQ(mojom::Connector::kInvalidApplicationID, remote_id);
+      EXPECT_TRUE(connection->IsPending());
+      EXPECT_EQ(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID());
       connection->AddConnectionCompletedClosure(
           base::Bind(&QuitLoop, &run_loop));
       run_loop.Run();
-      EXPECT_TRUE(connection->GetRemoteApplicationID(&remote_id));
-      EXPECT_NE(mojom::Connector::kInvalidApplicationID, remote_id);
+      EXPECT_FALSE(connection->IsPending());
+      remote_id = connection->GetRemoteInstanceID();
+      EXPECT_NE(mojom::kInvalidInstanceID, remote_id);
     }
 
     {
@@ -234,16 +233,17 @@
     connection->GetInterface(&service_a);
     connection->AddInterface<test::mojom::ExposedInterface>(this);
 
-    uint32_t remote_id = mojom::Connector::kInvalidApplicationID;
+    uint32_t remote_id = shell::mojom::kInvalidInstanceID;
     {
       base::RunLoop run_loop;
-      EXPECT_FALSE(connection->GetRemoteApplicationID(&remote_id));
-      EXPECT_EQ(mojom::Connector::kInvalidApplicationID, remote_id);
+      EXPECT_TRUE(connection->IsPending());
+      EXPECT_EQ(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID());
       connection->AddConnectionCompletedClosure(
           base::Bind(&QuitLoop, &run_loop));
       run_loop.Run();
-      EXPECT_TRUE(connection->GetRemoteApplicationID(&remote_id));
-      EXPECT_NE(mojom::Connector::kInvalidApplicationID, remote_id);
+      EXPECT_FALSE(connection->IsPending());
+      remote_id = connection->GetRemoteInstanceID();
+      EXPECT_NE(mojom::kInvalidInstanceID, remote_id);
     }
 
     {
diff --git a/mojo/shell/tests/lifecycle/lifecycle_unittest.cc b/mojo/shell/tests/lifecycle/lifecycle_unittest.cc
index a852f052..012dffc 100644
--- a/mojo/shell/tests/lifecycle/lifecycle_unittest.cc
+++ b/mojo/shell/tests/lifecycle/lifecycle_unittest.cc
@@ -39,7 +39,7 @@
 }
 
 struct Instance {
-  Instance() : id(mojom::Connector::kInvalidApplicationID), pid(0) {}
+  Instance() : id(shell::mojom::kInvalidInstanceID), pid(0) {}
   Instance(const std::string& name, const std::string& qualifier, uint32_t id,
            uint32_t pid)
       : name(name), qualifier(qualifier), id(id), pid(pid) {}
diff --git a/mojo/shell/tests/shell/shell_unittest.cc b/mojo/shell/tests/shell/shell_unittest.cc
index e76142a..db752bba 100644
--- a/mojo/shell/tests/shell/shell_unittest.cc
+++ b/mojo/shell/tests/shell/shell_unittest.cc
@@ -29,7 +29,7 @@
  public:
   explicit ShellTestClient(mojo::test::ShellTest* test)
       : mojo::test::ShellTestClient(test),
-        target_id_(mojom::Connector::kInvalidApplicationID),
+        target_id_(shell::mojom::kInvalidInstanceID),
         binding_(this) {}
   ~ShellTestClient() override {}
 
@@ -173,9 +173,9 @@
   //    mojo:shell_unittest)
   base::MessageLoop::current()->Run();
 
-  uint32_t remote_id = mojom::Connector::kInvalidApplicationID;
-  EXPECT_TRUE(connection->GetRemoteApplicationID(&remote_id));
-  EXPECT_NE(mojom::Connector::kInvalidApplicationID, remote_id);
+  EXPECT_FALSE(connection->IsPending());
+  uint32_t remote_id = connection->GetRemoteInstanceID();
+  EXPECT_NE(shell::mojom::kInvalidInstanceID, remote_id);
 
   // 3. Validate that this test suite's name was received from the application
   //    manager.
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index bbec7b0..eff98e32 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -863,6 +863,7 @@
 
 void CookieMonster::FlushStore(const base::Closure& callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
+
   if (initialized_ && store_.get())
     store_->Flush(callback);
   else if (!callback.is_null())
@@ -871,6 +872,7 @@
 
 void CookieMonster::SetForceKeepSessionState() {
   DCHECK(thread_checker_.CalledOnValidThread());
+
   if (store_)
     store_->SetForceKeepSessionState();
 }
@@ -1002,6 +1004,7 @@
                                     const std::string& name,
                                     const CookieChangedCallback& callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
+
   std::pair<GURL, std::string> key(gurl, name);
   if (hook_map_.count(key) == 0)
     hook_map_[key] = make_linked_ptr(new CookieChangedCallbackList());
@@ -1012,6 +1015,8 @@
 CookieMonster::~CookieMonster() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
+  // TODO(mmenke): Does it really make sense to run |delegate_| and
+  // CookieChanged callbacks when the CookieStore is destroyed?
   for (CookieMap::iterator cookie_it = cookies_.begin();
        cookie_it != cookies_.end();) {
     CookieMap::iterator current_cookie_it = cookie_it;
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 8103b749..7a06509 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -142,6 +142,8 @@
                 CookieMonsterDelegate* delegate,
                 int last_access_threshold_milliseconds);
 
+  ~CookieMonster() override;
+
   // Replaces all the cookies by |list|. This method does not flush the backend.
   void SetAllCookiesAsync(const CookieList& list,
                           const SetCookiesCallback& callback);
@@ -377,8 +379,6 @@
   // Record statistics every kRecordStatisticsIntervalSeconds of uptime.
   static const int kRecordStatisticsIntervalSeconds = 10 * 60;
 
-  ~CookieMonster() override;
-
   // The following are synchronous calls to which the asynchronous methods
   // delegate either immediately (if the store is loaded) or through a deferred
   // task (if the store is not yet loaded).
diff --git a/net/cookies/cookie_monster_perftest.cc b/net/cookies/cookie_monster_perftest.cc
index dd35638e..82ef9dd8 100644
--- a/net/cookies/cookie_monster_perftest.cc
+++ b/net/cookies/cookie_monster_perftest.cc
@@ -5,6 +5,8 @@
 #include <algorithm>
 
 #include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -119,7 +121,7 @@
 }
 
 TEST_F(CookieMonsterTest, TestAddCookiesOnSingleHost) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   std::vector<std::string> cookies;
   for (int i = 0; i < kNumCookies; i++) {
     cookies.push_back(base::StringPrintf("a%03d=b", i));
@@ -152,7 +154,7 @@
 }
 
 TEST_F(CookieMonsterTest, TestAddCookieOnManyHosts) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   std::string cookie(kCookieLine);
   std::vector<GURL> gurls;  // just wanna have ffffuunnn
   for (int i = 0; i < kNumCookies; ++i) {
@@ -185,7 +187,7 @@
 }
 
 TEST_F(CookieMonsterTest, TestDomainTree) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   GetCookiesCallback getCookiesCallback;
   SetCookieCallback setCookieCallback;
   const char domain_cookie_format_tree[] = "a=b; domain=%s";
@@ -238,7 +240,7 @@
 }
 
 TEST_F(CookieMonsterTest, TestDomainLine) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   SetCookieCallback setCookieCallback;
   GetCookiesCallback getCookiesCallback;
   std::vector<std::string> domain_list;
@@ -300,7 +302,7 @@
 
   store->SetLoadExpectation(true, initial_cookies);
 
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   // Import will happen on first access.
   GURL gurl("www.google.com");
@@ -314,7 +316,7 @@
 }
 
 TEST_F(CookieMonsterTest, TestGetKey) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   base::PerfTimeLogger timer("Cookie_monster_get_key");
   for (int i = 0; i < kNumCookies; i++)
     cm->GetKey("www.google.com");
@@ -370,9 +372,9 @@
   };
   for (int ci = 0; ci < static_cast<int>(arraysize(test_cases)); ++ci) {
     const TestCase& test_case(test_cases[ci]);
-    scoped_refptr<CookieMonster> cm(CreateMonsterFromStoreForGC(
+    scoped_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
         test_case.num_cookies, test_case.num_old_cookies, 0, 0,
-        CookieMonster::kSafeFromGlobalPurgeDays * 2));
+        CookieMonster::kSafeFromGlobalPurgeDays * 2);
 
     GURL gurl("http://google.com");
     std::string cookie_line("z=3");
diff --git a/net/cookies/cookie_monster_store_test.cc b/net/cookies/cookie_monster_store_test.cc
index 3920c9be..57cc52f 100644
--- a/net/cookies/cookie_monster_store_test.cc
+++ b/net/cookies/cookie_monster_store_test.cc
@@ -194,11 +194,12 @@
 void MockSimplePersistentCookieStore::SetForceKeepSessionState() {
 }
 
-CookieMonster* CreateMonsterFromStoreForGC(int num_secure_cookies,
-                                           int num_old_secure_cookies,
-                                           int num_non_secure_cookies,
-                                           int num_old_non_secure_cookies,
-                                           int days_old) {
+scoped_ptr<CookieMonster> CreateMonsterFromStoreForGC(
+    int num_secure_cookies,
+    int num_old_secure_cookies,
+    int num_non_secure_cookies,
+    int num_old_non_secure_cookies,
+    int days_old) {
   base::Time current(base::Time::Now());
   base::Time past_creation(base::Time::Now() - base::TimeDelta::FromDays(1000));
   scoped_refptr<MockSimplePersistentCookieStore> store(
@@ -232,7 +233,7 @@
     store->AddCookie(cc);
   }
 
-  return new CookieMonster(store.get(), NULL);
+  return make_scoped_ptr(new CookieMonster(store.get(), nullptr));
 }
 
 MockSimplePersistentCookieStore::~MockSimplePersistentCookieStore() {
diff --git a/net/cookies/cookie_monster_store_test.h b/net/cookies/cookie_monster_store_test.h
index 77fef31..bb8239c3 100644
--- a/net/cookies/cookie_monster_store_test.h
+++ b/net/cookies/cookie_monster_store_test.h
@@ -18,6 +18,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_monster.h"
 
@@ -190,11 +191,12 @@
 // will be marked secure and non-secure, respectively. Do two SetCookies().
 // Return whether each of the two SetCookies() took longer than |gc_perf_micros|
 // to complete, and how many cookie were left in the store afterwards.
-CookieMonster* CreateMonsterFromStoreForGC(int num_secure_cookies,
-                                           int num_old_secure_cookies,
-                                           int num_non_secure_cookies,
-                                           int num_old_non_secure_cookies,
-                                           int days_old);
+scoped_ptr<CookieMonster> CreateMonsterFromStoreForGC(
+    int num_secure_cookies,
+    int num_old_secure_cookies,
+    int num_non_secure_cookies,
+    int num_old_non_secure_cookies,
+    int days_old);
 
 }  // namespace net
 
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 88f5cbd..8e61dad 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -71,8 +71,8 @@
 const char kOtherDomain[] = "http://www.mit.edu";
 
 struct CookieMonsterTestTraits {
-  static scoped_refptr<CookieStore> Create() {
-    return new CookieMonster(NULL, NULL);
+  static scoped_ptr<CookieStore> Create() {
+    return make_scoped_ptr(new CookieMonster(nullptr, nullptr));
   }
 
   static const bool supports_http_only = true;
@@ -85,8 +85,8 @@
 };
 
 struct CookieMonsterEnforcingStrictSecure {
-  static scoped_refptr<CookieStore> Create() {
-    return new CookieMonster(NULL, NULL);
+  static scoped_ptr<CookieStore> Create() {
+    return make_scoped_ptr(new CookieMonster(nullptr, nullptr));
   }
 
   static const bool supports_http_only = true;
@@ -166,14 +166,14 @@
 
   // Helper for DeleteAllForHost test; repopulates CM with same layout
   // each time.
-  void PopulateCmForDeleteAllForHost(scoped_refptr<CookieMonster> cm) {
+  void PopulateCmForDeleteAllForHost(CookieMonster* cm) {
     GURL url_top_level_domain_plus_1(kTopLevelDomainPlus1);
     GURL url_top_level_domain_plus_2(kTopLevelDomainPlus2);
     GURL url_top_level_domain_plus_2_secure(kTopLevelDomainPlus2Secure);
     GURL url_top_level_domain_plus_3(kTopLevelDomainPlus3);
     GURL url_other(kOtherDomain);
 
-    this->DeleteAll(cm.get());
+    this->DeleteAll(cm);
 
     // Static population for probe:
     //    * Three levels of domain cookie (.b.a, .c.b.a, .d.c.b.a)
@@ -186,75 +186,75 @@
 
     // Domain cookies
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_1, "dom_1", "X", ".harvard.edu",
-        "/", base::Time(), base::Time(), base::Time(), false, false, false,
+        cm, url_top_level_domain_plus_1, "dom_1", "X", ".harvard.edu", "/",
+        base::Time(), base::Time(), base::Time(), false, false, false,
         COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "dom_2", "X",
-        ".math.harvard.edu", "/", base::Time(), base::Time(), base::Time(),
-        false, false, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "dom_2", "X", ".math.harvard.edu", "/",
+        base::Time(), base::Time(), base::Time(), false, false, false,
+        COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_3, "dom_3", "X",
+        cm, url_top_level_domain_plus_3, "dom_3", "X",
         ".bourbaki.math.harvard.edu", "/", base::Time(), base::Time(),
         base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
 
     // Host cookies
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_1, "host_1", "X", std::string(),
-        "/", base::Time(), base::Time(), base::Time(), false, false, false,
+        cm, url_top_level_domain_plus_1, "host_1", "X", std::string(), "/",
+        base::Time(), base::Time(), base::Time(), false, false, false,
         COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "host_2", "X", std::string(),
-        "/", base::Time(), base::Time(), base::Time(), false, false, false,
+        cm, url_top_level_domain_plus_2, "host_2", "X", std::string(), "/",
+        base::Time(), base::Time(), base::Time(), false, false, false,
         COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_3, "host_3", "X", std::string(),
-        "/", base::Time(), base::Time(), base::Time(), false, false, false,
+        cm, url_top_level_domain_plus_3, "host_3", "X", std::string(), "/",
+        base::Time(), base::Time(), base::Time(), false, false, false,
         COOKIE_PRIORITY_DEFAULT));
 
     // http_only cookie
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "httpo_check", "x",
-        std::string(), "/", base::Time(), base::Time(), base::Time(), false,
-        true, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "httpo_check", "x", std::string(), "/",
+        base::Time(), base::Time(), base::Time(), false, true, false,
+        COOKIE_PRIORITY_DEFAULT));
 
     // same-site cookie
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "firstp_check", "x",
-        std::string(), "/", base::Time(), base::Time(), base::Time(), false,
-        false, true, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "firstp_check", "x", std::string(),
+        "/", base::Time(), base::Time(), base::Time(), false, false, true,
+        COOKIE_PRIORITY_DEFAULT));
 
     // Secure cookies
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2_secure, "sec_dom", "X",
+        cm, url_top_level_domain_plus_2_secure, "sec_dom", "X",
         ".math.harvard.edu", "/", base::Time(), base::Time(), base::Time(),
         true, false, false, COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2_secure, "sec_host", "X",
-        std::string(), "/", base::Time(), base::Time(), base::Time(), true,
-        false, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2_secure, "sec_host", "X", std::string(),
+        "/", base::Time(), base::Time(), base::Time(), true, false, false,
+        COOKIE_PRIORITY_DEFAULT));
 
     // Domain path cookies
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "dom_path_1", "X",
-        ".math.harvard.edu", "/dir1", base::Time(), base::Time(), base::Time(),
-        false, false, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "dom_path_1", "X", ".math.harvard.edu",
+        "/dir1", base::Time(), base::Time(), base::Time(), false, false, false,
+        COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "dom_path_2", "X",
-        ".math.harvard.edu", "/dir1/dir2", base::Time(), base::Time(),
-        base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "dom_path_2", "X", ".math.harvard.edu",
+        "/dir1/dir2", base::Time(), base::Time(), base::Time(), false, false,
+        false, COOKIE_PRIORITY_DEFAULT));
 
     // Host path cookies
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "host_path_1", "X",
-        std::string(), "/dir1", base::Time(), base::Time(), base::Time(), false,
-        false, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "host_path_1", "X", std::string(),
+        "/dir1", base::Time(), base::Time(), base::Time(), false, false, false,
+        COOKIE_PRIORITY_DEFAULT));
     EXPECT_TRUE(this->SetCookieWithDetails(
-        cm.get(), url_top_level_domain_plus_2, "host_path_2", "X",
-        std::string(), "/dir1/dir2", base::Time(), base::Time(), base::Time(),
-        false, false, false, COOKIE_PRIORITY_DEFAULT));
+        cm, url_top_level_domain_plus_2, "host_path_2", "X", std::string(),
+        "/dir1/dir2", base::Time(), base::Time(), base::Time(), false, false,
+        false, COOKIE_PRIORITY_DEFAULT));
 
-    EXPECT_EQ(14U, this->GetAllCookies(cm.get()).size());
+    EXPECT_EQ(14U, this->GetAllCookies(cm).size());
   }
 
   Time GetFirstCookieAccessDate(CookieMonster* cm) {
@@ -283,7 +283,7 @@
         (domain_max_cookies + domain_purge_cookies) * 2;
     // Add a bunch of cookies on a single host, should purge them.
     {
-      scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+      scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
       for (int i = 0; i < more_than_enough_cookies; ++i) {
         std::string cookie = base::StringPrintf("a%03d=b", i);
         EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), cookie));
@@ -301,7 +301,7 @@
     // between them.  We shouldn't go above kDomainMaxCookies for both together.
     GURL url_google_specific(http_www_google_.Format("http://www.gmail.%D"));
     {
-      scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+      scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
       for (int i = 0; i < more_than_enough_cookies; ++i) {
         std::string cookie_general = base::StringPrintf("a%03d=b", i);
         EXPECT_TRUE(
@@ -444,10 +444,10 @@
                                 size_t expected_secure_cookies,
                                 size_t expected_non_secure_cookies,
                                 const AltHosts* alt_host_entries) {
-    scoped_refptr<CookieMonster> cm;
+    scoped_ptr<CookieMonster> cm;
 
     if (alt_host_entries == nullptr) {
-      cm = new CookieMonster(nullptr, nullptr);
+      cm.reset(new CookieMonster(nullptr, nullptr));
     } else {
       // When generating all of these cookies on alternate hosts, they need to
       // be all older than the max "safe" date for GC, which is currently 30
@@ -495,7 +495,7 @@
     DCHECK_EQ(50U, CookieMonster::kDomainCookiesQuotaMedium);
     DCHECK_EQ(70U, CookieMonster::kDomainCookiesQuotaHigh);
 
-    scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+    scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
 
     // Each test case adds 181 cookies, so 31 cookies are evicted.
     // Cookie same priority, repeated for each priority.
@@ -713,7 +713,7 @@
  protected:
   DeferredCookieTaskTest() : expect_load_called_(false) {
     persistent_store_ = new NewMockPersistentCookieStore();
-    cookie_monster_ = new CookieMonster(persistent_store_.get(), NULL);
+    cookie_monster_.reset(new CookieMonster(persistent_store_.get(), nullptr));
   }
 
   // Defines a cookie to be returned from PersistentCookieStore::Load
@@ -802,7 +802,7 @@
   // Indicates whether ExpectLoadCall() has been called.
   bool expect_load_called_;
   // Stores the CookieMonster under test.
-  scoped_refptr<CookieMonster> cookie_monster_;
+  scoped_ptr<CookieMonster> cookie_monster_;
   // Stores the mock PersistentCookieStore.
   scoped_refptr<NewMockPersistentCookieStore> persistent_store_;
 };
@@ -1145,7 +1145,7 @@
 
 TEST_F(CookieMonsterTest, TestCookieDeleteAll) {
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
   CookieOptions options;
   options.set_include_httponly();
 
@@ -1178,7 +1178,7 @@
 }
 
 TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedBetweenTimestamps) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   Time now = Time::Now();
 
   // Nothing has been added so nothing should be deleted.
@@ -1220,8 +1220,8 @@
 static const int kAccessDelayMs = kLastAccessThresholdMilliseconds + 20;
 
 TEST_F(CookieMonsterTest, TestLastAccess) {
-  scoped_refptr<CookieMonster> cm(
-      new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));
+  scoped_ptr<CookieMonster> cm(
+      new CookieMonster(nullptr, nullptr, kLastAccessThresholdMilliseconds));
 
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
   const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
@@ -1268,8 +1268,8 @@
 }
 
 TEST_F(CookieMonsterTest, SetCookieableSchemes) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
-  scoped_refptr<CookieMonster> cm_foo(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
+  scoped_ptr<CookieMonster> cm_foo(new CookieMonster(nullptr, nullptr));
 
   // Only cm_foo should allow foo:// cookies.
   std::vector<std::string> schemes;
@@ -1286,8 +1286,8 @@
 }
 
 TEST_F(CookieMonsterTest, GetAllCookiesForURL) {
-  scoped_refptr<CookieMonster> cm(
-      new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));
+  scoped_ptr<CookieMonster> cm(
+      new CookieMonster(nullptr, nullptr, kLastAccessThresholdMilliseconds));
 
   // Create an httponly cookie.
   CookieOptions options;
@@ -1355,7 +1355,7 @@
 }
 
 TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   CookieOptions options;
 
   EXPECT_TRUE(SetCookieWithOptions(cm.get(), www_google_foo_.url(),
@@ -1393,7 +1393,7 @@
 }
 
 TEST_F(CookieMonsterTest, CookieSorting) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
 
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B1; path=/"));
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B2; path=/foo"));
@@ -1422,6 +1422,27 @@
   EXPECT_EQ("A1", cookies[5].Value());
 }
 
+TEST_F(CookieMonsterTest, DeleteCookieByName) {
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
+
+  EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A1; path=/"));
+  EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A2; path=/foo"));
+  EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A3; path=/bar"));
+  EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B1; path=/"));
+  EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B2; path=/foo"));
+  EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B3; path=/bar"));
+
+  DeleteCookie(cm.get(), http_www_google_.AppendPath("foo/bar"), "A");
+
+  CookieList cookies = GetAllCookies(cm.get());
+  size_t expected_size = 4;
+  EXPECT_EQ(expected_size, cookies.size());
+  for (CookieList::iterator it = cookies.begin(); it != cookies.end(); ++it) {
+    EXPECT_NE("A1", it->Value());
+    EXPECT_NE("A2", it->Value());
+  }
+}
+
 // Tests importing from a persistent cookie store that contains duplicate
 // equivalent cookies. This situation should be handled by removing the
 // duplicate cookie (both from the in-memory cache, and from the backing store).
@@ -1478,7 +1499,7 @@
   // Inject our initial cookies into the mock PersistentCookieStore.
   store->SetLoadExpectation(true, initial_cookies);
 
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   // Verify that duplicates were not imported for path "/".
   // (If this had failed, GetCookies() would have also returned X=1, X=2, X=4).
@@ -1526,7 +1547,7 @@
   // Inject our initial cookies into the mock PersistentCookieStore.
   store->SetLoadExpectation(true, initial_cookies);
 
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   CookieList list(GetAllCookies(cm.get()));
   EXPECT_EQ(2U, list.size());
@@ -1542,8 +1563,7 @@
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
   scoped_refptr<MockCookieMonsterDelegate> delegate(
       new MockCookieMonsterDelegate);
-  scoped_refptr<CookieMonster> cm(
-      new CookieMonster(store.get(), delegate.get()));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), delegate.get()));
 
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "C=D"));
@@ -1622,7 +1642,7 @@
 }
 
 TEST_F(CookieMonsterTest, DeleteAllForHost) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
 
   // Test probes:
   //    * Non-secure URL, mid-level (http://w.c.b.a)
@@ -1632,7 +1652,7 @@
   // the http_only cookie, the host secure cookie, and the two host
   // path cookies.  http_only, secure, and paths are ignored by
   // this call, and domain cookies arent touched.
-  PopulateCmForDeleteAllForHost(cm);
+  PopulateCmForDeleteAllForHost(cm.get());
   EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
             GetCookies(cm.get(), GURL(kTopLevelDomainPlus3)));
   EXPECT_EQ("dom_1=X; dom_2=X; host_2=X; sec_dom=X; sec_host=X",
@@ -1660,7 +1680,7 @@
             GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                       std::string("/dir1/dir2/xxx"))));
 
-  PopulateCmForDeleteAllForHost(cm);
+  PopulateCmForDeleteAllForHost(cm.get());
   EXPECT_EQ(6, DeleteAllCreatedBetweenForHost(
                    cm.get(), base::Time(), base::Time::Now(),
                    GURL(kTopLevelDomainPlus2Secure)));
@@ -1676,7 +1696,7 @@
             GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                       std::string("/dir1/dir2/xxx"))));
 
-  PopulateCmForDeleteAllForHost(cm);
+  PopulateCmForDeleteAllForHost(cm.get());
   EXPECT_EQ(6,
             DeleteAllCreatedBetweenForHost(
                 cm.get(), base::Time(), base::Time::Now(),
@@ -1695,7 +1715,7 @@
 }
 
 TEST_F(CookieMonsterTest, UniqueCreationTime) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   CookieOptions options;
 
   // Add in three cookies through every public interface to the
@@ -1758,7 +1778,7 @@
 // Mainly a test of GetEffectiveDomain, or more specifically, of the
 // expected behavior of GetEffectiveDomain within the CookieMonster.
 TEST_F(CookieMonsterTest, GetKey) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
 
   // This test is really only interesting if GetKey() actually does something.
   EXPECT_EQ("google.com", cm->GetKey("www.google.com"));
@@ -1824,7 +1844,7 @@
 
   // Create new cookies and flush them to the store.
   {
-    scoped_refptr<CookieMonster> cmout(new CookieMonster(store.get(), NULL));
+    scoped_ptr<CookieMonster> cmout(new CookieMonster(store.get(), nullptr));
     for (const CookiesInputInfo* p = input_info;
          p < &input_info[arraysize(input_info)]; p++) {
       EXPECT_TRUE(SetCookieWithDetails(
@@ -1840,7 +1860,7 @@
 
   // Create a new cookie monster and make sure that everything is correct
   {
-    scoped_refptr<CookieMonster> cmin(new CookieMonster(store.get(), NULL));
+    scoped_ptr<CookieMonster> cmin(new CookieMonster(store.get(), nullptr));
     CookieList cookies(GetAllCookies(cmin.get()));
     ASSERT_EQ(2u, cookies.size());
     // Ordering is path length, then creation time.  So second cookie
@@ -1870,7 +1890,7 @@
 TEST_F(CookieMonsterTest, CookieListOrdering) {
   // Put a random set of cookies into a monster and make sure
   // they're returned in the right order.
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   EXPECT_TRUE(
       SetCookie(cm.get(), GURL("http://d.c.b.a.google.com/aa/x.html"), "c=1"));
   EXPECT_TRUE(SetCookie(cm.get(), GURL("http://b.a.google.com/aa/bb/cc/x.html"),
@@ -1927,7 +1947,7 @@
   // First we check to make sure that a whole lot of recent cookies
   // doesn't get rid of anything after garbage collection is checked for.
   {
-    scoped_refptr<CookieMonster> cm(
+    scoped_ptr<CookieMonster> cm(
         CreateMonsterForGC(CookieMonster::kMaxCookies * 2));
     EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
     SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
@@ -1969,9 +1989,9 @@
 
   for (int ci = 0; ci < static_cast<int>(arraysize(test_cases)); ++ci) {
     const TestCase* test_case = &test_cases[ci];
-    scoped_refptr<CookieMonster> cm(CreateMonsterFromStoreForGC(
+    scoped_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
         test_case->num_cookies, test_case->num_old_cookies, 0, 0,
-        CookieMonster::kSafeFromGlobalPurgeDays * 2));
+        CookieMonster::kSafeFromGlobalPurgeDays * 2);
     EXPECT_EQ(test_case->expected_initial_cookies,
               GetAllCookies(cm.get()).size())
         << "For test case " << ci;
@@ -2044,7 +2064,7 @@
 TEST_F(CookieMonsterTest, FlushStore) {
   scoped_refptr<CallbackCounter> counter(new CallbackCounter());
   scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   ASSERT_EQ(0, store->flush_count());
   ASSERT_EQ(0, counter->callback_count());
@@ -2079,7 +2099,7 @@
   ASSERT_EQ(2, counter->callback_count());
 
   // If there's no backing store, FlushStore() is always a safe no-op.
-  cm = new CookieMonster(NULL, NULL);
+  cm.reset(new CookieMonster(nullptr, nullptr));
   GetAllCookies(cm.get());  // Force init.
   cm->FlushStore(base::Closure());
   base::MessageLoop::current()->RunUntilIdle();
@@ -2094,7 +2114,7 @@
 
 TEST_F(CookieMonsterTest, SetAllCookies) {
   scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
   cm->SetPersistSessionCookies(true);
 
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "U=V; path=/"));
@@ -2140,7 +2160,7 @@
 }
 
 TEST_F(CookieMonsterTest, ComputeCookieDiff) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
 
   base::Time now = base::Time::Now();
   base::Time creation_time = now - base::TimeDelta::FromSeconds(1);
@@ -2257,7 +2277,7 @@
 // works).
 TEST_F(CookieMonsterTest, DeleteAll) {
   scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
   cm->SetPersistSessionCookies(true);
 
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "X=Y; path=/"));
@@ -2268,7 +2288,7 @@
 }
 
 TEST_F(CookieMonsterTest, HistogramCheck) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   // Should match call in InitializeHistograms, but doesn't really matter
   // since the histogram should have been initialized by the CM construction
   // above.
@@ -2307,7 +2327,7 @@
 // CookieStore if the "persist session cookies" option is on.
 TEST_F(CookieMonsterTest, PersistSessionCookies) {
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
   cm->SetPersistSessionCookies(true);
 
   // All cookies set with SetCookie are session cookies.
@@ -2343,7 +2363,7 @@
 // Test the commands sent to the persistent cookie store.
 TEST_F(CookieMonsterTest, PersisentCookieStorageTest) {
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   // Add a cookie.
   EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(),
@@ -2412,7 +2432,7 @@
   // Inject our initial cookies into the mock PersistentCookieStore.
   store->SetLoadExpectation(true, initial_cookies);
 
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   EXPECT_EQ("foo=bar; hello=world", GetCookies(cm.get(), url));
 }
@@ -2423,7 +2443,7 @@
   const std::string cookie_source_histogram = "Cookie.CookieSourceScheme";
 
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   histograms.ExpectTotalCount(cookie_source_histogram, 0);
 
@@ -2490,7 +2510,7 @@
   const std::string cookie_source_histogram = "Cookie.CookieDeleteEquivalent";
 
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   // Set a secure cookie from a secure origin
   EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "A=B; Secure"));
@@ -2555,7 +2575,7 @@
 }
 
 TEST_F(CookieMonsterStrictSecureTest, SetSecureCookies) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   GURL http_url("http://www.google.com");
   GURL http_superdomain_url("http://google.com");
   GURL https_url("https://www.google.com");
@@ -2748,7 +2768,7 @@
 // Tests that strict secure cookies doesn't trip equivalent cookie checks
 // accidentally. Regression test for https://crbug.com/569943.
 TEST_F(CookieMonsterStrictSecureTest, EquivalentCookies) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr));
   GURL http_url("http://www.google.com");
   GURL http_superdomain_url("http://google.com");
   GURL https_url("https://www.google.com");
@@ -2773,7 +2793,7 @@
   const std::string cookie_source_histogram = "Cookie.CookieDeleteEquivalent";
 
   scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
-  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+  scoped_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
 
   // Set a secure cookie from a secure origin
   EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "A=B; Secure"));
@@ -2848,7 +2868,7 @@
   CookieMonsterNotificationTest()
       : test_url_("http://www.google.com/foo"),
         store_(new MockPersistentCookieStore),
-        monster_(new CookieMonster(store_.get(), NULL)) {}
+        monster_(new CookieMonster(store_.get(), nullptr)) {}
 
   ~CookieMonsterNotificationTest() override {}
 
@@ -2859,7 +2879,7 @@
 
  private:
   scoped_refptr<MockPersistentCookieStore> store_;
-  scoped_refptr<CookieMonster> monster_;
+  scoped_ptr<CookieMonster> monster_;
 };
 
 void RecordCookieChanges(std::vector<CanonicalCookie>* out_cookies,
diff --git a/net/cookies/cookie_store.cc b/net/cookies/cookie_store.cc
index 780a292..85f0192 100644
--- a/net/cookies/cookie_store.cc
+++ b/net/cookies/cookie_store.cc
@@ -8,8 +8,6 @@
 
 namespace net {
 
-CookieStore::CookieStore() {}
-
 CookieStore::~CookieStore() {}
 
 std::string CookieStore::BuildCookieLine(
@@ -62,4 +60,6 @@
   GetCookieListWithOptionsAsync(url, options, callback);
 }
 
+CookieStore::CookieStore() {}
+
 }  // namespace net
diff --git a/net/cookies/cookie_store.h b/net/cookies/cookie_store.h
index f7805b9e6..6485261 100644
--- a/net/cookies/cookie_store.h
+++ b/net/cookies/cookie_store.h
@@ -12,7 +12,7 @@
 
 #include "base/callback.h"
 #include "base/callback_list.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
 #include "net/base/net_export.h"
 #include "net/cookies/canonical_cookie.h"
@@ -31,7 +31,7 @@
 // All async functions may either invoke the callback asynchronously, or they
 // may be invoked immediately (prior to return of the asynchronous function).
 // Destroying the CookieStore will cancel pending async callbacks.
-class NET_EXPORT CookieStore : public base::RefCountedThreadSafe<CookieStore> {
+class NET_EXPORT CookieStore {
  public:
   // Callback definitions.
   typedef base::Callback<void(const CookieList& cookies)> GetCookieListCallback;
@@ -44,6 +44,8 @@
       CookieChangedCallbackList;
   typedef CookieChangedCallbackList::Subscription CookieChangedSubscription;
 
+  virtual ~CookieStore();
+
   // Returns the cookie line (e.g. "cookie1=value1; cookie2=value2") represented
   // by |cookies|. The string is built in the same order as the given list.
   //
@@ -201,9 +203,7 @@
       const CookieChangedCallback& callback) = 0;
 
  protected:
-  friend class base::RefCountedThreadSafe<CookieStore>;
   CookieStore();
-  virtual ~CookieStore();
 };
 
 }  // namespace net
diff --git a/net/cookies/cookie_store_test_helpers.cc b/net/cookies/cookie_store_test_helpers.cc
index d055c37..50ae05d 100644
--- a/net/cookies/cookie_store_test_helpers.cc
+++ b/net/cookies/cookie_store_test_helpers.cc
@@ -34,10 +34,9 @@
 const int kDelayedTime = 0;
 
 DelayedCookieMonster::DelayedCookieMonster()
-      : cookie_monster_(new CookieMonster(NULL, NULL)),
-        did_run_(false),
-        result_(false) {
-}
+    : cookie_monster_(new CookieMonster(nullptr, nullptr)),
+      did_run_(false),
+      result_(false) {}
 
 DelayedCookieMonster::~DelayedCookieMonster() {
 }
diff --git a/net/cookies/cookie_store_test_helpers.h b/net/cookies/cookie_store_test_helpers.h
index ad02ab6..e2f566b 100644
--- a/net/cookies/cookie_store_test_helpers.h
+++ b/net/cookies/cookie_store_test_helpers.h
@@ -19,6 +19,8 @@
  public:
   DelayedCookieMonster();
 
+  ~DelayedCookieMonster() override;
+
   // Call the asynchronous CookieMonster function, expect it to immediately
   // invoke the internal callback.
   // Post a delayed task to invoke the original callback with the results.
@@ -111,9 +113,8 @@
       const CookieMonster::GetCookieListCallback& callback);
 
   friend class base::RefCountedThreadSafe<DelayedCookieMonster>;
-  ~DelayedCookieMonster() override;
 
-  scoped_refptr<CookieMonster> cookie_monster_;
+  scoped_ptr<CookieMonster> cookie_monster_;
 
   bool did_run_;
   bool result_;
diff --git a/net/cookies/cookie_store_unittest.h b/net/cookies/cookie_store_unittest.h
index 7198f508..a47e953 100644
--- a/net/cookies/cookie_store_unittest.h
+++ b/net/cookies/cookie_store_unittest.h
@@ -42,7 +42,7 @@
 // The CookieStoreTestTraits must have the following members:
 // struct CookieStoreTestTraits {
 //   // Factory function. Will be called at most once per test.
-//   static scoped_refptr<CookieStore> Create();
+//   static scoped_ptr<CookieStore> Create();
 //
 //   // The cookie store supports cookies with the exclude_httponly() option.
 //   static const bool supports_http_only;
@@ -278,10 +278,10 @@
   }
 
   // Returns the CookieStore for the test - each test only uses one CookieStore.
-  scoped_refptr<CookieStore> GetCookieStore() {
+  CookieStore* GetCookieStore() {
     if (!cookie_store_)
       cookie_store_ = CookieStoreTestTraits::Create();
-    return cookie_store_;
+    return cookie_store_.get();
   }
 
   // Compares two cookie lines.
@@ -332,13 +332,13 @@
     return tokens;
   }
 
-  scoped_refptr<CookieStore> cookie_store_;
+  scoped_ptr<CookieStore> cookie_store_;
 };
 
 TYPED_TEST_CASE_P(CookieStoreTest);
 
 TYPED_TEST_P(CookieStoreTest, SetCookieWithDetailsAsync) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2);
   base::Time one_hour_ago = base::Time::Now() - base::TimeDelta::FromHours(1);
@@ -346,39 +346,39 @@
       base::Time::Now() + base::TimeDelta::FromHours(1);
 
   EXPECT_TRUE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_foo_.url(), "A", "B", std::string(), "/foo",
+      cs, this->www_google_foo_.url(), "A", "B", std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false, false, false,
       COOKIE_PRIORITY_DEFAULT));
   // Note that for the creation time to be set exactly, without modification,
   // it must be different from the one set by the line above.
   EXPECT_TRUE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_bar_.url(), "C", "D",
-      this->www_google_bar_.domain(), "/bar", two_hours_ago, base::Time(),
-      one_hour_ago, false, true, false, COOKIE_PRIORITY_DEFAULT));
+      cs, this->www_google_bar_.url(), "C", "D", this->www_google_bar_.domain(),
+      "/bar", two_hours_ago, base::Time(), one_hour_ago, false, true, false,
+      COOKIE_PRIORITY_DEFAULT));
   EXPECT_TRUE(this->SetCookieWithDetails(
-      cs.get(), this->http_www_google_.url(), "E", "F", std::string(),
-      std::string(), base::Time(), base::Time(), base::Time(), true, false,
-      false, COOKIE_PRIORITY_DEFAULT));
+      cs, this->http_www_google_.url(), "E", "F", std::string(), std::string(),
+      base::Time(), base::Time(), base::Time(), true, false, false,
+      COOKIE_PRIORITY_DEFAULT));
 
   // Test that malformed attributes fail to set the cookie.
   EXPECT_FALSE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_foo_.url(), " A", "B", std::string(), "/foo",
+      cs, this->www_google_foo_.url(), " A", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false, false, false,
       COOKIE_PRIORITY_DEFAULT));
   EXPECT_FALSE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_foo_.url(), "A;", "B", std::string(), "/foo",
+      cs, this->www_google_foo_.url(), "A;", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false, false, false,
       COOKIE_PRIORITY_DEFAULT));
   EXPECT_FALSE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_foo_.url(), "A=", "B", std::string(), "/foo",
+      cs, this->www_google_foo_.url(), "A=", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false, false, false,
       COOKIE_PRIORITY_DEFAULT));
   EXPECT_FALSE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_foo_.url(), "A", "B", "google.ozzzzzzle",
-      "foo", base::Time(), base::Time(), base::Time(), false, false, false,
+      cs, this->www_google_foo_.url(), "A", "B", "google.ozzzzzzle", "foo",
+      base::Time(), base::Time(), base::Time(), false, false, false,
       COOKIE_PRIORITY_DEFAULT));
   EXPECT_FALSE(this->SetCookieWithDetails(
-      cs.get(), this->www_google_foo_.url(), "A=", "B", std::string(), "foo",
+      cs, this->www_google_foo_.url(), "A=", "B", std::string(), "foo",
       base::Time(), base::Time(), base::Time(), false, false, false,
       COOKIE_PRIORITY_DEFAULT));
 
@@ -391,8 +391,8 @@
   options.set_include_same_site();
   options.set_do_not_update_access_time();
 
-  CookieList cookies = this->GetCookieListWithOptions(
-      cs.get(), this->www_google_foo_.url(), options);
+  CookieList cookies =
+      this->GetCookieListWithOptions(cs, this->www_google_foo_.url(), options);
   CookieList::iterator it = cookies.begin();
 
   ASSERT_TRUE(it != cookies.end());
@@ -416,15 +416,15 @@
   // Verify that the cookie was set as 'httponly' by passing in a CookieOptions
   // that excludes them and getting an empty result.
   if (TypeParam::supports_http_only) {
-    cookies = this->GetCookieListWithOptions(
-        cs.get(), this->www_google_bar_.url(), CookieOptions());
+    cookies = this->GetCookieListWithOptions(cs, this->www_google_bar_.url(),
+                                             CookieOptions());
     it = cookies.begin();
     ASSERT_TRUE(it == cookies.end());
   }
 
   // Get the cookie using the wide open |options|:
-  cookies = this->GetCookieListWithOptions(
-      cs.get(), this->www_google_bar_.url(), options);
+  cookies =
+      this->GetCookieListWithOptions(cs, this->www_google_bar_.url(), options);
   it = cookies.begin();
 
   ASSERT_TRUE(it != cookies.end());
@@ -442,8 +442,8 @@
 
   EXPECT_TRUE(++it == cookies.end());
 
-  cookies = this->GetCookieListWithOptions(
-      cs.get(), this->https_www_google_.url(), options);
+  cookies = this->GetCookieListWithOptions(cs, this->https_www_google_.url(),
+                                           options);
   it = cookies.begin();
 
   ASSERT_TRUE(it != cookies.end());
@@ -465,289 +465,272 @@
 }
 
 TYPED_TEST_P(CookieStoreTest, DomainTest) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "A=B"));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(),
+      this->SetCookie(cs, this->http_www_google_.url(),
                       this->http_www_google_.Format("C=D; domain=.%D")));
-  this->MatchCookieLines(
-      "A=B; C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B; C=D",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Verify that A=B was set as a host cookie rather than a domain
   // cookie -- should not be accessible from a sub sub-domain.
   this->MatchCookieLines(
-      "C=D",
-      this->GetCookies(
-          cs.get(), GURL(this->http_www_google_.Format("http://foo.www.%D"))));
+      "C=D", this->GetCookies(
+                 cs, GURL(this->http_www_google_.Format("http://foo.www.%D"))));
 
   // Test and make sure we find domain cookies on the same domain.
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(),
+      this->SetCookie(cs, this->http_www_google_.url(),
                       this->http_www_google_.Format("E=F; domain=.www.%D")));
-  this->MatchCookieLines(
-      "A=B; C=D; E=F",
-      this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B; C=D; E=F",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Test setting a domain= that doesn't start w/ a dot, should
   // treat it as a domain cookie, as if there was a pre-pended dot.
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(),
+      this->SetCookie(cs, this->http_www_google_.url(),
                       this->http_www_google_.Format("G=H; domain=www.%D")));
-  this->MatchCookieLines(
-      "A=B; C=D; E=F; G=H",
-      this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B; C=D; E=F; G=H",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Test domain enforcement, should fail on a sub-domain or something too deep.
   EXPECT_FALSE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(),
+      this->SetCookie(cs, this->http_www_google_.url(),
                       this->http_www_google_.Format("I=J; domain=.%R")));
   this->MatchCookieLines(
       std::string(),
-      this->GetCookies(cs.get(),
-                       GURL(this->http_www_google_.Format("http://a.%R"))));
+      this->GetCookies(cs, GURL(this->http_www_google_.Format("http://a.%R"))));
   EXPECT_FALSE(this->SetCookie(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       this->http_www_google_.Format("K=L; domain=.bla.www.%D")));
   this->MatchCookieLines(
       "C=D; E=F; G=H",
       this->GetCookies(
-          cs.get(), GURL(this->http_www_google_.Format("http://bla.www.%D"))));
-  this->MatchCookieLines(
-      "A=B; C=D; E=F; G=H",
-      this->GetCookies(cs.get(), this->http_www_google_.url()));
+          cs, GURL(this->http_www_google_.Format("http://bla.www.%D"))));
+  this->MatchCookieLines("A=B; C=D; E=F; G=H",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 }
 
 // FireFox recognizes domains containing trailing periods as valid.
 // IE and Safari do not. Assert the expected policy here.
 TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_FALSE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_FALSE(this->SetCookie(cs, this->http_www_google_.url(),
                                "a=1; domain=.www.google.com."));
-  EXPECT_FALSE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_FALSE(this->SetCookie(cs, this->http_www_google_.url(),
                                "b=2; domain=.www.google.com.."));
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
 }
 
 // Test that cookies can bet set on higher level domains.
 TYPED_TEST_P(CookieStoreTest, ValidSubdomainTest) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url_abcd("http://a.b.c.d.com");
   GURL url_bcd("http://b.c.d.com");
   GURL url_cd("http://c.d.com");
   GURL url_d("http://d.com");
 
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_abcd, "a=1; domain=.a.b.c.d.com"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_abcd, "b=2; domain=.b.c.d.com"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_abcd, "c=3; domain=.c.d.com"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_abcd, "d=4; domain=.d.com"));
+  EXPECT_TRUE(this->SetCookie(cs, url_abcd, "a=1; domain=.a.b.c.d.com"));
+  EXPECT_TRUE(this->SetCookie(cs, url_abcd, "b=2; domain=.b.c.d.com"));
+  EXPECT_TRUE(this->SetCookie(cs, url_abcd, "c=3; domain=.c.d.com"));
+  EXPECT_TRUE(this->SetCookie(cs, url_abcd, "d=4; domain=.d.com"));
 
-  this->MatchCookieLines("a=1; b=2; c=3; d=4",
-                         this->GetCookies(cs.get(), url_abcd));
-  this->MatchCookieLines("b=2; c=3; d=4", this->GetCookies(cs.get(), url_bcd));
-  this->MatchCookieLines("c=3; d=4", this->GetCookies(cs.get(), url_cd));
-  this->MatchCookieLines("d=4", this->GetCookies(cs.get(), url_d));
+  this->MatchCookieLines("a=1; b=2; c=3; d=4", this->GetCookies(cs, url_abcd));
+  this->MatchCookieLines("b=2; c=3; d=4", this->GetCookies(cs, url_bcd));
+  this->MatchCookieLines("c=3; d=4", this->GetCookies(cs, url_cd));
+  this->MatchCookieLines("d=4", this->GetCookies(cs, url_d));
 
   // Check that the same cookie can exist on different sub-domains.
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_bcd, "X=bcd; domain=.b.c.d.com"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_bcd, "X=cd; domain=.c.d.com"));
+  EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=bcd; domain=.b.c.d.com"));
+  EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=cd; domain=.c.d.com"));
   this->MatchCookieLines("b=2; c=3; d=4; X=bcd; X=cd",
-                         this->GetCookies(cs.get(), url_bcd));
-  this->MatchCookieLines("c=3; d=4; X=cd", this->GetCookies(cs.get(), url_cd));
+                         this->GetCookies(cs, url_bcd));
+  this->MatchCookieLines("c=3; d=4; X=cd", this->GetCookies(cs, url_cd));
 }
 
 // Test that setting a cookie which specifies an invalid domain has
 // no side-effect. An invalid domain in this context is one which does
 // not match the originating domain.
 TYPED_TEST_P(CookieStoreTest, InvalidDomainTest) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url_foobar("http://foo.bar.com");
 
   // More specific sub-domain than allowed.
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "a=1; domain=.yo.foo.bar.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "a=1; domain=.yo.foo.bar.com"));
 
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_foobar, "b=2; domain=.foo.com"));
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "c=3; domain=.bar.foo.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "b=2; domain=.foo.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "c=3; domain=.bar.foo.com"));
 
   // Different TLD, but the rest is a substring.
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "d=4; domain=.foo.bar.com.net"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "d=4; domain=.foo.bar.com.net"));
 
   // A substring that isn't really a parent domain.
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_foobar, "e=5; domain=ar.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "e=5; domain=ar.com"));
 
   // Completely invalid domains:
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_foobar, "f=6; domain=."));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_foobar, "g=7; domain=/"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "f=6; domain=."));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "g=7; domain=/"));
   EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "h=8; domain=http://foo.bar.com"));
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "i=9; domain=..foo.bar.com"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_foobar, "j=10; domain=..bar.com"));
+      this->SetCookie(cs, url_foobar, "h=8; domain=http://foo.bar.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "i=9; domain=..foo.bar.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "j=10; domain=..bar.com"));
 
   // Make sure there isn't something quirky in the domain canonicalization
   // that supports full URL semantics.
   EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "k=11; domain=.foo.bar.com?blah"));
+      this->SetCookie(cs, url_foobar, "k=11; domain=.foo.bar.com?blah"));
   EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "l=12; domain=.foo.bar.com/blah"));
+      this->SetCookie(cs, url_foobar, "l=12; domain=.foo.bar.com/blah"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "m=13; domain=.foo.bar.com:80"));
+  EXPECT_FALSE(this->SetCookie(cs, url_foobar, "n=14; domain=.foo.bar.com:"));
   EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "m=13; domain=.foo.bar.com:80"));
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "n=14; domain=.foo.bar.com:"));
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foobar, "o=15; domain=.foo.bar.com#sup"));
+      this->SetCookie(cs, url_foobar, "o=15; domain=.foo.bar.com#sup"));
 
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url_foobar));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url_foobar));
 }
 
 // Make sure the cookie code hasn't gotten its subdomain string handling
 // reversed, missed a suffix check, etc.  It's important here that the two
 // hosts below have the same domain + registry.
 TYPED_TEST_P(CookieStoreTest, InvalidDomainSameDomainAndRegistry) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url_foocom("http://foo.com.com");
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), url_foocom, "a=1; domain=.foo.com.com.com"));
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url_foocom));
+  EXPECT_FALSE(this->SetCookie(cs, url_foocom, "a=1; domain=.foo.com.com.com"));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url_foocom));
 }
 
 // Setting the domain without a dot on a parent domain should add a domain
 // cookie.
 TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotParentDomain) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url_hosted("http://manage.hosted.filefront.com");
   GURL url_filefront("http://www.filefront.com");
-  EXPECT_TRUE(
-      this->SetCookie(cs.get(), url_hosted, "sawAd=1; domain=filefront.com"));
-  this->MatchCookieLines("sawAd=1", this->GetCookies(cs.get(), url_hosted));
-  this->MatchCookieLines("sawAd=1", this->GetCookies(cs.get(), url_filefront));
+  EXPECT_TRUE(this->SetCookie(cs, url_hosted, "sawAd=1; domain=filefront.com"));
+  this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_hosted));
+  this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_filefront));
 }
 
 // Even when the specified domain matches the domain of the URL exactly, treat
 // it as setting a domain cookie.
 TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotSameDomain) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://www.google.com");
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1; domain=www.google.com"));
-  this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=www.google.com"));
+  this->MatchCookieLines("a=1", this->GetCookies(cs, url));
   this->MatchCookieLines(
-      "a=1", this->GetCookies(cs.get(), GURL("http://sub.www.google.com")));
+      "a=1", this->GetCookies(cs, GURL("http://sub.www.google.com")));
   this->MatchCookieLines(
-      std::string(),
-      this->GetCookies(cs.get(), GURL("http://something-else.com")));
+      std::string(), this->GetCookies(cs, GURL("http://something-else.com")));
 }
 
 // Test that the domain specified in cookie string is treated case-insensitive
 TYPED_TEST_P(CookieStoreTest, CaseInsensitiveDomainTest) {
-    scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://www.google.com");
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1; domain=.GOOGLE.COM"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "b=2; domain=.wWw.gOOgLE.coM"));
-  this->MatchCookieLines("a=1; b=2", this->GetCookies(cs.get(), url));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=.GOOGLE.COM"));
+  EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.wWw.gOOgLE.coM"));
+  this->MatchCookieLines("a=1; b=2", this->GetCookies(cs, url));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestIpAddress) {
   GURL url_ip("http://1.2.3.4/weee");
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_ip, kValidCookieLine));
-  this->MatchCookieLines("A=B", this->GetCookies(cs.get(), url_ip));
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_TRUE(this->SetCookie(cs, url_ip, kValidCookieLine));
+  this->MatchCookieLines("A=B", this->GetCookies(cs, url_ip));
 }
 
 // IP addresses should not be able to set domain cookies.
 TYPED_TEST_P(CookieStoreTest, TestIpAddressNoDomainCookies) {
   GURL url_ip("http://1.2.3.4/weee");
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_ip, "b=2; domain=.1.2.3.4"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_ip, "c=3; domain=.3.4"));
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url_ip));
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=.1.2.3.4"));
+  EXPECT_FALSE(this->SetCookie(cs, url_ip, "c=3; domain=.3.4"));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url_ip));
   // It should be allowed to set a cookie if domain= matches the IP address
   // exactly.  This matches IE/Firefox, even though it seems a bit wrong.
-  EXPECT_FALSE(this->SetCookie(cs.get(), url_ip, "b=2; domain=1.2.3.3"));
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url_ip));
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_ip, "b=2; domain=1.2.3.4"));
-  this->MatchCookieLines("b=2", this->GetCookies(cs.get(), url_ip));
+  EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.3"));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url_ip));
+  EXPECT_TRUE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.4"));
+  this->MatchCookieLines("b=2", this->GetCookies(cs, url_ip));
 }
 
 // Test a TLD setting cookies on itself.
 TYPED_TEST_P(CookieStoreTest, TestTLD) {
   if (!TypeParam::supports_non_dotted_domains)
     return;
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://com/");
 
   // Allow setting on "com", (but only as a host cookie).
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1"));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
   // Domain cookies can't be set.
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com"));
   // Exact matches between the domain attribute and the host are treated as
   // host cookies, not domain cookies.
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "c=3; domain=com"));
+  EXPECT_TRUE(this->SetCookie(cs, url, "c=3; domain=com"));
 
-  this->MatchCookieLines("a=1; c=3", this->GetCookies(cs.get(), url));
+  this->MatchCookieLines("a=1; c=3", this->GetCookies(cs, url));
 
   // Make sure they don't show up for a normal .com, they should be host,
   // domain, cookies.
   this->MatchCookieLines(
       std::string(),
-      this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.com/")));
+      this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
   this->MatchCookieLines(std::string(),
-                         this->GetCookies(cs.get(), GURL("http://.com/")));
+                         this->GetCookies(cs, GURL("http://.com/")));
 }
 
 // http://com. should be treated the same as http://com.
 TYPED_TEST_P(CookieStoreTest, TestTLDWithTerminalDot) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://com./index.html");
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=.com."));
-  this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+  EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com."));
+  this->MatchCookieLines("a=1", this->GetCookies(cs, url));
   this->MatchCookieLines(
       std::string(),
-      this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.com./")));
+      this->GetCookies(cs, GURL("http://hopefully-no-cookies.com./")));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnUnknownTLD) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://a.b");
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "a=1; domain=.b"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=b"));
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url));
+  EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.b"));
+  EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=b"));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnKnownTLD) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://google.com");
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "a=1; domain=.com"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=com"));
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url));
+  EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.com"));
+  EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=com"));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnKnownDottedTLD) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://google.co.uk");
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "a=1; domain=.co.uk"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=.uk"));
-  this->MatchCookieLines(std::string(), this->GetCookies(cs.get(), url));
+  EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.co.uk"));
+  EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.uk"));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
   this->MatchCookieLines(
-      std::string(),
-      this->GetCookies(cs.get(), GURL("http://something-else.co.uk")));
+      std::string(), this->GetCookies(cs, GURL("http://something-else.co.uk")));
   this->MatchCookieLines(
-      std::string(),
-      this->GetCookies(cs.get(), GURL("http://something-else.uk")));
+      std::string(), this->GetCookies(cs, GURL("http://something-else.uk")));
 }
 
 // Intranet URLs should only be able to set host cookies.
 TYPED_TEST_P(CookieStoreTest, TestSettingCookiesOnUnknownTLD) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://b");
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1"));
-  EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=.b"));
-  this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+  EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.b"));
+  this->MatchCookieLines("a=1", this->GetCookies(cs, url));
 }
 
 // Exact matches between the domain attribute and an intranet host are
@@ -755,64 +738,59 @@
 TYPED_TEST_P(CookieStoreTest, TestSettingCookiesWithHostDomainOnUnknownTLD) {
   if (!TypeParam::supports_non_dotted_domains)
     return;
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://b");
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1; domain=b"));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=b"));
 
-  this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+  this->MatchCookieLines("a=1", this->GetCookies(cs, url));
 
   // Make sure it doesn't show up for an intranet subdomain, it should be
   // a host, not domain, cookie.
   this->MatchCookieLines(
       std::string(),
-      this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.b/")));
+      this->GetCookies(cs, GURL("http://hopefully-no-cookies.b/")));
   this->MatchCookieLines(std::string(),
-                         this->GetCookies(cs.get(), GURL("http://.b/")));
+                         this->GetCookies(cs, GURL("http://.b/")));
 }
 
 // Test reading/writing cookies when the domain ends with a period,
 // as in "www.google.com."
 TYPED_TEST_P(CookieStoreTest, TestHostEndsWithDot) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url("http://www.google.com");
   GURL url_with_dot("http://www.google.com.");
-  EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1"));
-  this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+  EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+  this->MatchCookieLines("a=1", this->GetCookies(cs, url));
 
   // Do not share cookie space with the dot version of domain.
   // Note: this is not what FireFox does, but it _is_ what IE+Safari do.
   if (TypeParam::preserves_trailing_dots) {
-    EXPECT_FALSE(
-        this->SetCookie(cs.get(), url, "b=2; domain=.www.google.com."));
-    this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
-    EXPECT_TRUE(
-        this->SetCookie(cs.get(), url_with_dot, "b=2; domain=.google.com."));
-    this->MatchCookieLines("b=2", this->GetCookies(cs.get(), url_with_dot));
+    EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.www.google.com."));
+    this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+    EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com."));
+    this->MatchCookieLines("b=2", this->GetCookies(cs, url_with_dot));
   } else {
-    EXPECT_TRUE(
-        this->SetCookie(cs.get(), url, "b=2; domain=.www.google.com."));
-    this->MatchCookieLines("a=1 b=2", this->GetCookies(cs.get(), url));
+    EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.www.google.com."));
+    this->MatchCookieLines("a=1 b=2", this->GetCookies(cs, url));
     // Setting this cookie should fail, since the trailing dot on the domain
     // isn't preserved, and then the domain mismatches the URL.
-    EXPECT_FALSE(
-        this->SetCookie(cs.get(), url_with_dot, "b=2; domain=.google.com."));
+    EXPECT_FALSE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com."));
   }
 
   // Make sure there weren't any side effects.
   this->MatchCookieLines(
       std::string(),
-      this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.com/")));
+      this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
   this->MatchCookieLines(std::string(),
-                         this->GetCookies(cs.get(), GURL("http://.com/")));
+                         this->GetCookies(cs, GURL("http://.com/")));
 }
 
 TYPED_TEST_P(CookieStoreTest, InvalidScheme) {
   if (!TypeParam::filters_schemes)
     return;
 
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_FALSE(
-      this->SetCookie(cs.get(), this->ftp_google_.url(), kValidCookieLine));
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_FALSE(this->SetCookie(cs, this->ftp_google_.url(), kValidCookieLine));
 }
 
 TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) {
@@ -822,42 +800,38 @@
   const std::string kValidDomainCookieLine =
       this->http_www_google_.Format("A=B; path=/; domain=%D");
 
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               kValidDomainCookieLine));
   this->MatchCookieLines(std::string(),
-                         this->GetCookies(cs.get(), this->ftp_google_.url()));
-  EXPECT_EQ(0U, this->GetCookieListWithOptions(
-                        cs.get(), this->ftp_google_.url(), CookieOptions())
+                         this->GetCookies(cs, this->ftp_google_.url()));
+  EXPECT_EQ(0U, this->GetCookieListWithOptions(cs, this->ftp_google_.url(),
+                                               CookieOptions())
                     .size());
 }
 
 TYPED_TEST_P(CookieStoreTest, PathTest) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   std::string url("http://www.google.izzle");
-  EXPECT_TRUE(this->SetCookie(cs.get(), GURL(url), "A=B; path=/wee"));
-  this->MatchCookieLines("A=B", this->GetCookies(cs.get(), GURL(url + "/wee")));
-  this->MatchCookieLines("A=B",
-                         this->GetCookies(cs.get(), GURL(url + "/wee/")));
-  this->MatchCookieLines("A=B",
-                         this->GetCookies(cs.get(), GURL(url + "/wee/war")));
+  EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=B; path=/wee"));
+  this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee")));
+  this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/")));
+  this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/war")));
   this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), GURL(url + "/wee/war/more/more")));
+      "A=B", this->GetCookies(cs, GURL(url + "/wee/war/more/more")));
   if (!TypeParam::has_path_prefix_bug)
     this->MatchCookieLines(std::string(),
-                           this->GetCookies(cs.get(), GURL(url + "/weehee")));
-  this->MatchCookieLines(std::string(),
-                         this->GetCookies(cs.get(), GURL(url + "/")));
+                           this->GetCookies(cs, GURL(url + "/weehee")));
+  this->MatchCookieLines(std::string(), this->GetCookies(cs, GURL(url + "/")));
 
   // If we add a 0 length path, it should default to /
-  EXPECT_TRUE(this->SetCookie(cs.get(), GURL(url), "A=C; path="));
-  this->MatchCookieLines("A=B; A=C",
-                         this->GetCookies(cs.get(), GURL(url + "/wee")));
-  this->MatchCookieLines("A=C", this->GetCookies(cs.get(), GURL(url + "/")));
+  EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=C; path="));
+  this->MatchCookieLines("A=B; A=C", this->GetCookies(cs, GURL(url + "/wee")));
+  this->MatchCookieLines("A=C", this->GetCookies(cs, GURL(url + "/")));
 }
 
 TYPED_TEST_P(CookieStoreTest, EmptyExpires) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   CookieOptions options;
   if (!TypeParam::supports_http_only)
     options.set_include_httponly();
@@ -866,171 +840,168 @@
       "ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
   std::string cookie_line = "ACSTM=20130308043820420042";
 
-  this->SetCookieWithOptions(cs.get(), url, set_cookie_line, options);
+  this->SetCookieWithOptions(cs, url, set_cookie_line, options);
   this->MatchCookieLines(cookie_line,
-                         this->GetCookiesWithOptions(cs.get(), url, options));
+                         this->GetCookiesWithOptions(cs, url, options));
 
   options.set_server_time(base::Time::Now() - base::TimeDelta::FromHours(1));
-  this->SetCookieWithOptions(cs.get(), url, set_cookie_line, options);
+  this->SetCookieWithOptions(cs, url, set_cookie_line, options);
   this->MatchCookieLines(cookie_line,
-                         this->GetCookiesWithOptions(cs.get(), url, options));
+                         this->GetCookiesWithOptions(cs, url, options));
 
   options.set_server_time(base::Time::Now() + base::TimeDelta::FromHours(1));
-  this->SetCookieWithOptions(cs.get(), url, set_cookie_line, options);
+  this->SetCookieWithOptions(cs, url, set_cookie_line, options);
   this->MatchCookieLines(cookie_line,
-                         this->GetCookiesWithOptions(cs.get(), url, options));
+                         this->GetCookiesWithOptions(cs, url, options));
 }
 
 TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) {
   if (!TypeParam::supports_http_only)
     return;
 
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   CookieOptions options;
   options.set_include_httponly();
 
   // Create a httponly cookie.
-  EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_google_.url(),
                                          "A=B; httponly", options));
 
   // Check httponly read protection.
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
-  this->MatchCookieLines(
-      "A=B", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
-                                         options));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
+  this->MatchCookieLines("A=B", this->GetCookiesWithOptions(
+                                    cs, this->http_www_google_.url(), options));
 
   // Check httponly overwrite protection.
-  EXPECT_FALSE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=C"));
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
-  this->MatchCookieLines(
-      "A=B", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
-                                         options));
-  EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+  EXPECT_FALSE(this->SetCookie(cs, this->http_www_google_.url(), "A=C"));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
+  this->MatchCookieLines("A=B", this->GetCookiesWithOptions(
+                                    cs, this->http_www_google_.url(), options));
+  EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_google_.url(),
                                          "A=C", options));
-  this->MatchCookieLines(
-      "A=C", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=C",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Check httponly create protection.
   EXPECT_FALSE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "B=A; httponly"));
-  this->MatchCookieLines(
-      "A=C", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
-                                         options));
-  EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+      this->SetCookie(cs, this->http_www_google_.url(), "B=A; httponly"));
+  this->MatchCookieLines("A=C", this->GetCookiesWithOptions(
+                                    cs, this->http_www_google_.url(), options));
+  EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_google_.url(),
                                          "B=A; httponly", options));
-  this->MatchCookieLines("A=C; B=A",
-                         this->GetCookiesWithOptions(
-                             cs.get(), this->http_www_google_.url(), options));
   this->MatchCookieLines(
-      "A=C", this->GetCookies(cs.get(), this->http_www_google_.url()));
+      "A=C; B=A",
+      this->GetCookiesWithOptions(cs, this->http_www_google_.url(), options));
+  this->MatchCookieLines("A=C",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   // Create a session cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              kValidCookieLine));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), kValidCookieLine));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Delete it via Max-Age.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               std::string(kValidCookieLine) + "; max-age=0"));
-  this->MatchCookieLineWithTimeout(cs.get(), this->http_www_google_.url(),
+  this->MatchCookieLineWithTimeout(cs, this->http_www_google_.url(),
                                    std::string());
 
   // Create a session cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              kValidCookieLine));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), kValidCookieLine));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Delete it via Expires.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               std::string(kValidCookieLine) +
                                   "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Create a persistent cookie.
   EXPECT_TRUE(this->SetCookie(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
 
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Delete it via Max-Age.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               std::string(kValidCookieLine) + "; max-age=0"));
-  this->MatchCookieLineWithTimeout(cs.get(), this->http_www_google_.url(),
+  this->MatchCookieLineWithTimeout(cs, this->http_www_google_.url(),
                                    std::string());
 
   // Create a persistent cookie.
   EXPECT_TRUE(this->SetCookie(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Delete it via Expires.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               std::string(kValidCookieLine) +
                                   "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Create a persistent cookie.
   EXPECT_TRUE(this->SetCookie(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Check that it is not deleted with significant enough clock skew.
   base::Time server_time;
   EXPECT_TRUE(base::Time::FromString("Sun, 17-Apr-1977 22:50:13 GMT",
                                      &server_time));
   EXPECT_TRUE(this->SetCookieWithServerTime(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
       server_time));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Create a persistent cookie.
   EXPECT_TRUE(this->SetCookie(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Delete it via Expires, with a unix epoch of 0.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               std::string(kValidCookieLine) +
                                   "; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestDeleteAll) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   // Set a session cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              kValidCookieLine));
-  EXPECT_EQ("A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), kValidCookieLine));
+  EXPECT_EQ("A=B", this->GetCookies(cs, this->http_www_google_.url()));
 
   // Set a persistent cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               "C=D; expires=Mon, 18-Apr-22 22:50:13 GMT"));
 
-  EXPECT_EQ(2u, this->GetAllCookies(cs.get()).size());
+  EXPECT_EQ(2u, this->GetAllCookies(cs).size());
 
   // Delete both, and make sure it works
-  EXPECT_EQ(2, this->DeleteAll(cs.get()));
-  EXPECT_EQ(0u, this->GetAllCookies(cs.get()).size());
+  EXPECT_EQ(2, this->DeleteAll(cs));
+  EXPECT_EQ(0u, this->GetAllCookies(cs).size());
 }
 
 TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetween) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   const base::Time last_month = base::Time::Now() -
                                 base::TimeDelta::FromDays(30);
   const base::Time last_minute = base::Time::Now() -
@@ -1041,90 +1012,86 @@
                                 base::TimeDelta::FromDays(30);
 
   // Add a cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "A=B"));
   // Check that the cookie is in the store.
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Remove cookies in empty intervals.
-  EXPECT_EQ(0, this->DeleteCreatedBetween(cs.get(), last_month, last_minute));
-  EXPECT_EQ(0, this->DeleteCreatedBetween(cs.get(), next_minute, next_month));
+  EXPECT_EQ(0, this->DeleteCreatedBetween(cs, last_month, last_minute));
+  EXPECT_EQ(0, this->DeleteCreatedBetween(cs, next_minute, next_month));
   // Check that the cookie is still there.
-  this->MatchCookieLines(
-      "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Remove the cookie with an interval defined by two dates.
-  EXPECT_EQ(1, this->DeleteCreatedBetween(cs.get(), last_minute, next_minute));
+  EXPECT_EQ(1, this->DeleteCreatedBetween(cs, last_minute, next_minute));
   // Check that the cookie disappeared.
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Add another cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "C=D"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "C=D"));
   // Check that the cookie is in the store.
-  this->MatchCookieLines(
-      "C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("C=D",
+                         this->GetCookies(cs, this->http_www_google_.url()));
 
   // Remove the cookie with a null ending time.
-  EXPECT_EQ(1, this->DeleteCreatedBetween(cs.get(), last_minute, base::Time()));
+  EXPECT_EQ(1, this->DeleteCreatedBetween(cs, last_minute, base::Time()));
   // Check that the cookie disappeared.
-  this->MatchCookieLines(
-      std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetweenForHost) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   GURL url_not_google("http://www.notgoogle.com");
   base::Time now = base::Time::Now();
 
   // These 3 cookies match the time range and host.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "C=D"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "Y=Z"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "A=B"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "C=D"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "Y=Z"));
 
   // This cookie does not match host.
-  EXPECT_TRUE(this->SetCookie(cs.get(), url_not_google, "E=F"));
+  EXPECT_TRUE(this->SetCookie(cs, url_not_google, "E=F"));
 
   // Delete cookies.
-  EXPECT_EQ(
-      3,  // Deletes A=B, C=D, Y=Z
-      this->DeleteAllCreatedBetweenForHost(cs.get(), now, base::Time::Max(),
-                                           this->http_www_google_.url()));
+  EXPECT_EQ(3,  // Deletes A=B, C=D, Y=Z
+            this->DeleteAllCreatedBetweenForHost(cs, now, base::Time::Max(),
+                                                 this->http_www_google_.url()));
 }
 
 TYPED_TEST_P(CookieStoreTest, TestSecure) {
-    scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
-    EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
-    this->MatchCookieLines(
-        "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
-    this->MatchCookieLines(
-        "A=B", this->GetCookies(cs.get(), this->https_www_google_.url()));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(), "A=B"));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->https_www_google_.url()));
 
-    EXPECT_TRUE(this->SetCookie(cs.get(), this->https_www_google_.url(),
-                                "A=B; secure"));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->https_www_google_.url(), "A=B; secure"));
   // The secure should overwrite the non-secure.
-    this->MatchCookieLines(
-        std::string(),
-        this->GetCookies(cs.get(), this->http_www_google_.url()));
-    this->MatchCookieLines(
-        "A=B", this->GetCookies(cs.get(), this->https_www_google_.url()));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->https_www_google_.url()));
 
-    EXPECT_TRUE(this->SetCookie(cs.get(), this->https_www_google_.url(),
-                                "D=E; secure"));
-    this->MatchCookieLines(
-        std::string(),
-        this->GetCookies(cs.get(), this->http_www_google_.url()));
-    this->MatchCookieLines(
-        "A=B; D=E", this->GetCookies(cs.get(), this->https_www_google_.url()));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->https_www_google_.url(), "D=E; secure"));
+  this->MatchCookieLines(std::string(),
+                         this->GetCookies(cs, this->http_www_google_.url()));
+  this->MatchCookieLines("A=B; D=E",
+                         this->GetCookies(cs, this->https_www_google_.url()));
 
-    EXPECT_TRUE(
-        this->SetCookie(cs.get(), this->https_www_google_.url(), "A=B"));
+  EXPECT_TRUE(this->SetCookie(cs, this->https_www_google_.url(), "A=B"));
   // The non-secure should overwrite the secure.
-    this->MatchCookieLines(
-        "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
-    this->MatchCookieLines(
-        "D=E; A=B", this->GetCookies(cs.get(), this->https_www_google_.url()));
+  this->MatchCookieLines("A=B",
+                         this->GetCookies(cs, this->http_www_google_.url()));
+  this->MatchCookieLines("D=E; A=B",
+                         this->GetCookies(cs, this->https_www_google_.url()));
 }
 
 static const int kLastAccessThresholdMilliseconds = 200;
@@ -1133,17 +1100,17 @@
 TYPED_TEST_P(CookieStoreTest, NetUtilCookieTest) {
   const GURL test_url("http://mojo.jojo.google.izzle/");
 
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
-  EXPECT_TRUE(this->SetCookie(cs.get(), test_url, "foo=bar"));
-  std::string value = this->GetCookies(cs.get(), test_url);
+  EXPECT_TRUE(this->SetCookie(cs, test_url, "foo=bar"));
+  std::string value = this->GetCookies(cs, test_url);
   this->MatchCookieLines("foo=bar", value);
 
   // test that we can retrieve all cookies:
-  EXPECT_TRUE(this->SetCookie(cs.get(), test_url, "x=1"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), test_url, "y=2"));
+  EXPECT_TRUE(this->SetCookie(cs, test_url, "x=1"));
+  EXPECT_TRUE(this->SetCookie(cs, test_url, "y=2"));
 
-  std::string result = this->GetCookies(cs.get(), test_url);
+  std::string result = this->GetCookies(cs, test_url);
   EXPECT_FALSE(result.empty());
   EXPECT_NE(result.find("x=1"), std::string::npos) << result;
   EXPECT_NE(result.find("y=2"), std::string::npos) << result;
@@ -1152,17 +1119,15 @@
 TYPED_TEST_P(CookieStoreTest, OverwritePersistentCookie) {
   GURL url_google("http://www.google.com/");
   GURL url_chromium("http://chromium.org");
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   // Insert a cookie "a" for path "/path1"
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              url_google,
+  EXPECT_TRUE(this->SetCookie(cs, url_google,
                               "a=val1; path=/path1; "
                               "expires=Mon, 18-Apr-22 22:50:13 GMT"));
 
   // Insert a cookie "b" for path "/path1"
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              url_google,
+  EXPECT_TRUE(this->SetCookie(cs, url_google,
                               "b=val1; path=/path1; "
                               "expires=Mon, 18-Apr-22 22:50:14 GMT"));
 
@@ -1170,80 +1135,72 @@
   // overwrite the non-http-only version.
   CookieOptions allow_httponly;
   allow_httponly.set_include_httponly();
-  EXPECT_TRUE(this->SetCookieWithOptions(cs.get(),
-                                         url_google,
+  EXPECT_TRUE(this->SetCookieWithOptions(cs, url_google,
                                          "b=val2; path=/path1; httponly; "
                                          "expires=Mon, 18-Apr-22 22:50:14 GMT",
                                          allow_httponly));
 
   // Insert a cookie "a" for path "/path1". This should overwrite.
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              url_google,
+  EXPECT_TRUE(this->SetCookie(cs, url_google,
                               "a=val33; path=/path1; "
                               "expires=Mon, 18-Apr-22 22:50:14 GMT"));
 
   // Insert a cookie "a" for path "/path2". This should NOT overwrite
   // cookie "a", since the path is different.
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              url_google,
+  EXPECT_TRUE(this->SetCookie(cs, url_google,
                               "a=val9; path=/path2; "
                               "expires=Mon, 18-Apr-22 22:50:14 GMT"));
 
   // Insert a cookie "a" for path "/path1", but this time for "chromium.org".
   // Although the name and path match, the hostnames do not, so shouldn't
   // overwrite.
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              url_chromium,
+  EXPECT_TRUE(this->SetCookie(cs, url_chromium,
                               "a=val99; path=/path1; "
                               "expires=Mon, 18-Apr-22 22:50:14 GMT"));
 
   if (TypeParam::supports_http_only) {
     this->MatchCookieLines(
-        "a=val33",
-        this->GetCookies(cs.get(), GURL("http://www.google.com/path1")));
+        "a=val33", this->GetCookies(cs, GURL("http://www.google.com/path1")));
   } else {
     this->MatchCookieLines(
         "a=val33; b=val2",
-        this->GetCookies(cs.get(), GURL("http://www.google.com/path1")));
+        this->GetCookies(cs, GURL("http://www.google.com/path1")));
   }
   this->MatchCookieLines(
-      "a=val9",
-      this->GetCookies(cs.get(), GURL("http://www.google.com/path2")));
+      "a=val9", this->GetCookies(cs, GURL("http://www.google.com/path2")));
   this->MatchCookieLines(
-      "a=val99", this->GetCookies(cs.get(), GURL("http://chromium.org/path1")));
+      "a=val99", this->GetCookies(cs, GURL("http://chromium.org/path1")));
 }
 
 TYPED_TEST_P(CookieStoreTest, CookieOrdering) {
   // Put a random set of cookies into a store and make sure they're returned in
   // the right order.
   // Cookies should be sorted by path length and creation time, as per RFC6265.
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
-  EXPECT_TRUE(this->SetCookie(
-      cs.get(), GURL("http://d.c.b.a.google.com/aa/x.html"), "c=1"));
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              GURL("http://b.a.google.com/aa/bb/cc/x.html"),
+  CookieStore* cs = this->GetCookieStore();
+  EXPECT_TRUE(
+      this->SetCookie(cs, GURL("http://d.c.b.a.google.com/aa/x.html"), "c=1"));
+  EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"),
                               "d=1; domain=b.a.google.com"));
   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
       TypeParam::creation_time_granularity_in_ms));
-  EXPECT_TRUE(this->SetCookie(cs.get(),
-                              GURL("http://b.a.google.com/aa/bb/cc/x.html"),
+  EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"),
                               "a=4; domain=b.a.google.com"));
   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
       TypeParam::creation_time_granularity_in_ms));
-  EXPECT_TRUE(this->SetCookie(cs.get(),
+  EXPECT_TRUE(this->SetCookie(cs,
                               GURL("http://c.b.a.google.com/aa/bb/cc/x.html"),
                               "e=1; domain=c.b.a.google.com"));
   EXPECT_TRUE(this->SetCookie(
-      cs.get(), GURL("http://d.c.b.a.google.com/aa/bb/x.html"), "b=1"));
-  EXPECT_TRUE(this->SetCookie(
-      cs.get(), GURL("http://news.bbc.co.uk/midpath/x.html"), "g=10"));
-  EXPECT_EQ("d=1; a=4; e=1; b=1; c=1",
-            this->GetCookies(cs.get(),
-                             GURL("http://d.c.b.a.google.com/aa/bb/cc/dd")));
+      cs, GURL("http://d.c.b.a.google.com/aa/bb/x.html"), "b=1"));
+  EXPECT_TRUE(this->SetCookie(cs, GURL("http://news.bbc.co.uk/midpath/x.html"),
+                              "g=10"));
+  EXPECT_EQ(
+      "d=1; a=4; e=1; b=1; c=1",
+      this->GetCookies(cs, GURL("http://d.c.b.a.google.com/aa/bb/cc/dd")));
 
   CookieOptions options;
   CookieList cookies = this->GetCookieListWithOptions(
-      cs.get(), GURL("http://d.c.b.a.google.com/aa/bb/cc/dd"), options);
+      cs, GURL("http://d.c.b.a.google.com/aa/bb/cc/dd"), options);
   CookieList::const_iterator it = cookies.begin();
 
   ASSERT_TRUE(it != cookies.end());
@@ -1267,16 +1224,15 @@
 // Check that GetAllCookiesAsync returns cookies from multiple domains, in the
 // correct order.
 TYPED_TEST_P(CookieStoreTest, GetAllCookiesAsync) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B; path=/a"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_foo_com_.url(), "C=D;/"));
-  EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_bar_com_.url(), "E=F; path=/bar"));
+      this->SetCookie(cs, this->http_www_google_.url(), "A=B; path=/a"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_foo_com_.url(), "C=D;/"));
+  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "E=F; path=/bar"));
 
   // Check cookies for url.
-  CookieList cookies = this->GetAllCookies(cs.get());
+  CookieList cookies = this->GetAllCookies(cs);
   CookieList::const_iterator it = cookies.begin();
 
   ASSERT_TRUE(it != cookies.end());
@@ -1301,25 +1257,24 @@
 }
 
 TYPED_TEST_P(CookieStoreTest, DeleteCookieAsync) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "A=A1; path=/"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              "A=A2; path=/foo"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              "A=A3; path=/bar"));
+      this->SetCookie(cs, this->http_www_google_.url(), "A=A1; path=/"));
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "B=B1; path=/"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              "B=B2; path=/foo"));
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
-                              "B=B3; path=/bar"));
+      this->SetCookie(cs, this->http_www_google_.url(), "A=A2; path=/foo"));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), "A=A3; path=/bar"));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), "B=B1; path=/"));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), "B=B2; path=/foo"));
+  EXPECT_TRUE(
+      this->SetCookie(cs, this->http_www_google_.url(), "B=B3; path=/bar"));
 
-  this->DeleteCookie(cs.get(), this->http_www_google_.AppendPath("foo/bar"),
-                     "A");
+  this->DeleteCookie(cs, this->http_www_google_.AppendPath("foo/bar"), "A");
 
-  CookieList cookies = this->GetAllCookies(cs.get());
+  CookieList cookies = this->GetAllCookies(cs);
   size_t expected_size = 4;
   EXPECT_EQ(expected_size, cookies.size());
   for (const auto& cookie : cookies) {
@@ -1329,63 +1284,63 @@
 }
 
 TYPED_TEST_P(CookieStoreTest, DeleteCanonicalCookieAsync) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
 
   // Set two cookies with the same name, and make sure both are set.
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B;Path=/foo"));
+      this->SetCookie(cs, this->http_www_google_.url(), "A=B;Path=/foo"));
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "A=C;Path=/bar"));
-  EXPECT_EQ(2u, this->GetAllCookies(cs.get()).size());
-  EXPECT_EQ("A=B", this->GetCookies(cs.get(), this->www_google_foo_.url()));
-  EXPECT_EQ("A=C", this->GetCookies(cs.get(), this->www_google_bar_.url()));
+      this->SetCookie(cs, this->http_www_google_.url(), "A=C;Path=/bar"));
+  EXPECT_EQ(2u, this->GetAllCookies(cs).size());
+  EXPECT_EQ("A=B", this->GetCookies(cs, this->www_google_foo_.url()));
+  EXPECT_EQ("A=C", this->GetCookies(cs, this->www_google_bar_.url()));
 
   // Delete the "/foo" cookie, and make sure only it was deleted.
   CookieList cookies = this->GetCookieListWithOptions(
-      cs.get(), this->www_google_foo_.url(), CookieOptions());
+      cs, this->www_google_foo_.url(), CookieOptions());
   ASSERT_EQ(1u, cookies.size());
-  EXPECT_EQ(1, this->DeleteCanonicalCookie(cs.get(), cookies[0]));
-  EXPECT_EQ(1u, this->GetAllCookies(cs.get()).size());
-  EXPECT_EQ("", this->GetCookies(cs.get(), this->www_google_foo_.url()));
-  EXPECT_EQ("A=C", this->GetCookies(cs.get(), this->www_google_bar_.url()));
+  EXPECT_EQ(1, this->DeleteCanonicalCookie(cs, cookies[0]));
+  EXPECT_EQ(1u, this->GetAllCookies(cs).size());
+  EXPECT_EQ("", this->GetCookies(cs, this->www_google_foo_.url()));
+  EXPECT_EQ("A=C", this->GetCookies(cs, this->www_google_bar_.url()));
 
   // Deleting the "/foo" cookie again should fail.
-  EXPECT_EQ(0, this->DeleteCanonicalCookie(cs.get(), cookies[0]));
+  EXPECT_EQ(0, this->DeleteCanonicalCookie(cs, cookies[0]));
 
   // Try to delete the "/bar" cookie after overwriting it with a new cookie.
-  cookies = this->GetCookieListWithOptions(
-      cs.get(), this->www_google_bar_.url(), CookieOptions());
+  cookies = this->GetCookieListWithOptions(cs, this->www_google_bar_.url(),
+                                           CookieOptions());
   ASSERT_EQ(1u, cookies.size());
   EXPECT_TRUE(
-      this->SetCookie(cs.get(), this->http_www_google_.url(), "A=D;Path=/bar"));
-  EXPECT_EQ(0, this->DeleteCanonicalCookie(cs.get(), cookies[0]));
-  EXPECT_EQ(1u, this->GetAllCookies(cs.get()).size());
-  EXPECT_EQ("A=D", this->GetCookies(cs.get(), this->www_google_bar_.url()));
+      this->SetCookie(cs, this->http_www_google_.url(), "A=D;Path=/bar"));
+  EXPECT_EQ(0, this->DeleteCanonicalCookie(cs, cookies[0]));
+  EXPECT_EQ(1u, this->GetAllCookies(cs).size());
+  EXPECT_EQ("A=D", this->GetCookies(cs, this->www_google_bar_.url()));
 
   // Delete the new "/bar" cookie.
-  cookies = this->GetCookieListWithOptions(
-      cs.get(), this->www_google_bar_.url(), CookieOptions());
+  cookies = this->GetCookieListWithOptions(cs, this->www_google_bar_.url(),
+                                           CookieOptions());
   ASSERT_EQ(1u, cookies.size());
-  EXPECT_EQ(1, this->DeleteCanonicalCookie(cs.get(), cookies[0]));
-  EXPECT_EQ(0u, this->GetAllCookies(cs.get()).size());
-  EXPECT_EQ("", this->GetCookies(cs.get(), this->www_google_bar_.url()));
+  EXPECT_EQ(1, this->DeleteCanonicalCookie(cs, cookies[0]));
+  EXPECT_EQ(0u, this->GetAllCookies(cs).size());
+  EXPECT_EQ("", this->GetCookies(cs, this->www_google_bar_.url()));
 }
 
 TYPED_TEST_P(CookieStoreTest, DeleteSessionCookie) {
-  scoped_refptr<CookieStore> cs(this->GetCookieStore());
+  CookieStore* cs = this->GetCookieStore();
   // Create a session cookie and a persistent cookie.
-  EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+  EXPECT_TRUE(this->SetCookie(cs, this->http_www_google_.url(),
                               std::string(kValidCookieLine)));
   EXPECT_TRUE(this->SetCookie(
-      cs.get(), this->http_www_google_.url(),
+      cs, this->http_www_google_.url(),
       this->http_www_google_.Format("C=D; path=/; domain=%D;"
                                     "expires=Mon, 18-Apr-22 22:50:13 GMT")));
-  this->MatchCookieLines(
-      "A=B; C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  this->MatchCookieLines("A=B; C=D",
+                         this->GetCookies(cs, this->http_www_google_.url()));
   // Delete the session cookie.
-  this->DeleteSessionCookies(cs.get());
+  this->DeleteSessionCookies(cs);
   // Check that the session cookie has been deleted but not the persistent one.
-  EXPECT_EQ("C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
+  EXPECT_EQ("C=D", this->GetCookies(cs, this->http_www_google_.url()));
 }
 
 REGISTER_TYPED_TEST_CASE_P(CookieStoreTest,
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 35c832a..35c06cb 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -133,7 +133,7 @@
       quic_migrate_sessions_early(false),
       proxy_delegate(NULL),
       enable_token_binding(false) {
-  quic_supported_versions.push_back(QUIC_VERSION_27);
+  quic_supported_versions.push_back(QUIC_VERSION_29);
 }
 
 HttpNetworkSession::Params::Params(const Params& other) = default;
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc
index e9ab617..3f4f55a 100644
--- a/net/url_request/url_request_context.cc
+++ b/net/url_request/url_request_context.cc
@@ -25,6 +25,7 @@
       proxy_service_(nullptr),
       network_delegate_(nullptr),
       http_user_agent_settings_(nullptr),
+      cookie_store_(nullptr),
       transport_security_state_(nullptr),
       cert_transparency_verifier_(nullptr),
       http_transaction_factory_(nullptr),
@@ -33,8 +34,7 @@
       backoff_manager_(nullptr),
       sdch_manager_(nullptr),
       network_quality_estimator_(nullptr),
-      url_requests_(new std::set<const URLRequest*>) {
-}
+      url_requests_(new std::set<const URLRequest*>) {}
 
 URLRequestContext::~URLRequestContext() {
   AssertNoURLRequests();
@@ -51,7 +51,7 @@
   set_ssl_config_service(other->ssl_config_service_.get());
   set_network_delegate(other->network_delegate_);
   set_http_server_properties(other->http_server_properties_);
-  set_cookie_store(other->cookie_store_.get());
+  set_cookie_store(other->cookie_store_);
   set_transport_security_state(other->transport_security_state_);
   set_cert_transparency_verifier(other->cert_transparency_verifier_);
   set_http_transaction_factory(other->http_transaction_factory_);
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index bb1486e..f51f5cb 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -145,7 +145,7 @@
 
   // Gets the cookie store for this context (may be null, in which case
   // cookies are not stored).
-  CookieStore* cookie_store() const { return cookie_store_.get(); }
+  CookieStore* cookie_store() const { return cookie_store_; }
   void set_cookie_store(CookieStore* cookie_store);
 
   TransportSecurityState* transport_security_state() const {
@@ -237,7 +237,7 @@
   NetworkDelegate* network_delegate_;
   base::WeakPtr<HttpServerProperties> http_server_properties_;
   HttpUserAgentSettings* http_user_agent_settings_;
-  scoped_refptr<CookieStore> cookie_store_;
+  CookieStore* cookie_store_;
   TransportSecurityState* transport_security_state_;
   CTVerifier* cert_transparency_verifier_;
   HttpTransactionFactory* http_transaction_factory_;
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 7066de1..b0e737f 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -257,10 +257,10 @@
 }
 
 void URLRequestContextBuilder::SetCookieAndChannelIdStores(
-      const scoped_refptr<CookieStore>& cookie_store,
-      scoped_ptr<ChannelIDService> channel_id_service) {
+    scoped_ptr<CookieStore> cookie_store,
+    scoped_ptr<ChannelIDService> channel_id_service) {
   DCHECK(cookie_store);
-  cookie_store_ = cookie_store;
+  cookie_store_ = std::move(cookie_store);
   channel_id_service_ = std::move(channel_id_service);
 }
 
@@ -338,10 +338,11 @@
   storage->set_http_auth_handler_factory(std::move(http_auth_handler_factory_));
 
   if (cookie_store_) {
-    storage->set_cookie_store(cookie_store_.get());
+    storage->set_cookie_store(std::move(cookie_store_));
     storage->set_channel_id_service(std::move(channel_id_service_));
   } else {
-    storage->set_cookie_store(new CookieMonster(NULL, NULL));
+    storage->set_cookie_store(
+        make_scoped_ptr(new CookieMonster(nullptr, nullptr)));
     // TODO(mmenke):  This always creates a file thread, even when it ends up
     // not being used.  Consider lazily creating the thread.
     storage->set_channel_id_service(make_scoped_ptr(new ChannelIDService(
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index 3af24fb..affcd4e 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -297,7 +297,7 @@
   // multiple channel-id stores (or used both with and without a channel id
   // store).
   void SetCookieAndChannelIdStores(
-      const scoped_refptr<CookieStore>& cookie_store,
+      scoped_ptr<CookieStore> cookie_store,
       scoped_ptr<ChannelIDService> channel_id_service);
 
   // Sets the task runner used to perform file operations. If not set, one will
@@ -348,7 +348,7 @@
   scoped_ptr<ProxyService> proxy_service_;
   scoped_ptr<NetworkDelegate> network_delegate_;
   scoped_ptr<ProxyDelegate> proxy_delegate_;
-  scoped_refptr<CookieStore> cookie_store_;
+  scoped_ptr<CookieStore> cookie_store_;
   scoped_ptr<FtpTransactionFactory> ftp_transaction_factory_;
   scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
   scoped_ptr<CertVerifier> cert_verifier_;
diff --git a/net/url_request/url_request_context_getter.h b/net/url_request/url_request_context_getter.h
index 1616f7c9..3e6cd08 100644
--- a/net/url_request/url_request_context_getter.h
+++ b/net/url_request/url_request_context_getter.h
@@ -29,7 +29,8 @@
  public:
   // Returns the URLRequestContextGetter's URLRequestContext. Must only be
   // called on the network task runner. Once NotifyContextShuttingDown() is
-  // invoked, must always return nullptr.
+  // invoked, must always return nullptr. Does not transfer ownership of
+  // the URLRequestContext.
   virtual URLRequestContext* GetURLRequestContext() = 0;
 
   // Returns a SingleThreadTaskRunner corresponding to the thread on
diff --git a/net/url_request/url_request_context_storage.cc b/net/url_request/url_request_context_storage.cc
index 2925107..ae073899 100644
--- a/net/url_request/url_request_context_storage.cc
+++ b/net/url_request/url_request_context_storage.cc
@@ -93,9 +93,10 @@
   context_->set_http_server_properties(http_server_properties_->GetWeakPtr());
 }
 
-void URLRequestContextStorage::set_cookie_store(CookieStore* cookie_store) {
-  context_->set_cookie_store(cookie_store);
-  cookie_store_ = cookie_store;
+void URLRequestContextStorage::set_cookie_store(
+    scoped_ptr<CookieStore> cookie_store) {
+  context_->set_cookie_store(cookie_store.get());
+  cookie_store_ = std::move(cookie_store);
 }
 
 void URLRequestContextStorage::set_transport_security_state(
diff --git a/net/url_request/url_request_context_storage.h b/net/url_request/url_request_context_storage.h
index 6669ae4..b888fb0 100644
--- a/net/url_request/url_request_context_storage.h
+++ b/net/url_request/url_request_context_storage.h
@@ -59,7 +59,7 @@
   void set_proxy_delegate(scoped_ptr<ProxyDelegate> proxy_delegate);
   void set_http_server_properties(
       scoped_ptr<HttpServerProperties> http_server_properties);
-  void set_cookie_store(CookieStore* cookie_store);
+  void set_cookie_store(scoped_ptr<CookieStore> cookie_store);
   void set_transport_security_state(
       scoped_ptr<TransportSecurityState> transport_security_state);
   void set_http_network_session(
@@ -101,7 +101,7 @@
   scoped_ptr<ProxyDelegate> proxy_delegate_;
   scoped_ptr<HttpServerProperties> http_server_properties_;
   scoped_ptr<HttpUserAgentSettings> http_user_agent_settings_;
-  scoped_refptr<CookieStore> cookie_store_;
+  scoped_ptr<CookieStore> cookie_store_;
   scoped_ptr<TransportSecurityState> transport_security_state_;
 
   // Not actually pointed at by the URLRequestContext, but may be used (but not
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index a6fc7eb..accf94c 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -544,10 +544,13 @@
 }
 
 TEST_F(URLRequestHttpJobTest, TestCancelWhileReadingCookies) {
-  context_.set_cookie_store(new DelayedCookieMonster());
+  DelayedCookieMonster cookie_monster;
+  TestURLRequestContext context(true);
+  context.set_cookie_store(&cookie_monster);
+  context.Init();
 
   TestDelegate delegate;
-  scoped_ptr<URLRequest> request = context_.CreateRequest(
+  scoped_ptr<URLRequest> request = context.CreateRequest(
       GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
 
   request->Start();
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 34e1f0bc..c209b4b 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -123,8 +123,10 @@
                       HttpCache::DefaultBackend::InMemory(0), false)));
   }
   // In-memory cookie store.
-  if (!cookie_store())
-    context_storage_.set_cookie_store(new CookieMonster(nullptr, nullptr));
+  if (!cookie_store()) {
+    context_storage_.set_cookie_store(
+        make_scoped_ptr(new CookieMonster(nullptr, nullptr)));
+  }
   // In-memory Channel ID service.
   if (!channel_id_service()) {
     context_storage_.set_channel_id_service(make_scoped_ptr(
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 2b6f11f..68e9997 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -2251,9 +2251,7 @@
   ASSERT_TRUE(test_server.Start());
 
   TestURLRequestContext context;
-  scoped_refptr<DelayedCookieMonster> delayed_cm =
-      new DelayedCookieMonster();
-  scoped_refptr<CookieStore> cookie_store = delayed_cm;
+  scoped_ptr<DelayedCookieMonster> delayed_cm(new DelayedCookieMonster());
   context.set_cookie_store(delayed_cm.get());
 
   // Set up a cookie.
diff --git a/ppapi/host/dispatch_host_message.h b/ppapi/host/dispatch_host_message.h
index a0b092e..c00df22 100644
--- a/ppapi/host/dispatch_host_message.h
+++ b/ppapi/host/dispatch_host_message.h
@@ -12,6 +12,8 @@
 
 #include <stdint.h>
 
+#include <tuple>
+
 #include "base/profiler/scoped_profile.h"
 #include "ipc/ipc_message_macros.h"
 #include "ppapi/c/pp_errors.h"
@@ -24,47 +26,47 @@
 template <class ObjT, class Method>
 inline int32_t DispatchResourceCall(ObjT* obj, Method method,
                                     HostMessageContext* context,
-                                    base::Tuple<>& arg) {
+                                    std::tuple<>& arg) {
   return (obj->*method)(context);
 }
 
 template <class ObjT, class Method, class A>
 inline int32_t DispatchResourceCall(ObjT* obj, Method method,
                                     HostMessageContext* context,
-                                    base::Tuple<A>& arg) {
-  return (obj->*method)(context, base::get<0>(arg));
+                                    std::tuple<A>& arg) {
+  return (obj->*method)(context, std::get<0>(arg));
 }
 
 template<class ObjT, class Method, class A, class B>
 inline int32_t DispatchResourceCall(ObjT* obj, Method method,
                                     HostMessageContext* context,
-                                    base::Tuple<A, B>& arg) {
-  return (obj->*method)(context, base::get<0>(arg), base::get<1>(arg));
+                                    std::tuple<A, B>& arg) {
+  return (obj->*method)(context, std::get<0>(arg), std::get<1>(arg));
 }
 
 template<class ObjT, class Method, class A, class B, class C>
 inline int32_t DispatchResourceCall(ObjT* obj, Method method,
                                     HostMessageContext* context,
-                                    base::Tuple<A, B, C>& arg) {
-  return (obj->*method)(context, base::get<0>(arg), base::get<1>(arg),
-                        base::get<2>(arg));
+                                    std::tuple<A, B, C>& arg) {
+  return (obj->*method)(context, std::get<0>(arg), std::get<1>(arg),
+                        std::get<2>(arg));
 }
 
 template<class ObjT, class Method, class A, class B, class C, class D>
 inline int32_t DispatchResourceCall(ObjT* obj, Method method,
                                     HostMessageContext* context,
-                                    base::Tuple<A, B, C, D>& arg) {
-  return (obj->*method)(context, base::get<0>(arg), base::get<1>(arg),
-                        base::get<2>(arg), base::get<3>(arg));
+                                    std::tuple<A, B, C, D>& arg) {
+  return (obj->*method)(context, std::get<0>(arg), std::get<1>(arg),
+                        std::get<2>(arg), std::get<3>(arg));
 }
 
 template<class ObjT, class Method, class A, class B, class C, class D, class E>
 inline int32_t DispatchResourceCall(ObjT* obj, Method method,
                                     HostMessageContext* context,
-                                    base::Tuple<A, B, C, D, E>& arg) {
-  return (obj->*method)(context, base::get<0>(arg), base::get<1>(arg),
-                        base::get<2>(arg), base::get<3>(arg),
-                        base::get<4>(arg));
+                                    std::tuple<A, B, C, D, E>& arg) {
+  return (obj->*method)(context, std::get<0>(arg), std::get<1>(arg),
+                        std::get<2>(arg), std::get<3>(arg),
+                        std::get<4>(arg));
 }
 
 // Note that this only works for message with 1 or more parameters. For
diff --git a/ppapi/proxy/dispatch_reply_message.h b/ppapi/proxy/dispatch_reply_message.h
index 2d66417..fc19adc 100644
--- a/ppapi/proxy/dispatch_reply_message.h
+++ b/ppapi/proxy/dispatch_reply_message.h
@@ -10,6 +10,8 @@
 #ifndef PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_
 #define PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_
 
+#include <tuple>
+
 #include "base/callback.h"
 #include "ipc/ipc_message_macros.h"
 #include "ppapi/c/pp_errors.h"
@@ -22,46 +24,46 @@
 template <class ObjT, class Method>
 inline void DispatchResourceReply(ObjT* obj, Method method,
                                   const ResourceMessageReplyParams& params,
-                                  const base::Tuple<>& arg) {
+                                  const std::tuple<>& arg) {
   (obj->*method)(params);
 }
 
 template <class ObjT, class Method, class A>
 inline void DispatchResourceReply(ObjT* obj, Method method,
                                   const ResourceMessageReplyParams& params,
-                                  const base::Tuple<A>& arg) {
-  (obj->*method)(params, base::get<0>(arg));
+                                  const std::tuple<A>& arg) {
+  (obj->*method)(params, std::get<0>(arg));
 }
 
 template<class ObjT, class Method, class A, class B>
 inline void DispatchResourceReply(ObjT* obj, Method method,
                                   const ResourceMessageReplyParams& params,
-                                  const base::Tuple<A, B>& arg) {
-  (obj->*method)(params, base::get<0>(arg), base::get<1>(arg));
+                                  const std::tuple<A, B>& arg) {
+  (obj->*method)(params, std::get<0>(arg), std::get<1>(arg));
 }
 
 template<class ObjT, class Method, class A, class B, class C>
 inline void DispatchResourceReply(ObjT* obj, Method method,
                                   const ResourceMessageReplyParams& params,
-                                  const base::Tuple<A, B, C>& arg) {
-  (obj->*method)(params, base::get<0>(arg), base::get<1>(arg),
-                 base::get<2>(arg));
+                                  const std::tuple<A, B, C>& arg) {
+  (obj->*method)(params, std::get<0>(arg), std::get<1>(arg),
+                 std::get<2>(arg));
 }
 
 template<class ObjT, class Method, class A, class B, class C, class D>
 inline void DispatchResourceReply(ObjT* obj, Method method,
                                   const ResourceMessageReplyParams& params,
-                                  const base::Tuple<A, B, C, D>& arg) {
-  (obj->*method)(params, base::get<0>(arg), base::get<1>(arg),
-                 base::get<2>(arg), base::get<3>(arg));
+                                  const std::tuple<A, B, C, D>& arg) {
+  (obj->*method)(params, std::get<0>(arg), std::get<1>(arg),
+                 std::get<2>(arg), std::get<3>(arg));
 }
 
 template<class ObjT, class Method, class A, class B, class C, class D, class E>
 inline void DispatchResourceReply(ObjT* obj, Method method,
                                   const ResourceMessageReplyParams& params,
-                                  const base::Tuple<A, B, C, D, E>& arg) {
-  (obj->*method)(params, base::get<0>(arg), base::get<1>(arg),
-                 base::get<2>(arg), base::get<3>(arg), base::get<4>(arg));
+                                  const std::tuple<A, B, C, D, E>& arg) {
+  (obj->*method)(params, std::get<0>(arg), std::get<1>(arg),
+                 std::get<2>(arg), std::get<3>(arg), std::get<4>(arg));
 }
 
 // Used to dispatch resource replies. In most cases, you should not call this
diff --git a/ppapi/proxy/nacl_message_scanner.cc b/ppapi/proxy/nacl_message_scanner.cc
index 643f6f7..bd29ae6 100644
--- a/ppapi/proxy/nacl_message_scanner.cc
+++ b/ppapi/proxy/nacl_message_scanner.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include <tuple>
 #include <utility>
 #include <vector>
 
@@ -164,26 +165,26 @@
 // The idea is to scan elements in the tuple which require special handling,
 // and write them into the |results| struct.
 template <class A>
-void ScanTuple(const base::Tuple<A>& t1, ScanningResults* results) {
-  ScanParam(base::get<0>(t1), results);
+void ScanTuple(const std::tuple<A>& t1, ScanningResults* results) {
+  ScanParam(std::get<0>(t1), results);
 }
 template <class A, class B>
-void ScanTuple(const base::Tuple<A, B>& t1, ScanningResults* results) {
-  ScanParam(base::get<0>(t1), results);
-  ScanParam(base::get<1>(t1), results);
+void ScanTuple(const std::tuple<A, B>& t1, ScanningResults* results) {
+  ScanParam(std::get<0>(t1), results);
+  ScanParam(std::get<1>(t1), results);
 }
 template <class A, class B, class C>
-void ScanTuple(const base::Tuple<A, B, C>& t1, ScanningResults* results) {
-  ScanParam(base::get<0>(t1), results);
-  ScanParam(base::get<1>(t1), results);
-  ScanParam(base::get<2>(t1), results);
+void ScanTuple(const std::tuple<A, B, C>& t1, ScanningResults* results) {
+  ScanParam(std::get<0>(t1), results);
+  ScanParam(std::get<1>(t1), results);
+  ScanParam(std::get<2>(t1), results);
 }
 template <class A, class B, class C, class D>
-void ScanTuple(const base::Tuple<A, B, C, D>& t1, ScanningResults* results) {
-  ScanParam(base::get<0>(t1), results);
-  ScanParam(base::get<1>(t1), results);
-  ScanParam(base::get<2>(t1), results);
-  ScanParam(base::get<3>(t1), results);
+void ScanTuple(const std::tuple<A, B, C, D>& t1, ScanningResults* results) {
+  ScanParam(std::get<0>(t1), results);
+  ScanParam(std::get<1>(t1), results);
+  ScanParam(std::get<2>(t1), results);
+  ScanParam(std::get<3>(t1), results);
 }
 
 template <class MessageType>
@@ -194,8 +195,7 @@
       : msg_(static_cast<const MessageType*>(msg)) {
   }
   bool ScanMessage(ScanningResults* results) {
-    typename base::TupleTypes<typename MessageType::Schema::Param>::ValueTuple
-        params;
+    typename MessageType::Param params;
     if (!MessageType::Read(msg_, &params))
       return false;
     ScanTuple(params, results);
@@ -203,8 +203,7 @@
   }
 
   bool ScanSyncMessage(ScanningResults* results) {
-    typename base::TupleTypes<typename MessageType::Schema::SendParam>
-        ::ValueTuple params;
+    typename MessageType::SendParam params;
     if (!MessageType::ReadSendParam(msg_, &params))
       return false;
     // If we need to rewrite the message, write the message id first.
@@ -218,8 +217,7 @@
   }
 
   bool ScanReply(ScanningResults* results) {
-    typename base::TupleTypes<typename MessageType::Schema::ReplyParam>
-        ::ValueTuple params;
+    typename MessageType::ReplyParam params;
     if (!MessageType::ReadReplyParam(msg_, &params))
       return false;
     // If we need to rewrite the message, write the message id first.
diff --git a/ppapi/proxy/plugin_var_tracker_unittest.cc b/ppapi/proxy/plugin_var_tracker_unittest.cc
index 79c1247..d59b695 100644
--- a/ppapi/proxy/plugin_var_tracker_unittest.cc
+++ b/ppapi/proxy/plugin_var_tracker_unittest.cc
@@ -4,6 +4,8 @@
 
 #include <stdint.h>
 
+#include <tuple>
+
 #include "ipc/ipc_test_sink.h"
 #include "ppapi/c/dev/ppp_class_deprecated.h"
 #include "ppapi/proxy/plugin_var_tracker.h"
@@ -58,9 +60,9 @@
     if (!release_msg)
       return -1;
 
-    base::Tuple<int64_t> id;
+    std::tuple<int64_t> id;
     PpapiHostMsg_PPBVar_ReleaseObject::Read(release_msg, &id);
-    return base::get<0>(id);
+    return std::get<0>(id);
   }
 };
 
diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc
index f3fb9ddc1..71b8816 100644
--- a/ppapi/proxy/ppapi_proxy_test.cc
+++ b/ppapi/proxy/ppapi_proxy_test.cc
@@ -5,6 +5,7 @@
 #include "ppapi/proxy/ppapi_proxy_test.h"
 
 #include <sstream>
+#include <tuple>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -138,13 +139,12 @@
   if (!reply_msg)
     return false;
 
-  base::TupleTypes<PpapiMsg_SupportsInterface::ReplyParam>::ValueTuple
-      reply_data;
+  PpapiMsg_SupportsInterface::ReplyParam reply_data;
   EXPECT_TRUE(PpapiMsg_SupportsInterface::ReadReplyParam(
       reply_msg, &reply_data));
 
   sink().ClearMessages();
-  return base::get<0>(reply_data);
+  return std::get<0>(reply_data);
 }
 
 // PluginProxyTestHarness ------------------------------------------------------
diff --git a/ppapi/proxy/resource_message_test_sink.cc b/ppapi/proxy/resource_message_test_sink.cc
index 4047d59d..864f72c 100644
--- a/ppapi/proxy/resource_message_test_sink.cc
+++ b/ppapi/proxy/resource_message_test_sink.cc
@@ -6,6 +6,8 @@
 
 #include <stddef.h>
 
+#include <tuple>
+
 #include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/proxy/resource_message_params.h"
 #include "ppapi/proxy/serialized_handle.h"
@@ -26,8 +28,8 @@
     if (msg->type() == WrapperMessage::ID) {
       typename WrapperMessage::Param params;
       WrapperMessage::Read(msg, &params);
-      Params cur_params = base::get<0>(params);
-      IPC::Message cur_msg = base::get<1>(params);
+      Params cur_params = std::get<0>(params);
+      IPC::Message cur_msg = std::get<1>(params);
       if (cur_msg.type() == id) {
         result.push_back(std::make_pair(cur_params, cur_msg));
       }
@@ -131,8 +133,8 @@
   bool success = PpapiHostMsg_ResourceSyncCall::ReadSendParam(
       &msg, &send_params);
   DCHECK(success);
-  ResourceMessageCallParams call_params = base::get<0>(send_params);
-  IPC::Message call_msg = base::get<1>(send_params);
+  ResourceMessageCallParams call_params = std::get<0>(send_params);
+  IPC::Message call_msg = std::get<1>(send_params);
   if (call_msg.type() != incoming_type_)
     return false;
   IPC::Message* wrapper_reply_msg = IPC::SyncMessage::GenerateReply(&msg);
diff --git a/ppapi/proxy/websocket_resource_unittest.cc b/ppapi/proxy/websocket_resource_unittest.cc
index 9df1308..d6dfd82 100644
--- a/ppapi/proxy/websocket_resource_unittest.cc
+++ b/ppapi/proxy/websocket_resource_unittest.cc
@@ -4,6 +4,8 @@
 
 #include <stdint.h>
 
+#include <tuple>
+
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "ppapi/c/pp_errors.h"
@@ -80,9 +82,9 @@
       PpapiHostMsg_WebSocket_Connect::ID, &params, &msg));
   PpapiHostMsg_WebSocket_Connect::Schema::Param p;
   PpapiHostMsg_WebSocket_Connect::Read(&msg, &p);
-  EXPECT_EQ(url, base::get<0>(p));
-  EXPECT_EQ(protocol0, base::get<1>(p)[0]);
-  EXPECT_EQ(protocol1, base::get<1>(p)[1]);
+  EXPECT_EQ(url, std::get<0>(p));
+  EXPECT_EQ(protocol0, std::get<1>(p)[0]);
+  EXPECT_EQ(protocol1, std::get<1>(p)[1]);
 
   // Synthesize a response.
   ResourceMessageReplyParams reply_params(params.pp_resource(),
diff --git a/remoting/host/pam_authorization_factory_posix.cc b/remoting/host/pam_authorization_factory_posix.cc
index c0352aa..2ae1eb3 100644
--- a/remoting/host/pam_authorization_factory_posix.cc
+++ b/remoting/host/pam_authorization_factory_posix.cc
@@ -167,12 +167,10 @@
 PamAuthorizationFactory::~PamAuthorizationFactory() {}
 
 scoped_ptr<protocol::Authenticator>
-PamAuthorizationFactory::CreateAuthenticator(
-    const std::string& local_jid,
-    const std::string& remote_jid,
-    const buzz::XmlElement* first_message) {
+PamAuthorizationFactory::CreateAuthenticator(const std::string& local_jid,
+                                             const std::string& remote_jid) {
   scoped_ptr<protocol::Authenticator> authenticator(
-      underlying_->CreateAuthenticator(local_jid, remote_jid, first_message));
+      underlying_->CreateAuthenticator(local_jid, remote_jid));
   return make_scoped_ptr(new PamAuthorizer(std::move(authenticator)));
 }
 
diff --git a/remoting/host/pam_authorization_factory_posix.h b/remoting/host/pam_authorization_factory_posix.h
index 2a084a6b..bc35a2b 100644
--- a/remoting/host/pam_authorization_factory_posix.h
+++ b/remoting/host/pam_authorization_factory_posix.h
@@ -22,8 +22,7 @@
 
   scoped_ptr<protocol::Authenticator> CreateAuthenticator(
       const std::string& local_jid,
-      const std::string& remote_jid,
-      const buzz::XmlElement* first_message) override;
+      const std::string& remote_jid) override;
 
  private:
   scoped_ptr<protocol::AuthenticatorFactory> underlying_;
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index 11fefc5..5018c134 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -232,8 +232,7 @@
 
   scoped_ptr<protocol::Authenticator> CreateAuthenticator(
       const std::string& local_jid,
-      const std::string& remote_jid,
-      const buzz::XmlElement* first_message) override {
+      const std::string& remote_jid) override {
     return make_scoped_ptr(new NoopAuthenticator());
   }
 };
diff --git a/remoting/protocol/authenticator.h b/remoting/protocol/authenticator.h
index 321116472..927790c 100644
--- a/remoting/protocol/authenticator.h
+++ b/remoting/protocol/authenticator.h
@@ -134,8 +134,7 @@
   // for the result of this method.
   virtual scoped_ptr<Authenticator> CreateAuthenticator(
       const std::string& local_jid,
-      const std::string& remote_jid,
-      const buzz::XmlElement* first_message) = 0;
+      const std::string& remote_jid) = 0;
 };
 
 }  // namespace protocol
diff --git a/remoting/protocol/fake_authenticator.cc b/remoting/protocol/fake_authenticator.cc
index 416d391a..49813ab 100644
--- a/remoting/protocol/fake_authenticator.cc
+++ b/remoting/protocol/fake_authenticator.cc
@@ -210,13 +210,11 @@
       action_(action), async_(async) {
 }
 
-FakeHostAuthenticatorFactory::~FakeHostAuthenticatorFactory() {
-}
+FakeHostAuthenticatorFactory::~FakeHostAuthenticatorFactory() {}
 
 scoped_ptr<Authenticator> FakeHostAuthenticatorFactory::CreateAuthenticator(
     const std::string& local_jid,
-    const std::string& remote_jid,
-    const buzz::XmlElement* first_message) {
+    const std::string& remote_jid) {
   scoped_ptr<FakeAuthenticator> authenticator(new FakeAuthenticator(
       FakeAuthenticator::HOST, round_trips_, action_, async_));
   authenticator->set_messages_till_started(messages_till_started_);
diff --git a/remoting/protocol/fake_authenticator.h b/remoting/protocol/fake_authenticator.h
index d0413952..b6c40ce 100644
--- a/remoting/protocol/fake_authenticator.h
+++ b/remoting/protocol/fake_authenticator.h
@@ -101,8 +101,7 @@
   // AuthenticatorFactory interface.
   scoped_ptr<Authenticator> CreateAuthenticator(
       const std::string& local_jid,
-      const std::string& remote_jid,
-      const buzz::XmlElement* first_message) override;
+      const std::string& remote_jid) override;
 
  private:
   int round_trips_;
diff --git a/remoting/protocol/it2me_host_authenticator_factory.cc b/remoting/protocol/it2me_host_authenticator_factory.cc
index 695b1b5..9ccf297 100644
--- a/remoting/protocol/it2me_host_authenticator_factory.cc
+++ b/remoting/protocol/it2me_host_authenticator_factory.cc
@@ -27,8 +27,7 @@
 
 scoped_ptr<Authenticator> It2MeHostAuthenticatorFactory::CreateAuthenticator(
     const std::string& local_jid,
-    const std::string& remote_jid,
-    const buzz::XmlElement* first_message) {
+    const std::string& remote_jid) {
   // Check the client domain policy.
   if (!required_client_domain_.empty()) {
     std::string client_username = remote_jid;
diff --git a/remoting/protocol/it2me_host_authenticator_factory.h b/remoting/protocol/it2me_host_authenticator_factory.h
index 78957d2..6a12164 100644
--- a/remoting/protocol/it2me_host_authenticator_factory.h
+++ b/remoting/protocol/it2me_host_authenticator_factory.h
@@ -32,8 +32,7 @@
   // AuthenticatorFactory interface.
   scoped_ptr<Authenticator> CreateAuthenticator(
       const std::string& local_jid,
-      const std::string& remote_jid,
-      const buzz::XmlElement* first_message) override;
+      const std::string& remote_jid) override;
 
  private:
   std::string local_cert_;
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc
index f3c53b9..f7872cf 100644
--- a/remoting/protocol/jingle_session_manager.cc
+++ b/remoting/protocol/jingle_session_manager.cc
@@ -82,8 +82,7 @@
 
     scoped_ptr<Authenticator> authenticator =
         authenticator_factory_->CreateAuthenticator(
-            signal_strategy_->GetLocalJid(), message.from,
-            message.description->authenticator_message());
+            signal_strategy_->GetLocalJid(), message.from);
 
     JingleSession* session = new JingleSession(this);
     session->InitializeIncomingConnection(message, std::move(authenticator));
diff --git a/remoting/protocol/me2me_host_authenticator_factory.cc b/remoting/protocol/me2me_host_authenticator_factory.cc
index 56e9631..1d8b5b08 100644
--- a/remoting/protocol/me2me_host_authenticator_factory.cc
+++ b/remoting/protocol/me2me_host_authenticator_factory.cc
@@ -62,16 +62,13 @@
   return std::move(result);
 }
 
-Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() {
-}
+Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() {}
 
-Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() {
-}
+Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() {}
 
 scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator(
     const std::string& local_jid,
-    const std::string& remote_jid,
-    const buzz::XmlElement* first_message) {
+    const std::string& remote_jid) {
 
   std::string remote_jid_prefix;
 
diff --git a/remoting/protocol/me2me_host_authenticator_factory.h b/remoting/protocol/me2me_host_authenticator_factory.h
index 18ad8d3..0f1cc7d5 100644
--- a/remoting/protocol/me2me_host_authenticator_factory.h
+++ b/remoting/protocol/me2me_host_authenticator_factory.h
@@ -51,8 +51,7 @@
   // AuthenticatorFactory interface.
   scoped_ptr<Authenticator> CreateAuthenticator(
       const std::string& local_jid,
-      const std::string& remote_jid,
-      const buzz::XmlElement* first_message) override;
+      const std::string& remote_jid) override;
 
  private:
   // Used for all host authenticators.
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 9df119e..1949ddb 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -417,6 +417,15 @@
     ]
   }
 
+  # Add the files for the SkFontMgr_Android. This is used to emulate android
+  # fonts on linux. See content/zygote/zygote_main_linux.cc
+  if (is_linux) {
+    sources += [
+      "//third_party/skia/src/ports/SkFontMgr_android.cpp",
+      "//third_party/skia/src/ports/SkFontMgr_android_parser.cpp",
+    ]
+  }
+
   if (!is_linux && !is_android) {
     sources -= [
       "//third_party/skia/src/ports/SkFontHost_FreeType.cpp",
@@ -464,6 +473,7 @@
     deps += [
       "//build/linux:fontconfig",
       "//build/linux:freetype2",
+      "//third_party/expat",
       "//third_party/icu:icuuc",
     ]
   }
diff --git a/skia/ext/refptr.h b/skia/ext/refptr.h
index f528930..a1860334 100644
--- a/skia/ext/refptr.h
+++ b/skia/ext/refptr.h
@@ -139,8 +139,14 @@
   friend RefPtr<U> AdoptRef(U* ptr);
 
   template<typename U>
+  friend RefPtr<U> AdoptRef(sk_sp<U>&&);
+
+  template<typename U>
   friend RefPtr<U> SharePtr(U* ptr);
 
+  template<typename U>
+  friend RefPtr<U> SharePtr(sk_sp<U>);
+
   template <typename U>
   friend class RefPtr;
 };
@@ -149,11 +155,17 @@
 template<typename T>
 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); }
 
+template<typename T>
+RefPtr<T> AdoptRef(sk_sp<T>&& sp) { return RefPtr<T>(sp.release()); }
+
 // For objects that are already owned. This doesn't take ownership of existing
 // references and adds a new one.
 template<typename T>
 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); }
 
+template<typename T>
+RefPtr<T> SharePtr(sk_sp<T> sp) { return RefPtr<T>(sp.release()); }
+
 }  // namespace skia
 
 #endif  // SKIA_EXT_REFPTR_H_
diff --git a/skia/ext/refptr_unittest.cc b/skia/ext/refptr_unittest.cc
index 237f439..cd25318a 100644
--- a/skia/ext/refptr_unittest.cc
+++ b/skia/ext/refptr_unittest.cc
@@ -214,5 +214,31 @@
   EXPECT_FALSE(returned);
 }
 
+TEST(RefPtrTest, SkSP) {
+  sk_sp<RefCountCounter> sp = sk_make_sp<RefCountCounter>();
+  EXPECT_EQ(0, sp->ref_count_changes());
+
+  RefPtr<RefCountCounter> ref = skia::SharePtr(sp);
+  EXPECT_FALSE(ref->unique());
+  EXPECT_EQ(1, ref->ref_count_changes());
+
+  sp = sk_make_sp<RefCountCounter>();
+  EXPECT_TRUE(ref->unique());
+  EXPECT_EQ(2, ref->ref_count_changes());
+
+  ref = skia::SharePtr(std::move(sp));
+  EXPECT_TRUE(ref->unique());
+  EXPECT_EQ(0, ref->ref_count_changes());
+
+  sp = sk_make_sp<RefCountCounter>();
+  ref = skia::AdoptRef(std::move(sp));
+  EXPECT_TRUE(ref->unique());
+  EXPECT_EQ(0, ref->ref_count_changes());
+
+  ref = skia::AdoptRef(sk_make_sp<RefCountCounter>());
+  EXPECT_TRUE(ref->unique());
+  EXPECT_EQ(0, ref->ref_count_changes());
+}
+
 }  // namespace
 }  // namespace skia
diff --git a/skia/skia_library.gypi b/skia/skia_library.gypi
index e5cfea65..a706a65 100644
--- a/skia/skia_library.gypi
+++ b/skia/skia_library.gypi
@@ -162,6 +162,7 @@
       'dependencies': [
         '../build/linux/system.gyp:fontconfig',
         '../build/linux/system.gyp:freetype2',
+        '../third_party/expat/expat.gyp:expat',
         '../third_party/icu/icu.gyp:icuuc',
       ],
       'cflags': [
@@ -294,6 +295,14 @@
         ],
       },
     }],
+    # Add the files for the SkFontMgr_Android. This is used to emulate android
+    # fonts on linux. See content/zygote/zygote_main_linux.cc
+    [ 'OS == "linux"', {
+      'sources/': [
+        ['include', 'SkFontMgr_android\\.cpp$',],
+        ['include', 'SkFontMgr_android_parser\\.cpp$',],
+      ],
+    }],
   ],
 
   'direct_dependent_settings': {
diff --git a/storage/browser/fileapi/copy_or_move_operation_delegate.cc b/storage/browser/fileapi/copy_or_move_operation_delegate.cc
index 1577278..a31ff74 100644
--- a/storage/browser/fileapi/copy_or_move_operation_delegate.cc
+++ b/storage/browser/fileapi/copy_or_move_operation_delegate.cc
@@ -5,6 +5,7 @@
 #include "storage/browser/fileapi/copy_or_move_operation_delegate.h"
 
 #include <stdint.h>
+#include <tuple>
 #include <utility>
 
 #include "base/bind.h"
@@ -411,21 +412,21 @@
   void NotifyOnStartUpdate(const FileSystemURL& url) {
     if (file_system_context_->GetUpdateObservers(url.type())) {
       file_system_context_->GetUpdateObservers(url.type())
-          ->Notify(&FileUpdateObserver::OnStartUpdate, base::MakeTuple(url));
+          ->Notify(&FileUpdateObserver::OnStartUpdate, std::make_tuple(url));
     }
   }
 
   void NotifyOnModifyFile(const FileSystemURL& url) {
     if (file_system_context_->GetChangeObservers(url.type())) {
       file_system_context_->GetChangeObservers(url.type())
-          ->Notify(&FileChangeObserver::OnModifyFile, base::MakeTuple(url));
+          ->Notify(&FileChangeObserver::OnModifyFile, std::make_tuple(url));
     }
   }
 
   void NotifyOnEndUpdate(const FileSystemURL& url) {
     if (file_system_context_->GetUpdateObservers(url.type())) {
       file_system_context_->GetUpdateObservers(url.type())
-          ->Notify(&FileUpdateObserver::OnEndUpdate, base::MakeTuple(url));
+          ->Notify(&FileUpdateObserver::OnEndUpdate, std::make_tuple(url));
     }
   }
 
diff --git a/storage/browser/fileapi/file_system_operation_impl.cc b/storage/browser/fileapi/file_system_operation_impl.cc
index 15700f0..74ba055 100644
--- a/storage/browser/fileapi/file_system_operation_impl.cc
+++ b/storage/browser/fileapi/file_system_operation_impl.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 #include <limits>
+#include <tuple>
 #include <utility>
 
 #include "base/bind.h"
@@ -581,7 +582,7 @@
   if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) {
     DCHECK(operation_context_);
     operation_context_->change_observers()->Notify(
-        &FileChangeObserver::OnModifyFile, base::MakeTuple(url));
+        &FileChangeObserver::OnModifyFile, std::make_tuple(url));
   }
 
   StatusCallback cancel_callback = cancel_callback_;
diff --git a/storage/browser/fileapi/file_system_operation_runner.cc b/storage/browser/fileapi/file_system_operation_runner.cc
index 4e6bf2b..2052b38 100644
--- a/storage/browser/fileapi/file_system_operation_runner.cc
+++ b/storage/browser/fileapi/file_system_operation_runner.cc
@@ -5,6 +5,7 @@
 #include "storage/browser/fileapi/file_system_operation_runner.h"
 
 #include <stdint.h>
+#include <tuple>
 #include <utility>
 
 #include "base/bind.h"
@@ -637,7 +638,7 @@
                                                 const FileSystemURL& url) {
   if (file_system_context_->GetUpdateObservers(url.type())) {
     file_system_context_->GetUpdateObservers(url.type())->Notify(
-        &FileUpdateObserver::OnStartUpdate, base::MakeTuple(url));
+        &FileUpdateObserver::OnStartUpdate, std::make_tuple(url));
   }
   write_target_urls_[id].insert(url);
 }
@@ -646,7 +647,7 @@
                                                const FileSystemURL& url) {
   if (file_system_context_->GetAccessObservers(url.type())) {
     file_system_context_->GetAccessObservers(url.type())->Notify(
-        &FileAccessObserver::OnAccess, base::MakeTuple(url));
+        &FileAccessObserver::OnAccess, std::make_tuple(url));
   }
 }
 
@@ -668,7 +669,7 @@
         iter != urls.end(); ++iter) {
       if (file_system_context_->GetUpdateObservers(iter->type())) {
         file_system_context_->GetUpdateObservers(iter->type())->Notify(
-            &FileUpdateObserver::OnEndUpdate, base::MakeTuple(*iter));
+            &FileUpdateObserver::OnEndUpdate, std::make_tuple(*iter));
       }
     }
     write_target_urls_.erase(found);
diff --git a/storage/browser/fileapi/obfuscated_file_util.cc b/storage/browser/fileapi/obfuscated_file_util.cc
index cdd8b7a..018249db 100644
--- a/storage/browser/fileapi/obfuscated_file_util.cc
+++ b/storage/browser/fileapi/obfuscated_file_util.cc
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <queue>
+#include <tuple>
 
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
@@ -91,7 +92,7 @@
                  const FileSystemURL& url,
                  int64_t growth) {
   context->update_observers()->Notify(
-      &FileUpdateObserver::OnUpdate, base::MakeTuple(url, growth));
+      &FileUpdateObserver::OnUpdate, std::make_tuple(url, growth));
 }
 
 void TouchDirectory(SandboxDirectoryDatabase* db, FileId dir_id) {
@@ -322,7 +323,7 @@
     *created = true;
     UpdateUsage(context, url, growth);
     context->change_observers()->Notify(
-        &FileChangeObserver::OnCreateFile, base::MakeTuple(url));
+        &FileChangeObserver::OnCreateFile, std::make_tuple(url));
   }
   return error;
 }
@@ -381,7 +382,7 @@
       return error;
     UpdateUsage(context, url, growth);
     context->change_observers()->Notify(
-        &FileChangeObserver::OnCreateDirectory, base::MakeTuple(url));
+        &FileChangeObserver::OnCreateDirectory, std::make_tuple(url));
     if (first) {
       first = false;
       TouchDirectory(db, file_info.parent_id);
@@ -482,7 +483,7 @@
   if (error == base::File::FILE_OK) {
     UpdateUsage(context, url, growth);
     context->change_observers()->Notify(
-        &FileChangeObserver::OnModifyFile, base::MakeTuple(url));
+        &FileChangeObserver::OnModifyFile, std::make_tuple(url));
   }
   return error;
 }
@@ -609,16 +610,16 @@
   if (overwrite) {
     context->change_observers()->Notify(
         &FileChangeObserver::OnModifyFile,
-        base::MakeTuple(dest_url));
+        std::make_tuple(dest_url));
   } else {
     context->change_observers()->Notify(
         &FileChangeObserver::OnCreateFileFrom,
-        base::MakeTuple(dest_url, src_url));
+        std::make_tuple(dest_url, src_url));
   }
 
   if (!copy) {
     context->change_observers()->Notify(
-        &FileChangeObserver::OnRemoveFile, base::MakeTuple(src_url));
+        &FileChangeObserver::OnRemoveFile, std::make_tuple(src_url));
     TouchDirectory(db, src_file_info.parent_id);
   }
 
@@ -697,10 +698,10 @@
 
   if (overwrite) {
     context->change_observers()->Notify(
-        &FileChangeObserver::OnModifyFile, base::MakeTuple(dest_url));
+        &FileChangeObserver::OnModifyFile, std::make_tuple(dest_url));
   } else {
     context->change_observers()->Notify(
-        &FileChangeObserver::OnCreateFile, base::MakeTuple(dest_url));
+        &FileChangeObserver::OnCreateFile, std::make_tuple(dest_url));
   }
 
   UpdateUsage(context, dest_url, growth);
@@ -741,7 +742,7 @@
   TouchDirectory(db, file_info.parent_id);
 
   context->change_observers()->Notify(
-      &FileChangeObserver::OnRemoveFile, base::MakeTuple(url));
+      &FileChangeObserver::OnRemoveFile, std::make_tuple(url));
 
   if (error == base::File::FILE_ERROR_NOT_FOUND)
     return base::File::FILE_OK;
@@ -776,7 +777,7 @@
   UpdateUsage(context, url, growth);
   TouchDirectory(db, file_info.parent_id);
   context->change_observers()->Notify(
-      &FileChangeObserver::OnRemoveDirectory, base::MakeTuple(url));
+      &FileChangeObserver::OnRemoveDirectory, std::make_tuple(url));
   return base::File::FILE_OK;
 }
 
@@ -1372,7 +1373,7 @@
     if (file.IsValid()) {
       UpdateUsage(context, url, growth);
       context->change_observers()->Notify(
-          &FileChangeObserver::OnCreateFile, base::MakeTuple(url));
+          &FileChangeObserver::OnCreateFile, std::make_tuple(url));
     }
     return file;
   }
@@ -1415,7 +1416,7 @@
   if (delta) {
     UpdateUsage(context, url, delta);
     context->change_observers()->Notify(
-        &FileChangeObserver::OnModifyFile, base::MakeTuple(url));
+        &FileChangeObserver::OnModifyFile, std::make_tuple(url));
   }
   return file;
 }
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.cc b/storage/browser/fileapi/sandbox_file_stream_writer.cc
index 09384ff..363fb01 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.cc
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.cc
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include <limits>
+#include <tuple>
 
 #include "base/files/file_util_proxy.h"
 #include "base/sequenced_task_runner.h"
@@ -227,7 +228,7 @@
     if (overlapped < 0)
       overlapped = 0;
     observers_.Notify(&FileUpdateObserver::OnUpdate,
-                      base::MakeTuple(url_, write_response - overlapped));
+                      std::make_tuple(url_, write_response - overlapped));
   }
   total_bytes_written_ += write_response;
 
diff --git a/storage/browser/fileapi/task_runner_bound_observer_list.h b/storage/browser/fileapi/task_runner_bound_observer_list.h
index 2af1c94c..eae9ddf1 100644
--- a/storage/browser/fileapi/task_runner_bound_observer_list.h
+++ b/storage/browser/fileapi/task_runner_bound_observer_list.h
@@ -11,6 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/thread.h"
+#include "base/tuple.h"
 
 namespace storage {
 
diff --git a/sync/api/model_type_service.h b/sync/api/model_type_service.h
index 950060e..bba4211 100644
--- a/sync/api/model_type_service.h
+++ b/sync/api/model_type_service.h
@@ -38,8 +38,19 @@
   // model type store.
   virtual scoped_ptr<MetadataChangeList> CreateMetadataChangeList() = 0;
 
-  // Perform the initial merge of data from the sync server. Should only need
-  // to be called when sync is first turned on, not on every restart.
+  // Perform the initial merge between local and sync data. This should only be
+  // called when a data type is first enabled to start syncing, and there is no
+  // sync metadata. Best effort should be made to match local and sync data. The
+  // keys in the |entity_data_map| will have been created via GetClientTag(...),
+  // and if a local and sync data should match/merge but disagree on tags, the
+  // service should use the sync data's tag. Any local pieces of data that are
+  // not present in sync should immediately be Put(...) to the processor before
+  // returning. The same MetadataChangeList that was passed into this function
+  // can be passed to Put(...) calls. Delete(...) can also be called but should
+  // not be needed for most model types. Durable storage writes, if not able to
+  // combine all change atomically, should save the metadata after the data
+  // changes, so that this merge will be re-driven by sync if is not completely
+  // saved during the current run.
   virtual syncer::SyncError MergeSyncData(
       scoped_ptr<MetadataChangeList> metadata_change_list,
       EntityDataMap entity_data_map) = 0;
diff --git a/sync/protocol/password_specifics.proto b/sync/protocol/password_specifics.proto
index 7f27072..201fb3f 100644
--- a/sync/protocol/password_specifics.proto
+++ b/sync/protocol/password_specifics.proto
@@ -53,7 +53,7 @@
 
   // For parsed web forms and Credential Manager API:
   //     url-scheme://url-host[:url-port]/path
-  // For Android: <empty>.
+  // For Android: "android://<hash of cert>@<package name>"
   // For proxy/HTTP auth: url-scheme://url-host[:url-port]/path
   optional string origin = 3;
 
diff --git a/testing/android/OWNERS b/testing/android/OWNERS
index 0946638..0156372 100644
--- a/testing/android/OWNERS
+++ b/testing/android/OWNERS
@@ -1,4 +1,5 @@
 dtrainor@chromium.org
+jbudorick@chromium.org
 miguelg@chromium.org
 nyquist@chromium.org
 skyostil@chromium.org
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn
index 984338aa..56a4257 100644
--- a/testing/libfuzzer/fuzzers/BUILD.gn
+++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -253,6 +253,7 @@
     "//base",
     "//third_party/libpng",
   ]
+  dict = "dicts/png.dict"
 }
 
 fuzzer_test("icu_uregex_open_fuzzer") {
@@ -311,3 +312,14 @@
   ]
   libfuzzer_options = "re2_fuzzer.options"
 }
+
+fuzzer_test("libxml_xml_regexp_compile_fuzzer") {
+  sources = [
+    "libxml_xml_regexp_compile_fuzzer.cc",
+  ]
+  deps = [
+    "//third_party/libxml",
+  ]
+  libfuzzer_options = "libxml_xml_regexp_compile_fuzzer.options"
+  additional_configs = [ "//testing/libfuzzer:no_clusterfuzz" ]
+}
diff --git a/testing/libfuzzer/fuzzers/dicts/png.dict b/testing/libfuzzer/fuzzers/dicts/png.dict
new file mode 100644
index 0000000..ea12d19
--- /dev/null
+++ b/testing/libfuzzer/fuzzers/dicts/png.dict
@@ -0,0 +1,38 @@
+#
+# AFL dictionary for PNG images
+# -----------------------------
+#
+# Just the basic, standard-originating sections; does not include vendor
+# extensions.
+#
+# Created by Michal Zalewski <lcamtuf@google.com>
+#
+
+header_png="\x89PNG\x0d\x0a\x1a\x0a"
+
+section_IDAT="IDAT"
+section_IEND="IEND"
+section_IHDR="IHDR"
+section_PLTE="PLTE"
+section_bKGD="bKGD"
+section_cHRM="cHRM"
+section_fRAc="fRAc"
+section_gAMA="gAMA"
+section_gIFg="gIFg"
+section_gIFt="gIFt"
+section_gIFx="gIFx"
+section_hIST="hIST"
+section_iCCP="iCCP"
+section_iTXt="iTXt"
+section_oFFs="oFFs"
+section_pCAL="pCAL"
+section_pHYs="pHYs"
+section_sBIT="sBIT"
+section_sCAL="sCAL"
+section_sPLT="sPLT"
+section_sRGB="sRGB"
+section_sTER="sTER"
+section_tEXt="tEXt"
+section_tIME="tIME"
+section_tRNS="tRNS"
+section_zTXt="zTXt"
diff --git a/testing/libfuzzer/fuzzers/libxml_xml_regexp_compile_fuzzer.cc b/testing/libfuzzer/fuzzers/libxml_xml_regexp_compile_fuzzer.cc
new file mode 100644
index 0000000..65aba296
--- /dev/null
+++ b/testing/libfuzzer/fuzzers/libxml_xml_regexp_compile_fuzzer.cc
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "libxml/parser.h"
+#include "libxml/tree.h"
+#include "libxml/xmlversion.h"
+
+
+void ignore (void * ctx, const char * msg, ...) {
+  // Error handler to avoid spam of error messages from libxml parser.
+}
+
+
+// Entry point for LibFuzzer.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  xmlSetGenericErrorFunc(NULL, &ignore);
+
+  std::vector<uint8_t> buffer(size + 1, 0);
+  std::copy(data, data + size, buffer.data());
+
+  xmlRegexpPtr x = xmlRegexpCompile(buffer.data());
+  if (x)
+    xmlRegFreeRegexp(x);
+
+  return 0;
+}
diff --git a/testing/libfuzzer/fuzzers/libxml_xml_regexp_compile_fuzzer.options b/testing/libfuzzer/fuzzers/libxml_xml_regexp_compile_fuzzer.options
new file mode 100644
index 0000000..76499d9
--- /dev/null
+++ b/testing/libfuzzer/fuzzers/libxml_xml_regexp_compile_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = random(4, 32)
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 4fb51b0..4593812 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -283,3 +283,5 @@
 
 crbug.com/584807 printing/webgl-oversized-printing.html [ Slow ]
 crbug.com/584807 virtual/threaded/printing/webgl-oversized-printing.html [ Slow ]
+
+crbug.com/592183 usb/usbDevice.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index e367f966..c24c608d 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -116,8 +116,6 @@
 crbug.com/539226 [ Win ] http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-redirect-response-handling.html [ Timeout Pass ]
 crbug.com/539226 [ Win ] http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-preflight-handling.html [ Timeout Pass ]
 
-crbug.com/592063 svg/custom/relative-sized-shadow-tree-content-with-symbol.xhtml [ NeedsRebaseline ]
-
 crbug.com/417782 [ Linux Win ] virtual/rootlayerscrolls/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ]
 crbug.com/492664 [ Linux ] imported/csswg-test/css-writing-modes-3/box-offsets-rel-pos-vlr-005.xht [ Failure ]
 crbug.com/492664 [ Linux ] imported/csswg-test/css-writing-modes-3/box-offsets-rel-pos-vrl-004.xht [ Failure ]
@@ -189,11 +187,6 @@
 crbug.com/339597 http/tests/navigation/back-to-redirect-with-frame.php [ Pass Timeout ]
 crbug.com/473718 http/tests/navigation/beacon-cross-origin-redirect.html [ Failure Pass ]
 
-# Skia roll
-crbug.com/586181 svg/batik/paints/patternRegions-positioned-objects.svg [ NeedsRebaseline ]
-crbug.com/586181 svg/batik/paints/patternRegions.svg [ NeedsRebaseline ]
-crbug.com/586181 svg/custom/stroked-pattern.svg [ NeedsRebaseline ]
-
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-basic.html [ Pass Failure ]
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-consume-deltas.html [ Pass Failure ]
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-consume-deltas-throw.html [ Pass Failure ]
@@ -283,10 +276,10 @@
 crbug.com/567837 [ Mac ] virtual/scalefactor200withzoom/fast/hidpi/static/data-suggestion-picker-appearance.html [ Skip ]
 
 # TODO(oshima): Move the event scaling code to eventSender and remove this.
-crbug.com/495750 virtual/scalefactor200/fast/hidpi/static/mousewheel-scroll-amount.html [ Skip ]
-crbug.com/495750 virtual/scalefactor200/fast/hidpi/static/gesture-scroll-amount.html [ Skip ]
-crbug.com/495750 virtual/scalefactor150/fast/hidpi/static/mousewheel-scroll-amount.html [ Skip ]
-crbug.com/495750 virtual/scalefactor150/fast/hidpi/static/gesture-scroll-amount.html [ Skip ]
+crbug.com/567837 virtual/scalefactor200/fast/hidpi/static/mousewheel-scroll-amount.html [ Skip ]
+crbug.com/567837 virtual/scalefactor200/fast/hidpi/static/gesture-scroll-amount.html [ Skip ]
+crbug.com/567837 virtual/scalefactor150/fast/hidpi/static/mousewheel-scroll-amount.html [ Skip ]
+crbug.com/567837 virtual/scalefactor150/fast/hidpi/static/gesture-scroll-amount.html [ Skip ]
 
 # TODO(ojan): These tests aren't flaky. See crbug.com/517144.
 # Release trybots run asserts, but the main waterfall ones don't. So, even
@@ -314,8 +307,7 @@
 crbug.com/498539 inspector/elements/styles-3/styles-change-node-while-editing.html [ Failure Pass ]
 crbug.com/498539 [ Mac ] inspector/sources/debugger/live-edit-no-reveal.html [ Crash Pass Timeout ]
 crbug.com/498539 [ Mac10.10 ] inspector/sources/debugger/debug-inlined-scripts-fragment-id.html [ Pass Timeout ]
-# TODO(yangguo): Uncomment this line once crbug.com/590992 has been fixed.
-# crbug.com/498539 [ Precise ] inspector/sources/debugger-step/debugger-step-over-inlined-scripts.html [ Pass Timeout ]
+crbug.com/498539 [ Precise ] inspector/sources/debugger-step/debugger-step-over-inlined-scripts.html [ Pass Timeout ]
 crbug.com/498539 [ Precise Win7 Mac10.10 ] inspector/sources/debugger-breakpoints/dynamic-scripts-breakpoints.html [ Pass Timeout ]
 crbug.com/498539 [ Precise Mac10.10 ] inspector/sources/debugger-breakpoints/set-breakpoint.html [ Pass Timeout ]
 crbug.com/498539 [ Trusty ] inspector/sources/debugger/mutation-observer-suspend-while-paused.html [ Pass Timeout ]
@@ -458,7 +450,6 @@
 crbug.com/490511 imported/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/color.html [ Failure Pass ]
 crbug.com/490511 imported/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/width.html [ Failure Pass ]
 crbug.com/490511 imported/web-platform-tests/html/semantics/document-metadata/styling/LinkStyle.html [ Failure Pass ]
-crbug.com/525896 imported/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html [ Failure ]
 crbug.com/490511 imported/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html [ Failure ]
 crbug.com/525889 imported/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-setInterval.html [ Failure ]
 crbug.com/525889 imported/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-setTimeout.html [ Failure ]
@@ -939,8 +930,6 @@
 crbug.com/498021 [ Linux ] fast/text/international/complex-character-based-fallback.html [ Failure ]
 crbug.com/498021 [ Linux ] fast/text/international/hindi-spacing.html [ Failure ]
 
-crbug.com/567998 imported/web-platform-tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/document-all.html [ NeedsManualRebaseline ]
-
 # Significant Slimming Paint failure.
 crbug.com/459305 [ Mac ] svg/custom/foreign-object-skew.svg [ Failure ]
 
@@ -1088,9 +1077,6 @@
 
 crbug.com/464736 http/tests/xmlhttprequest/ontimeout-event-override-after-failure.html [ Pass Failure ]
 
-crbug.com/591901 fast/images/color-profile-background-clip-text.html [ NeedsRebaseline ]
-crbug.com/591901 fast/images/color-profile-svg-fill-text.html [ NeedsRebaseline ]
-
 crbug.com/521730 [ Win10 ] fast/forms/month-multiple-fields/month-multiple-fields-preserve-value-after-history-back.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/forms/month-multiple-fields/month-multiple-fields-value-set-empty.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/forms/suggested-value.html [ Failure ]
@@ -1265,15 +1251,6 @@
 
 crbug.com/574196 fast/js/mozilla/strict/13.1.html [ NeedsManualRebaseline ]
 
-crbug.com/588803 inspector/console/alert-toString-exception.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/console/console-eval-scoped.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/console/console-format-es6.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/console/console-object-constructor-name.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/runtime/runtime-getProperties.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/sources/debugger-frameworks/frameworks-jquery.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/sources/debugger-ui/function-details.html [ NeedsManualRebaseline ]
-crbug.com/588803 inspector/sources/debugger-ui/function-generator-details.html [ NeedsManualRebaseline ]
-
 crbug.com/568867 [ Win Debug ] transforms/3d/point-mapping/3d-point-mapping-deep.html [ Failure ]
 crbug.com/568867 [ Win Debug ] transforms/3d/point-mapping/3d-point-mapping-preserve-3d.html [ Failure ]
 
@@ -1289,7 +1266,6 @@
 crbug.com/571710 http/tests/inspector/search/source-frame-search.html [ Timeout Pass ]
 
 crbug.com/571716 inspector/audits/audits-panel-functional.html [ Crash Pass ]
-
 crbug.com/571721 inspector/console/console-xpath.html [ Timeout Pass ]
 
 crbug.com/580378 [ Mac ] fast/replaced/width100percent-searchfield.html [ Failure Pass ]
@@ -1318,8 +1294,6 @@
 
 crbug.com/581038 fast/text/first-letter-bad-line-boxes-crash.html [ Crash Pass ]
 
-crbug.com/585724 fast/js/JSON-parse.html [ NeedsManualRebaseline ]
-
 crbug.com/587136 [ Linux Debug ] http/tests/security/xss-DENIED-cross-origin-stack-overflow.html [ Timeout Pass ]
 
 crbug.com/587593 [ Android ] fast/js/pic/cached-single-entry-transition.html [ Pass Failure ]
@@ -1330,19 +1304,6 @@
 
 crbug.com/588103 fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html [ Pass Failure ]
 
-crbug.com/590992 inspector/sources/debugger-step/debugger-step-into-async1.html [ Pass Failure ]
-crbug.com/590992 inspector/sources/debugger-step/debugger-step-into-document-write.html [ Pass Failure ]
-crbug.com/590992 inspector/sources/debugger-step/debugger-step-into-inlined-scripts.html [ Pass Failure ]
-crbug.com/590992 inspector/sources/debugger-step/debugger-step-over-document-write.html [ Pass Failure ]
-crbug.com/590992 inspector/sources/debugger-step/debugger-step-over-inlined-scripts.html [ Pass Failure Timeout ]
-
-crbug.com/257405 fast/js/invalid-syntax-for-function.html [ NeedsManualRebaseline ]
-crbug.com/257405 fast/js/kde/string-1-n.html [ NeedsManualRebaseline ]
-crbug.com/257405 fast/js/kde/string-2-n.html [ NeedsManualRebaseline ]
-crbug.com/257405 fast/regex/non-pattern-characters.html [ NeedsManualRebaseline ]
-crbug.com/257405 http/tests/websocket/bad-sub-protocol-control-chars.html [ NeedsManualRebaseline ]
-crbug.com/257405 inspector/console/console-control-characters.html [ NeedsManualRebaseline ]
-
 crbug.com/591821 fast/events/iframe-object-onload.html [ Failure Pass ]
 crbug.com/591821 [ Linux Win ] fast/events/menu-key-context-menu-document.html [ Failure Pass ]
 crbug.com/591821 fast/events/keyboard-scroll-by-page.html [ Failure Pass ]
@@ -1409,7 +1370,7 @@
 
 crbug.com/591902 [ Linux Mac10.10 Mac10.11 Retina ] http/tests/security/contentTypeOptions/nosniff-script-without-content-type-blocked.html [ Failure ]
 
-crbug.com/592183 usb/usbDevice.html [ Timeout Pass ]
-
 crbug.com/592185 fast/repaint/fixed-right-in-page-scale.html [ Failure Pass ]
 
+crbug.com/592409 inspector-protocol/debugger/stepping-with-blackboxed-ranges.html [ NeedsManualRebaseline ]
+
diff --git a/third_party/WebKit/LayoutTests/css3/images/pixelated-border-image.html b/third_party/WebKit/LayoutTests/css3/images/pixelated-border-image.html
index dc71aa2..c7ea51a7 100644
--- a/third_party/WebKit/LayoutTests/css3/images/pixelated-border-image.html
+++ b/third_party/WebKit/LayoutTests/css3/images/pixelated-border-image.html
@@ -7,6 +7,7 @@
         border-image-source: url(resources/border-image.png);
         border-image-slice: 6;
         image-rendering: pixelated;
+        border-style: solid;
     }
 </style>
 <body>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/4145535Crash.html b/third_party/WebKit/LayoutTests/fast/block/float/4145535Crash.html
index 3dfaf1f..ccea589 100644
--- a/third_party/WebKit/LayoutTests/fast/block/float/4145535Crash.html
+++ b/third_party/WebKit/LayoutTests/fast/block/float/4145535Crash.html
@@ -1,3 +1,3 @@
 <table
 CELLSPACING=8888888888>
-<EMBED UNITS="4">
\ No newline at end of file
+<EMBED UNITS="4" type="image/png">
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-01.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-01.html
index ffd8c1f..d712dc2 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-01.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-01.html
@@ -7,6 +7,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html
index 643eaae..1504fc1 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html
@@ -8,6 +8,7 @@
             margin: 10px;
             display: inline-block;
             -webkit-border-radius: 10px;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-longhand.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-longhand.html
index dab6530..1be8c63 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-longhand.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-longhand.html
@@ -10,6 +10,7 @@
             border-image-source: url("resources/border-image.png");
             border-image-slice: 21 30 30 21 fill;
             border-image-width: 1;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-massive-scale.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-massive-scale.html
index f499901..c43c367 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-massive-scale.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-massive-scale.html
@@ -8,6 +8,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice-expected.txt b/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice-expected.txt
index a56f63ad..4551a99d 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice-expected.txt
@@ -3,5 +3,5 @@
 layer at (0,0) size 800x416
   LayoutBlockFlow {HTML} at (0,0) size 800x416
     LayoutBlockFlow {BODY} at (8,8) size 784x400
-      LayoutBlockFlow {DIV} at (0,0) size 400x400 [border: (100px none #000000)]
+      LayoutBlockFlow {DIV} at (0,0) size 400x400 [border: (100px solid #000000)]
         LayoutBlockFlow {DIV} at (100,100) size 200x200 [bgcolor=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice.html
index 71b34299..5086d4a0 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-omit-right-slice.html
@@ -17,6 +17,7 @@
         -webkit-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAUFJREFUGNMBNgHJ/gPcUkznH/n8lGR5YkMIIMDXFhgoVNnfqeM5dbre55MDGkF/U6tMmi12K6QBpfkB4H3NyPZAiyjm6kp//uPtAA4pZhHPJ8xbkSop4chy5ecPsVSqkC03ozAmk77SOwOHR+fDXmoF5UUJU9YsnVfehg/iLC7p3etC3w3LEA8D0eGf/DZozPPzoSSX6gTVlQ/L4Ylt4SrFiOgqNDQPAPvl/JQuLv33xK66eAgGCn+OAIUu1Fugs2hsZNIB6gPhrZ80q7sXNUEuIE7EGNC5Dc2ExcIe9tseb4r7usAAralzLgdas9URX21wGUqSgDnf/jMydhxMIEx4w9TtAfCQPsbi30EEVABXFJYnOZgfbQK3CLkwg6PDGG27KwOYF7jD+sIHhdwoUyILAF5sv/6bI6S56fbULB5OToUjFpS7UHGrVgAAAABJRU5ErkJggg==) 1 2 3;
         border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAUFJREFUGNMBNgHJ/gPcUkznH/n8lGR5YkMIIMDXFhgoVNnfqeM5dbre55MDGkF/U6tMmi12K6QBpfkB4H3NyPZAiyjm6kp//uPtAA4pZhHPJ8xbkSop4chy5ecPsVSqkC03ozAmk77SOwOHR+fDXmoF5UUJU9YsnVfehg/iLC7p3etC3w3LEA8D0eGf/DZozPPzoSSX6gTVlQ/L4Ylt4SrFiOgqNDQPAPvl/JQuLv33xK66eAgGCn+OAIUu1Fugs2hsZNIB6gPhrZ80q7sXNUEuIE7EGNC5Dc2ExcIe9tseb4r7usAAralzLgdas9URX21wGUqSgDnf/jMydhxMIEx4w9TtAfCQPsbi30EEVABXFJYnOZgfbQK3CLkwg6PDGG27KwOYF7jD+sIHhdwoUyILAF5sv/6bI6S56fbULB5OToUjFpS7UHGrVgAAAABJRU5ErkJggg==) 1 2 3;
         border-width: 100px;
+        border-style: solid;
     }
 
     body > div > div {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-in-shorthand.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-in-shorthand.html
index 4b37ce2..e2da5d67 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-in-shorthand.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-in-shorthand.html
@@ -8,6 +8,7 @@
             display: inline-block;
             -webkit-border-image: url("resources/border-image.png") 21 30 30 21 / 1 / 21px 30px 30px 21px stretch;
             margin:30px;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline-vertical-lr.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline-vertical-lr.html
index 4e30d37f4..c35ab117 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline-vertical-lr.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline-vertical-lr.html
@@ -4,6 +4,7 @@
         span {
             border-width: 21px 30px 30px 21px;
             -webkit-border-image: url("resources/border-image.png") 21 30 30 21 / 1 / 21px 30px 30px 21px repeat;
+            border-style: solid;
         }
     </style>
 </head>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline.html
index e1afd9f..15c98a2 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset-split-inline.html
@@ -4,6 +4,7 @@
         span {
             border-width: 21px 30px 30px 21px;
             -webkit-border-image: url("resources/border-image.png") 21 30 30 21 / 1 / 21px 30px 30px 21px repeat;
+            border-style: solid;
         }
     </style>
 </head>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset.html
index a42cdce..14beaeb 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-outset.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-outset.html
@@ -11,6 +11,7 @@
             border-image-width: 1;
             border-image-outset: 1;
             margin:30px;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-round.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-round.html
index 45e038d..a067e6f2 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-round.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-round.html
@@ -6,6 +6,7 @@
             height: 60px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         .text-image {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat.html
index ab309265..08535779 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat.html
@@ -7,6 +7,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-rotate-transform.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-rotate-transform.html
index bc9a2e8..6604632 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-rotate-transform.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-rotate-transform.html
@@ -8,6 +8,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-scale-transform.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-scale-transform.html
index 3e59d00b..5863124 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-scale-transform.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-scale-transform.html
@@ -8,6 +8,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled.html
index 751619c6..0a2c8f5 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled.html
@@ -7,6 +7,7 @@
             height: 150px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-scrambled.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-scrambled.html
index 9dca501529..2d158c8 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-scrambled.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-scrambled.html
@@ -7,6 +7,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-side-reduction.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-side-reduction.html
index 1d456542..b98d6f9 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-side-reduction.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-side-reduction.html
@@ -10,6 +10,7 @@
             border-image-source: url("resources/border-image.png");
             border-image-slice: 21 30 30 21 fill;
             border-image-width: 30;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained.html
index f7e92fa1..48f9bb2 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained.html
@@ -9,6 +9,7 @@
             border-image-source: url("resources/border-image.png");
             border-image-repeat: repeat;
             display: inline-block;
+            border-style: solid;
         }
 
         div.tl {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-slices.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-slices.html
index d0e1cf6..a4af2b9 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-slices.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-slices.html
@@ -9,6 +9,7 @@
             display: inline-block;
             border-image-source: url("resources/border-image.png") !important;
             border-image-slice: 21 30 30 21 fill !important;
+            border-style: solid;
         }
 
         div.rr {
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-source.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-source.html
index c044698a..3a38be7 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-source.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-source.html
@@ -7,6 +7,7 @@
             height: 75px;
             margin: 10px;
             display: inline-block;
+            border-style: solid;
             border-image-source: url("resources/border-image.png") !important
         }
 
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius-expected.txt b/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius-expected.txt
index e06b616..f23c2fcc 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius-expected.txt
@@ -4,4 +4,4 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DIV} at (0,0) size 100x100 [bgcolor=#FF0000]
-      LayoutBlockFlow {DIV} at (0,0) size 100x100 [bgcolor=#FF0000] [border: (10px none #0000FF7F)]
+      LayoutBlockFlow {DIV} at (0,0) size 100x100 [bgcolor=#FF0000] [border: (10px solid #0000FF7F)]
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius.html
index d0b2cfd..f2132fdf 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-trumps-radius.html
@@ -8,4 +8,5 @@
     border-width: 10px;
     border-color: rgba(0, 0, 255, 0.5);
     -webkit-border-image: -webkit-linear-gradient(green, green) 10 10 10 10;
+    border-style: solid;
 "></div>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/scaled-border-image.html b/third_party/WebKit/LayoutTests/fast/borders/scaled-border-image.html
index 9a42758..2cfbf96 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/scaled-border-image.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/scaled-border-image.html
@@ -8,6 +8,7 @@
         border-image-slice: 21 30 30 21 fill;
         border-image-width: 1;
         border-image-repeat: repeat;
+        border-style: solid;
     }
 </style>
 <div></div>
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html
index 2e7a26d8..62e3074 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html
@@ -25,6 +25,7 @@
         var grid = document.getElementById("grid");
         grid.offsetTop;
         var embed = document.createElement("embed");
+        embed.setAttribute("type", "image/png");
         grid.appendChild(embed);
     </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns-expected.txt b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns-expected.txt
index 004409c..f1152773 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns-expected.txt
@@ -7,6 +7,7 @@
 PASS window.getComputedStyle(gridAutoMultipleItems, '').getPropertyValue('grid-template-columns') is "30px"
 PASS window.getComputedStyle(gridMinMaxAutoAutoMultipleItemsOneWithoutMinWidth, '').getPropertyValue('grid-template-columns') is "60px"
 PASS window.getComputedStyle(gridMinMaxAutoMaxContentMultipleItemsOneWithAutoMinWidth, '').getPropertyValue('grid-template-columns') is "80px"
+PASS window.getComputedStyle(gridAutoAndAutoFixedWidthChildren, '').getPropertyValue('grid-template-columns') is "200px 50px"
 
 Check that min-width is honored when sizing auto columns and spanning grid items.
 PASS window.getComputedStyle(gridAutoAndAutoOneSpanningOneNonSpannig, '').getPropertyValue('grid-template-columns') is "35px 15px"
@@ -18,10 +19,10 @@
 
 Check the interactions between width and min-width and auto tracks.
 PASS window.getComputedStyle(gridAutoWithFixedWidthChild, '').getPropertyValue('grid-template-columns') is "60px"
-PASS window.getComputedStyle(gridAutoWithFixedWidthChildAndMinWidth, '').getPropertyValue('grid-template-columns') is "40px"
+PASS window.getComputedStyle(gridAutoWithFixedWidthChildAndMinWidth, '').getPropertyValue('grid-template-columns') is "60px"
 PASS window.getComputedStyle(gridAutoWithFixedWidthChildAndHigherMinWidth, '').getPropertyValue('grid-template-columns') is "90px"
 PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedWidth, '').getPropertyValue('grid-template-columns') is "25px 25px"
-PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedWidthAndMinWidth, '').getPropertyValue('grid-template-columns') is "25px 25px"
+PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedWidthAndMinWidth, '').getPropertyValue('grid-template-columns') is "30px 30px"
 PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedWidthAndHigherMinWidth, '').getPropertyValue('grid-template-columns') is "35px 35px"
 
 Check that borders and paddings are considering when computing min sizes.
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns.html
index 6ab82778..b76d99f3 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-columns.html
@@ -15,6 +15,7 @@
 
 .width50 { width: 50px; }
 .width60 { width: 60px; }
+.width200 { width: 200px; }
 
 .border5 { border: 5px solid #abc; }
 .padding8 { padding: 0px 8px 0px; }
@@ -88,6 +89,15 @@
     </div>
 </div>
 
+
+<div class="constrainedContainer">
+    <div class="grid gridAutoAndAuto" id="gridAutoAndAutoFixedWidthChildren">
+	<div class="firstRowFirstColumn width200 minWidth50"></div>
+	<div class="firstRowSecondColumn width50"></div>
+    </div>
+</div>
+
+
 <div class="constrainedContainer">
     <div class="grid gridAutoAndAuto" id="gridAutoAndAutoOneSpanningOneNonSpannig">
 	<div class="firstRowFirstColumn">XX XX</div>
@@ -239,6 +249,7 @@
 testGridColumnsValues("gridAutoMultipleItems", "30px");
 testGridColumnsValues("gridMinMaxAutoAutoMultipleItemsOneWithoutMinWidth", "60px");
 testGridColumnsValues("gridMinMaxAutoMaxContentMultipleItemsOneWithAutoMinWidth", "80px");
+testGridColumnsValues("gridAutoAndAutoFixedWidthChildren", "200px 50px");
 
 debug("");
 debug("Check that min-width is honored when sizing auto columns and spanning grid items.");
@@ -252,10 +263,10 @@
 debug("");
 debug("Check the interactions between width and min-width and auto tracks.");
 testGridColumnsValues("gridAutoWithFixedWidthChild", "60px");
-testGridColumnsValues("gridAutoWithFixedWidthChildAndMinWidth", "40px");
+testGridColumnsValues("gridAutoWithFixedWidthChildAndMinWidth", "60px");
 testGridColumnsValues("gridAutoWithFixedWidthChildAndHigherMinWidth", "90px");
 testGridColumnsValues("gridAutoAndAutoOneSpanningFixedWidth", "25px 25px");
-testGridColumnsValues("gridAutoAndAutoOneSpanningFixedWidthAndMinWidth", "25px 25px");
+testGridColumnsValues("gridAutoAndAutoOneSpanningFixedWidthAndMinWidth", "30px 30px");
 testGridColumnsValues("gridAutoAndAutoOneSpanningFixedWidthAndHigherMinWidth", "35px 35px");
 
 debug("");
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows-expected.txt b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows-expected.txt
index 567c9c1..b4cd04b 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows-expected.txt
@@ -3,11 +3,12 @@
 PASS window.getComputedStyle(gridAuto, '').getPropertyValue('grid-template-rows') is "40px"
 PASS window.getComputedStyle(gridAutoItemSmallerThanMinSize, '').getPropertyValue('grid-template-rows') is "40px"
 PASS window.getComputedStyle(gridMinMaxAutoAuto, '').getPropertyValue('grid-template-rows') is "40px"
-PASS window.getComputedStyle(gridMinMaxAutoMaxContent, '').getPropertyValue('grid-template-rows') is "20px"
+PASS window.getComputedStyle(gridMinMaxAutoMaxContent, '').getPropertyValue('grid-template-rows') is "30px"
 PASS window.getComputedStyle(gridMinMaxMinContentAuto, '').getPropertyValue('grid-template-rows') is "60px"
 PASS window.getComputedStyle(gridAutoMultipleItems, '').getPropertyValue('grid-template-rows') is "60px"
 PASS window.getComputedStyle(gridMinMaxAutoAutoMultipleItemsOneWithoutMinHeight, '').getPropertyValue('grid-template-rows') is "50px"
 PASS window.getComputedStyle(gridMinMaxAutoMaxContentMultipleItemsOneWithAutoMinHeight, '').getPropertyValue('grid-template-rows') is "60px"
+PASS window.getComputedStyle(gridAutoAndAutoFixedHeightChildren, '').getPropertyValue('grid-template-rows') is "200px 50px"
 
 Check that min-height is honored when sizing auto rows and spanning grid items.
 PASS window.getComputedStyle(gridAutoAndAutoOneSpanningOneNonSpannig, '').getPropertyValue('grid-template-rows') is "10px 40px"
@@ -19,10 +20,10 @@
 
 Check the interactions between height and min-height and auto tracks.
 PASS window.getComputedStyle(gridAutoWithFixedHeightChild, '').getPropertyValue('grid-template-rows') is "60px"
-PASS window.getComputedStyle(gridAutoWithFixedHeightChildAndMinHeight, '').getPropertyValue('grid-template-rows') is "40px"
+PASS window.getComputedStyle(gridAutoWithFixedHeightChildAndMinHeight, '').getPropertyValue('grid-template-rows') is "60px"
 PASS window.getComputedStyle(gridAutoWithFixedHeightChildAndHigherMinHeight, '').getPropertyValue('grid-template-rows') is "90px"
 PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedHeight, '').getPropertyValue('grid-template-rows') is "25px 25px"
-PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedHeightAndMinHeight, '').getPropertyValue('grid-template-rows') is "25px 25px"
+PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedHeightAndMinHeight, '').getPropertyValue('grid-template-rows') is "30px 30px"
 PASS window.getComputedStyle(gridAutoAndAutoOneSpanningFixedHeightAndHigherMinHeight, '').getPropertyValue('grid-template-rows') is "35px 35px"
 
 Check that borders and paddings are considering when computing min sizes.
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows.html
index bea9c618..fb59455 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-automatic-minimum-for-auto-rows.html
@@ -16,6 +16,7 @@
 .height30 { height: 30px; }
 .height50 { height: 50px; }
 .height60 { height: 60px; }
+.height200 { height: 200px; }
 
 .border5 { border: 5px solid #abc; }
 .padding8 { padding: 8px 0px; }
@@ -74,9 +75,16 @@
 </div>
 
 <div class="constrainedContainer">
+    <div class="grid gridAutoAndAuto" id="gridAutoAndAutoFixedHeightChildren">
+       <div class="firstRowFirstColumn height200"></div>
+       <div class="secondRowFirstColumn height50"></div>
+    </div>
+</div>
+
+<div class="constrainedContainer">
     <div class="grid gridAutoAndAuto" id="gridAutoAndAutoOneSpanningOneNonSpannig">
-	<div class="firstRowFirstColumn">XX XX</div>
-	<div class="bothRowFirstColumn minHeight50">XXXXXX X XXX</div>
+        <div class="firstRowFirstColumn">XX XX</div>
+        <div class="bothRowFirstColumn minHeight50">XXXXXX X XXX</div>
     </div>
 </div>
 
@@ -220,11 +228,12 @@
 testGridRowsValues("gridAuto", "40px");
 testGridRowsValues("gridAutoItemSmallerThanMinSize", "40px");
 testGridRowsValues("gridMinMaxAutoAuto", "40px");
-testGridRowsValues("gridMinMaxAutoMaxContent", "20px");
+testGridRowsValues("gridMinMaxAutoMaxContent", "30px");
 testGridRowsValues("gridMinMaxMinContentAuto", "60px");
 testGridRowsValues("gridAutoMultipleItems", "60px");
 testGridRowsValues("gridMinMaxAutoAutoMultipleItemsOneWithoutMinHeight", "50px");
 testGridRowsValues("gridMinMaxAutoMaxContentMultipleItemsOneWithAutoMinHeight", "60px");
+testGridRowsValues("gridAutoAndAutoFixedHeightChildren", "200px 50px");
 
 debug("");
 debug("Check that min-height is honored when sizing auto rows and spanning grid items.");
@@ -238,10 +247,10 @@
 debug("");
 debug("Check the interactions between height and min-height and auto tracks.");
 testGridRowsValues("gridAutoWithFixedHeightChild", "60px");
-testGridRowsValues("gridAutoWithFixedHeightChildAndMinHeight", "40px");
+testGridRowsValues("gridAutoWithFixedHeightChildAndMinHeight", "60px");
 testGridRowsValues("gridAutoWithFixedHeightChildAndHigherMinHeight", "90px");
 testGridRowsValues("gridAutoAndAutoOneSpanningFixedHeight", "25px 25px");
-testGridRowsValues("gridAutoAndAutoOneSpanningFixedHeightAndMinHeight", "25px 25px");
+testGridRowsValues("gridAutoAndAutoOneSpanningFixedHeightAndMinHeight", "30px 30px");
 testGridRowsValues("gridAutoAndAutoOneSpanningFixedHeightAndHigherMinHeight", "35px 35px");
 
 debug("");
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDocument/document-plugins-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLDocument/document-plugins-expected.txt
index 102825f..cb2dcbc3 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLDocument/document-plugins-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDocument/document-plugins-expected.txt
@@ -3,5 +3,3 @@
 If the test passes, you will see a pass message below.
 
 PASS
-
- 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-child.html b/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-child.html
index 37c2942..1ecd4a4d 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-child.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-child.html
@@ -25,6 +25,7 @@
 
     embed = document.createElement("embed");
     embed.setAttribute("width", 2);
+    embed.setAttribute("type", "image/png");
     object.appendChild(embed);
     
     document.body.appendChild(object);
diff --git a/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-sibling.html b/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-sibling.html
index a4f53d5..8ef507f 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-sibling.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/insertedIntoDocument-sibling.html
@@ -21,6 +21,7 @@
     
     object.innerHTML = "<embed width=\"2\"/><element id=\"foo\"/>";
     embed = object.firstChild;
+    embed.setAttribute("type", "image/png");
     
     attr = document.createAttribute("width");
     object.setAttributeNode(attr);
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.txt b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.txt
index 63dc708..f9a7cf98 100644
--- a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.txt
@@ -3,4 +3,4 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,10) size 784x580
-      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient.html b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient.html
index f6123f41..458ccc3 100644
--- a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient.html
+++ b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient.html
@@ -7,10 +7,11 @@
             height: 75px;
             margin: 10px;
             -webkit-border-image: -webkit-gradient(linear, left top, left bottom, from(#00abeb), to(#fff), color-stop(0.5, #fff), color-stop(0.5, #66cc00)) 21 30 30 21 repeat repeat;
+            border-style: solid;
         }
     </style>
 </head>
 <body>
     <div></div>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison-expected.html b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison-expected.html
index 35b6768..b65499d 100644
--- a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison-expected.html
+++ b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison-expected.html
@@ -6,6 +6,7 @@
 	box-sizing: border-box;
     width: 40px;
     height: 13px;
+    border-style: solid;
 }
 
 .test1 {
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison.html b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison.html
index 40a8688..741318db 100644
--- a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison.html
+++ b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-border-image-comparison.html
@@ -6,6 +6,7 @@
 	box-sizing: border-box;
     width: 40px;
     height: 13px;
+    border-style: solid;
 }
 
 .test1 {
diff --git a/third_party/WebKit/LayoutTests/fast/images/webp-flip-expected.png b/third_party/WebKit/LayoutTests/fast/images/webp-flip-expected.png
new file mode 100644
index 0000000..2361a9f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/images/webp-flip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/images/webp-flip-expected.txt b/third_party/WebKit/LayoutTests/fast/images/webp-flip-expected.txt
similarity index 70%
rename from third_party/WebKit/LayoutTests/platform/mac-retina/fast/images/webp-flip-expected.txt
rename to third_party/WebKit/LayoutTests/fast/images/webp-flip-expected.txt
index 73cb718..826935c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/images/webp-flip-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/images/webp-flip-expected.txt
@@ -3,4 +3,4 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow {P} at (0,0) size 162.80x6 [border: (3px none #000000)]
+      LayoutBlockFlow {P} at (0,0) size 162.80x6 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/fast/images/webp-flip.html b/third_party/WebKit/LayoutTests/fast/images/webp-flip.html
index 70f1919..8c1a8b1 100644
--- a/third_party/WebKit/LayoutTests/fast/images/webp-flip.html
+++ b/third_party/WebKit/LayoutTests/fast/images/webp-flip.html
@@ -1,2 +1,2 @@
 <!--test case for crbug.com/390069 -->
-<p style="width: 20%; border-image: url('flip.webp') 101 repeat">
+<p style="width: 20%; border-style: solid; border-image: url('flip.webp') 101 repeat">
diff --git a/third_party/WebKit/LayoutTests/fast/js/JSON-parse-expected.txt b/third_party/WebKit/LayoutTests/fast/js/JSON-parse-expected.txt
index 24fc96c..9cbf3b81 100644
--- a/third_party/WebKit/LayoutTests/fast/js/JSON-parse-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/js/JSON-parse-expected.txt
@@ -1,11 +1,11 @@
 function (jsonObject){
         return jsonObject.parse();
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token u.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token u in JSON at position 0.
 function (jsonObject){
         return jsonObject.parse('');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected end of input.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected end of JSON input.
 function (jsonObject){
         return jsonObject.parse('1');
     }
@@ -17,11 +17,11 @@
 function (jsonObject){
         return jsonObject.parse('Infinity');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token I.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token I in JSON at position 0.
 function (jsonObject){
         return jsonObject.parse('NaN');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token N.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token N in JSON at position 0.
 function (jsonObject){
         return jsonObject.parse('null');
     }
@@ -29,7 +29,7 @@
 function (jsonObject){
         return jsonObject.parse('undefined');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token u.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token u in JSON at position 0.
 function (jsonObject){
         return jsonObject.parse('{}');
     }
@@ -37,31 +37,31 @@
 function (jsonObject){
         return jsonObject.parse('({})');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token (.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ( in JSON at position 0.
 function (jsonObject){
         return jsonObject.parse('{a}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('{a:}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('{a:5}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('{a:5,}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('{"a"}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token }.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token } in JSON at position 4.
 function (jsonObject){
         return jsonObject.parse('{"a":}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token }.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token } in JSON at position 5.
 function (jsonObject){
         return jsonObject.parse('{"a":5}');
     }
@@ -73,20 +73,20 @@
 function (jsonObject){
         return jsonObject.parse('{"a":5,}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token }.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token } in JSON at position 7.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('{"a":5,,}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token , in JSON at position 7.
 function (jsonObject){
         return jsonObject.parse('{"a":5,"a",}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token , in JSON at position 10.
 function (jsonObject){
         return jsonObject.parse('{"a":(5,"a"),}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token (.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ( in JSON at position 5.
 function (jsonObject){
         return jsonObject.parse('[]');
     }
@@ -98,7 +98,7 @@
 function (jsonObject){
         return jsonObject.parse('[1,]');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ].
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ] in JSON at position 3.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('[1,2]');
@@ -107,12 +107,12 @@
 function (jsonObject){
         return jsonObject.parse('[1,2,,]');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token , in JSON at position 5.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('[1,2,,4]');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token , in JSON at position 5.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('""');
@@ -129,15 +129,15 @@
 function (jsonObject){
         return jsonObject.parse('"a\\"');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected end of input.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected end of JSON input.
 function (jsonObject){
         return jsonObject.parse('"a\\z"');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z in JSON at position 3.
 function (jsonObject){
         return jsonObject.parse('"a\\\z"');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z in JSON at position 3.
 function (jsonObject){
         return jsonObject.parse('"a\\\\z"');
     }
@@ -145,7 +145,7 @@
 function (jsonObject){
         return jsonObject.parse('"a\tz"');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 	.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 	 in JSON at position 2.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('"a\\tz"');
@@ -155,7 +155,7 @@
         return jsonObject.parse('"a\nz"');
     }
 PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 
-.
+ in JSON at position 2.
 function (jsonObject){
         return jsonObject.parse('"a\\nz"');
     }
@@ -164,7 +164,7 @@
         return jsonObject.parse('"a\rz"');
     }
 PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 
-.
+ in JSON at position 2.
 function (jsonObject){
         return jsonObject.parse('"a\\rz"');
     }
@@ -180,7 +180,7 @@
 function (jsonObject){
         return jsonObject.parse('"a\bz"');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token .
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token  in JSON at position 2.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('"a\\bz"');
@@ -190,7 +190,7 @@
         return jsonObject.parse('"a\rz"');
     }
 PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 
-.
+ in JSON at position 2.
 function (jsonObject){
         return jsonObject.parse('"a\\rz"');
     }
@@ -198,19 +198,19 @@
 function (jsonObject){
         return jsonObject.parse('"a\\uz"     ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z in JSON at position 4.
 function (jsonObject){
         return jsonObject.parse('"a\\u0z"    ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z in JSON at position 5.
 function (jsonObject){
         return jsonObject.parse('"a\\u00z"   ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z in JSON at position 6.
 function (jsonObject){
         return jsonObject.parse('"a\\u000z"  ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z in JSON at position 7.
 function (jsonObject){
         return jsonObject.parse('"a\\u0000z" ');
     }
@@ -226,11 +226,11 @@
 function (jsonObject){
         return jsonObject.parse('"a\\u000Gz" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G in JSON at position 7.
 function (jsonObject){
         return jsonObject.parse('"a\\u000gz" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g in JSON at position 7.
 function (jsonObject){
         return jsonObject.parse('"a\\u00A0z" ');
     }
@@ -242,11 +242,11 @@
 function (jsonObject){
         return jsonObject.parse('"a\\u00G0z" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G in JSON at position 6.
 function (jsonObject){
         return jsonObject.parse('"a\\u00g0z" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g in JSON at position 6.
 function (jsonObject){
         return jsonObject.parse('"a\\u0A00z" ');
     }
@@ -258,11 +258,11 @@
 function (jsonObject){
         return jsonObject.parse('"a\\u0G00z" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G in JSON at position 5.
 function (jsonObject){
         return jsonObject.parse('"a\\u0g00z" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g in JSON at position 5.
 function (jsonObject){
         return jsonObject.parse('"a\\uA000z" ');
     }
@@ -274,71 +274,71 @@
 function (jsonObject){
         return jsonObject.parse('"a\\uG000z" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G in JSON at position 4.
 function (jsonObject){
         return jsonObject.parse('"a\\ug000z" ');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g in JSON at position 4.
 function (jsonObject){
         return jsonObject.parse('00');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number in JSON at position 1.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('01');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number in JSON at position 1.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('0.a');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a in JSON at position 2.
 function (jsonObject){
         return jsonObject.parse('0x0');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token x.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token x in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('2e1.3');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ..
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token . in JSON at position 3.
 function (jsonObject){
         return jsonObject.parse('2e-+10');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token +.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token + in JSON at position 3.
 function (jsonObject){
         return jsonObject.parse('2e+-10');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number in JSON at position 3.
 function (jsonObject){
         return jsonObject.parse('2e3e4');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token e.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token e in JSON at position 3.
 function (jsonObject){
         return jsonObject.parse('-01.0');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number in JSON at position 2.
 function (jsonObject){
         return jsonObject.parse('-01');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number in JSON at position 2.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('-01.a');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number in JSON at position 2.
 function (jsonObject){
         return jsonObject.parse('1.e1');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token e.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token e in JSON at position 2.
 json2.js did not throw for a test we expect to throw.
 function (jsonObject){
         return jsonObject.parse('{/* block comments are not allowed */}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token /.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token / in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('{// line comments are not allowed \n}');
     }
-PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token /.
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token / in JSON at position 1.
 function (jsonObject){
         return jsonObject.parse('true');
     }
diff --git a/third_party/WebKit/LayoutTests/fast/js/invalid-syntax-for-function-expected.txt b/third_party/WebKit/LayoutTests/fast/js/invalid-syntax-for-function-expected.txt
index dc56c4c..f45d880 100644
--- a/third_party/WebKit/LayoutTests/fast/js/invalid-syntax-for-function-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/js/invalid-syntax-for-function-expected.txt
@@ -1,3 +1,3 @@
-CONSOLE ERROR: line 1: Uncaught SyntaxError: Unexpected token ILLEGAL
+CONSOLE ERROR: line 1: Uncaught SyntaxError: Invalid or unexpected token
 This test ensures we don't crash when we are given garbage for an attribute expecting a function.
 https://bugs.webkit.org/show_bug.cgi?id=19025
diff --git a/third_party/WebKit/LayoutTests/fast/js/kde/string-1-n-expected.txt b/third_party/WebKit/LayoutTests/fast/js/kde/string-1-n-expected.txt
index a91ed0de..a0eec4a 100644
--- a/third_party/WebKit/LayoutTests/fast/js/kde/string-1-n-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/js/kde/string-1-n-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: line 1: Uncaught SyntaxError: Unexpected token ILLEGAL
+CONSOLE ERROR: line 1: Uncaught SyntaxError: Invalid or unexpected token
 KDE JS Test
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/js/kde/string-2-n-expected.txt b/third_party/WebKit/LayoutTests/fast/js/kde/string-2-n-expected.txt
index a91ed0de..a0eec4a 100644
--- a/third_party/WebKit/LayoutTests/fast/js/kde/string-2-n-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/js/kde/string-2-n-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: line 1: Uncaught SyntaxError: Unexpected token ILLEGAL
+CONSOLE ERROR: line 1: Uncaught SyntaxError: Invalid or unexpected token
 KDE JS Test
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/regex/non-pattern-characters-expected.txt b/third_party/WebKit/LayoutTests/fast/regex/non-pattern-characters-expected.txt
index ee54c5c..933e623 100644
--- a/third_party/WebKit/LayoutTests/fast/regex/non-pattern-characters-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/regex/non-pattern-characters-expected.txt
@@ -51,7 +51,7 @@
 PASS regexp.lastIndex is 2
 
 Testing regexp: [invalid * variations]
-PASS /*/ threw exception SyntaxError: Unexpected token ILLEGAL.
+PASS /*/ threw exception SyntaxError: Invalid or unexpected token.
 PASS /^*/ threw exception SyntaxError: Invalid regular expression: /^*/: Nothing to repeat.
 
 Testing regexp: /a+/gm
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/border-outline-0.html b/third_party/WebKit/LayoutTests/fast/repaint/border-outline-0.html
index 0f6dbe083..25960c6 100644
--- a/third_party/WebKit/LayoutTests/fast/repaint/border-outline-0.html
+++ b/third_party/WebKit/LayoutTests/fast/repaint/border-outline-0.html
@@ -21,6 +21,7 @@
     position: absolute;
     top: 10px;
     left: 10px;
+    border-style: solid;
 }
 </style>
 
diff --git a/third_party/WebKit/LayoutTests/fast/replaced/outline-replaced-elements.html b/third_party/WebKit/LayoutTests/fast/replaced/outline-replaced-elements.html
index 36963ca7..5a0fecb 100644
--- a/third_party/WebKit/LayoutTests/fast/replaced/outline-replaced-elements.html
+++ b/third_party/WebKit/LayoutTests/fast/replaced/outline-replaced-elements.html
@@ -37,7 +37,7 @@
  &lt;iframe&gt;
   <iframe src="resources/square-blue-100x100.png"></iframe>
  &lt;embed&gt;
-  <embed data="resources/square-blue-100x100.png">
+  <embed src="resources/square-blue-100x100.png" type="image/png">
  &lt;object&gt;
   <object src="resources/square-blue-100x100.png"></object>
 </div>
diff --git a/third_party/WebKit/LayoutTests/fast/replaced/percent-height-in-anonymous-block-widget.html b/third_party/WebKit/LayoutTests/fast/replaced/percent-height-in-anonymous-block-widget.html
index 3510e562..088cd862 100644
--- a/third_party/WebKit/LayoutTests/fast/replaced/percent-height-in-anonymous-block-widget.html
+++ b/third_party/WebKit/LayoutTests/fast/replaced/percent-height-in-anonymous-block-widget.html
@@ -5,7 +5,7 @@
     </p>
     <div style="height: 50px; background: blue; width: 100px;" id="target">
         <div></div>
-        <embed id="object" style="height: 100%;">
+        <embed id="object" style="height: 100%;" type="image/png">
     </div>
 </body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/fast/replaced/replaced-breaking.html b/third_party/WebKit/LayoutTests/fast/replaced/replaced-breaking.html
index 51a9b3b..1368c31 100644
--- a/third_party/WebKit/LayoutTests/fast/replaced/replaced-breaking.html
+++ b/third_party/WebKit/LayoutTests/fast/replaced/replaced-breaking.html
@@ -15,7 +15,7 @@
         <input type="checkbox"><input type="checkbox">
         <input type="radio"><input type="radio">
         <iframe></iframe><iframe></iframe>
-        <embed></embed><embed></embed>
+        <embed type="image/png"></embed><embed type="image/png"></embed>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/replaced/table-percent-height.html b/third_party/WebKit/LayoutTests/fast/replaced/table-percent-height.html
index 10611ac8..fce47a1 100644
--- a/third_party/WebKit/LayoutTests/fast/replaced/table-percent-height.html
+++ b/third_party/WebKit/LayoutTests/fast/replaced/table-percent-height.html
@@ -139,8 +139,8 @@
 <table><tr><td><canvas id="canvas-75" style="background-color: #00ff00; height: 75%;"></canvas></td></tr></table>
 <table><tr><td><canvas id="canvas-100" style="background-color: #00ff00; height: 100%;"></canvas></td></tr></table>
 
-<table><tr><td><embed id="embed-75" style="background-color: #00ff00; height: 75%;"></embed></td></tr></table>
-<table><tr><td><embed id="embed-100" style="background-color: #00ff00; height: 100%;"></embed></td></tr></table>
+<table><tr><td><embed id="embed-75" style="background-color: #00ff00; height: 75%;" type="image/foo"></embed></td></tr></table>
+<table><tr><td><embed id="embed-100" style="background-color: #00ff00; height: 100%;" type="image/bar"></embed></td></tr></table>
 
 <table><tr><td><img id="img-75" src="resources/square-blue-100x100.png" style="height: 75%;"></td></tr></table>
 <table><tr><td><img id="img-100" src="resources/square-blue-100x100.png" style="height: 100%;"></td></tr></table>
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-lr.html b/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-lr.html
index ac20181..f6b73ea 100644
--- a/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-lr.html
+++ b/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-lr.html
@@ -6,6 +6,7 @@
     font-size:86px;
     margin: 30px;
     -webkit-border-image: url("../borders/resources/border-image.png") 21 30 30 21 repeat repeat;
+    border-style: solid;
 }
 </style>
 </head>
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-rl.html b/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-rl.html
index 919b349..61fcc437 100644
--- a/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-rl.html
+++ b/third_party/WebKit/LayoutTests/fast/writing-mode/border-image-vertical-rl.html
@@ -6,6 +6,7 @@
     font-size:86px;
     margin: 30px;
     -webkit-border-image: url("../borders/resources/border-image.png") 21 30 30 21 repeat repeat;
+    border-style: solid;
 }
 </style>
 </head>
diff --git a/third_party/WebKit/LayoutTests/http/tests/linkHeader/link-rel-import-css-rule-capital.html b/third_party/WebKit/LayoutTests/http/tests/linkHeader/link-rel-import-css-rule-capital.html
new file mode 100644
index 0000000..e65fb67
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/linkHeader/link-rel-import-css-rule-capital.html
@@ -0,0 +1,26 @@
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+
+<style>
+#target2 { color: 008000; }
+</style>
+
+<link rel="import" href="data:text/html,<style>.test .testWithCapital { background-color: green; } .test .testwithoutcapital { border: 2px green; } #target2 { color: ff0000 } #tArGeT1 { color: green }</style>">
+<div class="test">
+  <div id="target1" class="testwithoutcapital testWithCapital"></div>
+</div>
+<div id="target2"></div>
+
+<script>
+var green = "rgb(0, 128, 0)";
+
+test(function() {
+  assert_equals(getComputedStyle(target1).color, green);
+  assert_equals(getComputedStyle(target1).borderColor, green);
+  assert_equals(getComputedStyle(target1).backgroundColor, green);
+}, "Test that rules with capital letters in <link rel=import> are not ignored");
+
+test(function() {
+  assert_equals(getComputedStyle(target2).color, green);
+}, "Test that rules in <link rel=import> are parsed in strict mode");
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt b/third_party/WebKit/LayoutTests/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt
index e21f673..f59b36e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt
@@ -5,9 +5,9 @@
 PASS new WebSocket("ws://127.0.0.1:8880/simple", "\0") threw exception SyntaxError: Failed to construct 'WebSocket': The subprotocol '\u0000' is invalid..
 PASS new WebSocket("ws://127.0.0.1:8880/simple", "	") threw exception SyntaxError: Failed to construct 'WebSocket': The subprotocol '\u0009' is invalid..
 PASS new WebSocket("ws://127.0.0.1:8880/simple", "
-") threw exception SyntaxError: Unexpected token ILLEGAL.
+") threw exception SyntaxError: Invalid or unexpected token.
 PASS new WebSocket("ws://127.0.0.1:8880/simple", "
-") threw exception SyntaxError: Unexpected token ILLEGAL.
+") threw exception SyntaxError: Invalid or unexpected token.
 PASS new WebSocket("ws://127.0.0.1:8880/simple", "") threw exception SyntaxError: Failed to construct 'WebSocket': The subprotocol '\u001B' is invalid..
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/documents/dom-tree-accessors/document.title-09-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/documents/dom-tree-accessors/document.title-09-expected.txt
new file mode 100644
index 0000000..1bd121d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/documents/dom-tree-accessors/document.title-09-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL No title element in SVG document assert_equals: expected "title" but got "x-child"
+FAIL Title element in SVG document assert_equals: expected "foobar" but got "foo"
+FAIL Title element not child of SVG root assert_equals: expected "" but got "foo"
+FAIL Title element not in SVG namespace assert_equals: expected "" but got "foo"
+FAIL Root element not named "svg" assert_equals: expected "" but got "foo"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/document-all-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/document-all-expected.txt
deleted file mode 100644
index 52ce6b8..0000000
--- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/document-all-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL 'unusual behaviors' of document.all assert_equals: expected "undefined" but got "object"
-FAIL 'unusual behaviors' of document.all with assignment assert_equals: expected "undefined" but got "object"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/stepping-with-blackboxed-ranges-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/stepping-with-blackboxed-ranges-expected.txt
index a871bfa..a1b1e067 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/stepping-with-blackboxed-ranges-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/stepping-with-blackboxed-ranges-expected.txt
@@ -25,12 +25,12 @@
 testFunction: 9:4
 
 action: stepInto
-notBlackboxedBoo: 16:4
+notBlackboxedBoo: 16:12
 testFunction: 9:4
 
 action: stepOver
 action: stepInto
-notBlackboxedFoo: 2:4
+notBlackboxedFoo: 2:12
 blackboxedFoo: 10:12
 notBlackboxedBoo: 17:12
 testFunction: 9:4
diff --git a/third_party/WebKit/LayoutTests/inspector/console/alert-toString-exception-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/alert-toString-exception-expected.txt
index b2251a6d..b13fa7b 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/alert-toString-exception-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/alert-toString-exception-expected.txt
@@ -3,5 +3,5 @@
 Test that browser won't crash if inspector is opened for a page that fails to convert alert() argument to string. The test passes if it doesn't crash. Bug 60541
 
 Page reloaded.
-alert-toString-exception.html:6 Uncaught Exception in toString().alert.toString @ alert-toString-exception.html:6(anonymous function) @ alert-toString-exception.html:6
+alert-toString-exception.html:6 Uncaught Exception in toString().toString @ alert-toString-exception.html:6(anonymous function) @ alert-toString-exception.html:6
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-control-characters-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-control-characters-expected.txt
index c840aac3..97fbb83 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-control-characters-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-control-characters-expected.txt
@@ -1,5 +1,5 @@
 Verify that control characters are substituted with printable characters.
 
 var� i = 0;
- Uncaught SyntaxError: Unexpected token ILLEGAL(…)
+ Uncaught SyntaxError: Invalid or unexpected token(…)
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-eval-scoped-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-eval-scoped-expected.txt
index 0208a3f5..02042e71 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-eval-scoped-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-eval-scoped-expected.txt
@@ -21,7 +21,7 @@
     enumerable : true
     get : {
         className : "Function"
-        description : "function getter() { }"
+        description : "function get getter() { }"
         objectId : <string>
         type : "function"
     }
@@ -41,7 +41,7 @@
     name : "setter"
     set : {
         className : "Function"
-        description : "function setter(_) { }"
+        description : "function set setter(_) { }"
         objectId : <string>
         type : "function"
     }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-format-es6-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-format-es6-expected.txt
index 05b5249..10717ee4 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-format-es6-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-format-es6-expected.txt
@@ -50,7 +50,7 @@
 console-format-es6.html:11 Object {a: Symbol(), Symbol(a): 2}
     a: Symbol()
     getter: (...)
-    get getter: getter()
+    get getter: get getter()
     Symbol(a): 2
     __proto__: Object
 console-format-es6.html:12 [Object]
@@ -61,7 +61,7 @@
 Object {a: Symbol(), Symbol(a): 2}
     a: Symbol()
     getter: (...)
-    get getter: getter()
+    get getter: get getter()
     Symbol(a): 2
     __proto__: Object
 console-format-es6.html:11 Map {Object {a: Symbol(), Symbol(a): 2} => Object {foo: 1}}
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-object-constructor-name-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-object-constructor-name-expected.txt
index 3301d61..25eb402 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-object-constructor-name-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-object-constructor-name-expected.txt
@@ -5,5 +5,5 @@
 
 console-object-constructor-name.html:12 Parent
 console-object-constructor-name.html:13 Child
-console-object-constructor-name.html:14 outer.inner
+console-object-constructor-name.html:14 inner
 
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties-expected.txt b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties-expected.txt
index 338d884..5a92b89 100644
--- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties-expected.txt
@@ -7,14 +7,14 @@
 {
     enumerable : true
     getter : {
-        description : "function () { return 1; }"
+        description : "function get foo() { return 1; }"
         objectId : <string>
         type : "function"
     }
     isOwn : true
     name : "foo"
     setter : {
-        description : "function (value) { }"
+        description : "function set foo(value) { }"
         objectId : <string>
         type : "function"
     }
@@ -27,7 +27,7 @@
 {
     enumerable : true
     getter : {
-        description : "function () { return 1; }"
+        description : "function get foo() { return 1; }"
         objectId : <string>
         type : "function"
     }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-jquery-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-jquery-expected.txt
index 719ce495..1112589 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-jquery-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-jquery-expected.txt
@@ -12,31 +12,31 @@
 Executing StepInto...
 Call stack:
     0) onEachScript (frameworks-jquery.html:39)
-  * 1) m.extend.each (jquery-1.11.1.min.js:2)
-  * 2) m.fn.m.each (jquery-1.11.1.min.js:2)
+  * 1) each (jquery-1.11.1.min.js:2)
+  * 2) each (jquery-1.11.1.min.js:2)
     3) testFunction (frameworks-jquery.html:18)
 
 Executing StepInto...
 Executing StepInto...
 Call stack:
     0) onEachScript (frameworks-jquery.html:39)
-  * 1) m.extend.each (jquery-1.11.1.min.js:2)
-  * 2) m.fn.m.each (jquery-1.11.1.min.js:2)
+  * 1) each (jquery-1.11.1.min.js:2)
+  * 2) each (jquery-1.11.1.min.js:2)
     3) testFunction (frameworks-jquery.html:18)
 
 Executing StepOver...
 Executing StepOver...
 Call stack:
     0) onEachScript (frameworks-jquery.html:39)
-  * 1) m.extend.each (jquery-1.11.1.min.js:2)
-  * 2) m.fn.m.each (jquery-1.11.1.min.js:2)
+  * 1) each (jquery-1.11.1.min.js:2)
+  * 2) each (jquery-1.11.1.min.js:2)
     3) testFunction (frameworks-jquery.html:18)
 
 Executing StepOut...
 Call stack:
     0) onEachScript (frameworks-jquery.html:39)
-  * 1) m.extend.each (jquery-1.11.1.min.js:2)
-  * 2) m.fn.m.each (jquery-1.11.1.min.js:2)
+  * 1) each (jquery-1.11.1.min.js:2)
+  * 2) each (jquery-1.11.1.min.js:2)
     3) testFunction (frameworks-jquery.html:18)
 
 Executing StepOut...
@@ -46,38 +46,38 @@
 Executing StepInto...
 Call stack:
     0) onTestEvent1 (frameworks-jquery.html:24)
-  * 1) m.event.dispatch (jquery-1.11.1.min.js:3)
+  * 1) dispatch (jquery-1.11.1.min.js:3)
   * 2) r.handle (jquery-1.11.1.min.js:3)
-  * 3) m.event.trigger (jquery-1.11.1.min.js:3)
+  * 3) trigger (jquery-1.11.1.min.js:3)
   * 4)  (jquery-1.11.1.min.js:3)
-  * 5) m.extend.each (jquery-1.11.1.min.js:2)
-  * 6) m.fn.m.each (jquery-1.11.1.min.js:2)
-  * 7) m.fn.extend.trigger (jquery-1.11.1.min.js:3)
+  * 5) each (jquery-1.11.1.min.js:2)
+  * 6) each (jquery-1.11.1.min.js:2)
+  * 7) trigger (jquery-1.11.1.min.js:3)
     8) testFunction (frameworks-jquery.html:19)
 
 Executing StepOut...
 Call stack:
     0) onTestEvent2 (frameworks-jquery.html:29)
-  * 1) m.event.dispatch (jquery-1.11.1.min.js:3)
+  * 1) dispatch (jquery-1.11.1.min.js:3)
   * 2) r.handle (jquery-1.11.1.min.js:3)
-  * 3) m.event.trigger (jquery-1.11.1.min.js:3)
+  * 3) trigger (jquery-1.11.1.min.js:3)
   * 4)  (jquery-1.11.1.min.js:3)
-  * 5) m.extend.each (jquery-1.11.1.min.js:2)
-  * 6) m.fn.m.each (jquery-1.11.1.min.js:2)
-  * 7) m.fn.extend.trigger (jquery-1.11.1.min.js:3)
+  * 5) each (jquery-1.11.1.min.js:2)
+  * 6) each (jquery-1.11.1.min.js:2)
+  * 7) trigger (jquery-1.11.1.min.js:3)
     8) testFunction (frameworks-jquery.html:19)
 
 Executing StepOver...
 Executing StepOver...
 Call stack:
     0) onTestEvent3 (frameworks-jquery.html:34)
-  * 1) m.event.dispatch (jquery-1.11.1.min.js:3)
+  * 1) dispatch (jquery-1.11.1.min.js:3)
   * 2) r.handle (jquery-1.11.1.min.js:3)
-  * 3) m.event.trigger (jquery-1.11.1.min.js:3)
+  * 3) trigger (jquery-1.11.1.min.js:3)
   * 4)  (jquery-1.11.1.min.js:3)
-  * 5) m.extend.each (jquery-1.11.1.min.js:2)
-  * 6) m.fn.m.each (jquery-1.11.1.min.js:2)
-  * 7) m.fn.extend.trigger (jquery-1.11.1.min.js:3)
+  * 5) each (jquery-1.11.1.min.js:2)
+  * 6) each (jquery-1.11.1.min.js:2)
+  * 7) trigger (jquery-1.11.1.min.js:3)
     8) testFunction (frameworks-jquery.html:19)
 
 
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-details-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-details-expected.txt
index 805f304a..0c6e642 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-details-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-details-expected.txt
@@ -27,7 +27,7 @@
 lineNumber: 16
 columnNumber: 15
 scriptId is valid: true
-functionName: obj.m
+functionName: m
 isGenerator: false
 scopeChain #0: global; <global object properties omitted>
 
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-generator-details-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-generator-details-expected.txt
index 4e8ca17..e043b9d2 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-generator-details-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/function-generator-details-expected.txt
@@ -27,7 +27,7 @@
 
 Running: testIterObjGenerator
 iterObjGenerator: type = object, subtype = generator
-functionName: "obj.generator"
+functionName: "generator"
 lineNumber: 25
 columnNumber: 8
 scriptId is valid: true
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/block/float/4145535Crash-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/block/float/4145535Crash-expected.txt
new file mode 100644
index 0000000..9e953bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/block/float/4145535Crash-expected.txt
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow (anonymous) at (0,0) size 784x150
+      LayoutTable {TABLE} at (0,150) size 0x0
+layer at (8,8) size 300x150
+  LayoutEmbeddedObject {EMBED} at (0,0) size 300x150
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-01-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-01-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-01-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-border-radius-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-border-radius-expected.txt
new file mode 100644
index 0000000..235e337
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-border-radius-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutText {#text} at (0,131) size 504x19
+        text run at (0,131) width 504: "This test checks to make sure the border-image is not clipped by the border radius. "
+      LayoutBlockFlow {DIV} at (513.67,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,312) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,433) size 4x19
+        text run at (146,433) width 4: " "
+      LayoutBlockFlow {DIV} at (160,312) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-longhand-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-longhand-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-longhand-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-massive-scale-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-massive-scale-expected.txt
new file mode 100644
index 0000000..7a4be60
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-massive-scale-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600 scrollHeight 726
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x726 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x726
+    LayoutBlockFlow {BODY} at (8,8) size 784x710
+      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutText {#text} at (350,335) size 4x19
+        text run at (350,335) width 4: " "
+      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutText {#text} at (704,335) size 4x19
+        text run at (704,335) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,365) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutText {#text} at (350,690) size 4x19
+        text run at (350,690) width 4: " "
+      LayoutBlockFlow {DIV} at (364,365) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-omit-right-slice-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-omit-right-slice-expected.txt
new file mode 100644
index 0000000..a56f63ad
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-omit-right-slice-expected.txt
@@ -0,0 +1,7 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x416
+  LayoutBlockFlow {HTML} at (0,0) size 800x416
+    LayoutBlockFlow {BODY} at (8,8) size 784x400
+      LayoutBlockFlow {DIV} at (0,0) size 400x400 [border: (100px none #000000)]
+        LayoutBlockFlow {DIV} at (100,100) size 200x200 [bgcolor=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-expected.txt
new file mode 100644
index 0000000..52233d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (186,171) size 4x19
+        text run at (186,171) width 4: " "
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (376,171) size 4x19
+        text run at (376,171) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (30,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (186,362) size 4x19
+        text run at (186,362) width 4: " "
+      LayoutBlockFlow {DIV} at (220,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-in-shorthand-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-in-shorthand-expected.txt
new file mode 100644
index 0000000..52233d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-in-shorthand-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (186,171) size 4x19
+        text run at (186,171) width 4: " "
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (376,171) size 4x19
+        text run at (376,171) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (30,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (186,362) size 4x19
+        text run at (186,362) width 4: " "
+      LayoutBlockFlow {DIV} at (220,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-split-inline-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-split-inline-expected.txt
new file mode 100644
index 0000000..3cc218a3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-outset-split-inline-expected.txt
@@ -0,0 +1,12 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (0,0) size 784x350
+        LayoutInline {SPAN} at (0,0) size 36x230 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+          LayoutText {#text} at (46,85) size 6x29
+            text run at (46,85) width 6: " "
+          LayoutBR {BR} at (52,108) size 0x0
+          LayoutText {#text} at (25,235) size 6x29
+            text run at (25,235) width 6: " "
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-repeat-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-repeat-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-repeat-round-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-repeat-round-expected.txt
new file mode 100644
index 0000000..b417721
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-repeat-round-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (154,116) size 4x19
+        text run at (154,116) width 4: " "
+      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (312,116) size 4x19
+        text run at (312,116) width 4: " "
+      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (470,116) size 4x19
+        text run at (470,116) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,146) size 113x90 [border: (15px solid #00000000)]
+      LayoutText {#text} at (133,231) size 4x19
+        text run at (133,231) width 4: " "
+      LayoutBlockFlow {DIV} at (147,146) size 113x90 [border: (15px solid #00000000)]
+      LayoutText {#text} at (270,231) size 4x19
+        text run at (270,231) width 4: " "
+      LayoutBlockFlow {DIV} at (284,146) size 113x90 [border: (15px solid #00000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-rotate-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-rotate-transform-expected.txt
new file mode 100644
index 0000000..8ed98f0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-rotate-transform-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600 scrollWidth 824 scrollHeight 731
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+layer at (8,8) size 784x584
+  LayoutBlockFlow {BODY} at (8,8) size 784x584
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (146,131) size 4x19
+      text run at (146,131) width 4: " "
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (296,131) size 4x19
+      text run at (296,131) width 4: " "
+    LayoutBR {BR} at (0,0) size 0x0
+    LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (146,282) size 4x19
+      text run at (146,282) width 4: " "
+    LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scale-transform-expected.txt
new file mode 100644
index 0000000..14d7d9d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scale-transform-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600 scrollWidth 1576 scrollHeight 1192
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+layer at (8,8) size 784x584
+  LayoutBlockFlow {BODY} at (8,8) size 784x584
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (146,131) size 4x19
+      text run at (146,131) width 4: " "
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (296,131) size 4x19
+      text run at (296,131) width 4: " "
+    LayoutBR {BR} at (0,0) size 0x0
+    LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (146,282) size 4x19
+      text run at (146,282) width 4: " "
+    LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scaled-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scaled-expected.txt
new file mode 100644
index 0000000..40ad848
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scaled-expected.txt
@@ -0,0 +1,22 @@
+layer at (0,0) size 800x600 scrollHeight 626
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x626 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x626
+    LayoutBlockFlow {BODY} at (8,8) size 784x610
+      LayoutBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 780x39
+          text run at (0,0) width 780: "The purpose of this test case is to illustrate the legacy behavior of -webkit-border-image. The specified border widths actually end"
+          text run at (0,20) width 595: "up becoming the real border widths. The border-image property in the specification doesn't do this."
+      LayoutBlockFlow (anonymous) at (0,56) size 784x554
+        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutText {#text} at (272,257) size 4x19
+          text run at (272,257) width 4: " "
+        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutText {#text} at (548,257) size 4x19
+          text run at (548,257) width 4: " "
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutBlockFlow {DIV} at (10,287) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutText {#text} at (272,534) size 4x19
+          text run at (272,534) width 4: " "
+        LayoutBlockFlow {DIV} at (286,287) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scrambled-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scrambled-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-scrambled-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-side-reduction-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-side-reduction-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-side-reduction-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-slice-constrained-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-slice-constrained-expected.txt
new file mode 100644
index 0000000..54b61815
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-slice-constrained-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (191,176) size 4x19
+        text run at (191,176) width 4: " "
+      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-slices-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-slices-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-slices-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-source-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-source-expected.txt
new file mode 100644
index 0000000..47ad2e73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-source-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,131) size 4x19
+        text run at (146,131) width 4: " "
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (296,131) size 4x19
+        text run at (296,131) width 4: " "
+      LayoutBR {BR} at (0,0) size 0x0
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (146,282) size 4x19
+        text run at (146,282) width 4: " "
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-trumps-radius-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-trumps-radius-expected.txt
new file mode 100644
index 0000000..e06b616
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/border-image-trumps-radius-expected.txt
@@ -0,0 +1,7 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (0,0) size 100x100 [bgcolor=#FF0000]
+      LayoutBlockFlow {DIV} at (0,0) size 100x100 [bgcolor=#FF0000] [border: (10px none #0000FF7F)]
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/borders/scaled-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/borders/scaled-border-image-expected.txt
new file mode 100644
index 0000000..dc0b445
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/borders/scaled-border-image-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,10) size 784x570
+      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow (anonymous) at (0,136) size 784x20
+        LayoutText {#text} at (0,0) size 381x19
+          text run at (0,0) width 381: "This should look like the above, only scaled up by a factor of 2:"
+      LayoutBlockFlow {DIV} at (20,176) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/gradients/border-image-gradient-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/gradients/border-image-gradient-expected.txt
new file mode 100644
index 0000000..63dc708
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/gradients/border-image-gradient-expected.txt
@@ -0,0 +1,6 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,10) size 784x580
+      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/android/fast/images/color-profile-background-clip-text-expected.png
new file mode 100644
index 0000000..64097a35
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/android/fast/images/color-profile-svg-fill-text-expected.png
new file mode 100644
index 0000000..6a012ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/images/webp-flip-expected.png b/third_party/WebKit/LayoutTests/platform/android/fast/images/webp-flip-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/platform/linux/fast/images/webp-flip-expected.png
rename to third_party/WebKit/LayoutTests/platform/android/fast/images/webp-flip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/images/webp-flip-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/images/webp-flip-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/platform/linux/fast/images/webp-flip-expected.txt
rename to third_party/WebKit/LayoutTests/platform/android/fast/images/webp-flip-expected.txt
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/js/JSON-parse-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/js/JSON-parse-expected.txt
new file mode 100644
index 0000000..24fc96c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/js/JSON-parse-expected.txt
@@ -0,0 +1,606 @@
+function (jsonObject){
+        return jsonObject.parse();
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token u.
+function (jsonObject){
+        return jsonObject.parse('');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected end of input.
+function (jsonObject){
+        return jsonObject.parse('1');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('-1');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('Infinity');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token I.
+function (jsonObject){
+        return jsonObject.parse('NaN');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token N.
+function (jsonObject){
+        return jsonObject.parse('null');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('undefined');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token u.
+function (jsonObject){
+        return jsonObject.parse('{}');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('({})');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token (.
+function (jsonObject){
+        return jsonObject.parse('{a}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+function (jsonObject){
+        return jsonObject.parse('{a:}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+function (jsonObject){
+        return jsonObject.parse('{a:5}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+function (jsonObject){
+        return jsonObject.parse('{a:5,}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+function (jsonObject){
+        return jsonObject.parse('{"a"}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token }.
+function (jsonObject){
+        return jsonObject.parse('{"a":}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token }.
+function (jsonObject){
+        return jsonObject.parse('{"a":5}');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('{"__proto__":5}');
+    }
+FAIL JSON.stringify(tests[i](nativeJSON)) should be {}. Was {"__proto__":5}.
+function (jsonObject){
+        return jsonObject.parse('{"a":5,}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token }.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('{"a":5,,}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+function (jsonObject){
+        return jsonObject.parse('{"a":5,"a",}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+function (jsonObject){
+        return jsonObject.parse('{"a":(5,"a"),}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token (.
+function (jsonObject){
+        return jsonObject.parse('[]');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('[1]');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('[1,]');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ].
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('[1,2]');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('[1,2,,]');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('[1,2,,4]');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ,.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('""');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"\'"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected end of input.
+function (jsonObject){
+        return jsonObject.parse('"a\\z"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+function (jsonObject){
+        return jsonObject.parse('"a\\\z"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+function (jsonObject){
+        return jsonObject.parse('"a\\\\z"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\tz"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 	.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('"a\\tz"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\nz"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 
+.
+function (jsonObject){
+        return jsonObject.parse('"a\\nz"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\rz"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 
+.
+function (jsonObject){
+        return jsonObject.parse('"a\\rz"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\/z"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\/z"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\bz"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token .
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('"a\\bz"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\rz"');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token 
+.
+function (jsonObject){
+        return jsonObject.parse('"a\\rz"');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\uz"     ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+function (jsonObject){
+        return jsonObject.parse('"a\\u0z"    ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+function (jsonObject){
+        return jsonObject.parse('"a\\u00z"   ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+function (jsonObject){
+        return jsonObject.parse('"a\\u000z"  ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token z.
+function (jsonObject){
+        return jsonObject.parse('"a\\u0000z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u000Az" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u000az" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u000Gz" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+function (jsonObject){
+        return jsonObject.parse('"a\\u000gz" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+function (jsonObject){
+        return jsonObject.parse('"a\\u00A0z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u00a0z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u00G0z" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+function (jsonObject){
+        return jsonObject.parse('"a\\u00g0z" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+function (jsonObject){
+        return jsonObject.parse('"a\\u0A00z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u0a00z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\u0G00z" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+function (jsonObject){
+        return jsonObject.parse('"a\\u0g00z" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+function (jsonObject){
+        return jsonObject.parse('"a\\uA000z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\ua000z" ');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a\\uG000z" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token G.
+function (jsonObject){
+        return jsonObject.parse('"a\\ug000z" ');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token g.
+function (jsonObject){
+        return jsonObject.parse('00');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('01');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('0.a');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token a.
+function (jsonObject){
+        return jsonObject.parse('0x0');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token x.
+function (jsonObject){
+        return jsonObject.parse('2e1.3');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token ..
+function (jsonObject){
+        return jsonObject.parse('2e-+10');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token +.
+function (jsonObject){
+        return jsonObject.parse('2e+-10');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+function (jsonObject){
+        return jsonObject.parse('2e3e4');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token e.
+function (jsonObject){
+        return jsonObject.parse('-01.0');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+function (jsonObject){
+        return jsonObject.parse('-01');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('-01.a');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected number.
+function (jsonObject){
+        return jsonObject.parse('1.e1');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token e.
+json2.js did not throw for a test we expect to throw.
+function (jsonObject){
+        return jsonObject.parse('{/* block comments are not allowed */}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token /.
+function (jsonObject){
+        return jsonObject.parse('{// line comments are not allowed \n}');
+    }
+PASS tests[i](nativeJSON) threw exception SyntaxError: Unexpected token /.
+function (jsonObject){
+        return jsonObject.parse('true');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('false');
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleObject));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleObject,null,100));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null,100));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null,100));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleObject,null," "));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null," "));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null," "));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleObject,null,"\t"));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null,"\t"));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null,"\t"));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleObject,null,"\n"));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject,null,"\n"));
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is tests[i].expected
+function (jsonObject){
+        return jsonObject.parse("true", log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse("false", log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse("null", log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse("1", log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse("1.5", log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('"a string"', log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleArray), log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexArray), log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(simpleObject), log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(complexObject), log);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse('{"__proto__":{"a":5}}', log);
+    }
+FAIL JSON.stringify(tests[i](nativeJSON)) should be {"":{},"keyType":"string"}. Was {"":{"__proto__":{"keyType":"string"}},"keyType":"string"}.
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse("true", logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse("false", logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse("null", logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse("1", logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse("1.5", logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse('"a string"', logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(simpleArray), logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(complexArray), logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(simpleObject), logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(complexObject), logOrder);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse("true", logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse("false", logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse("null", logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse("1", logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse("1.5", logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse('"a string"', logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse(JSON.stringify(simpleArray), logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse(JSON.stringify(complexArray), logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse(JSON.stringify(simpleObject), logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        logOrderString = "";
+        jsonObject.parse(JSON.stringify(complexObject), logOrder);
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        callCount = 0;
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(complexArray), throwAfterFifthCall);
+    }
+PASS tests[i](nativeJSON) threw exception from reviver.
+function (jsonObject){
+        callCount = 0;
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(simpleObject), throwAfterFifthCall);
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        callCount = 0;
+        logOrderString = "";
+        return jsonObject.parse(JSON.stringify(complexObject), throwAfterFifthCall);
+    }
+PASS tests[i](nativeJSON) threw exception from reviver.
+function (jsonObject){
+        callCount = 0;
+        logOrderString = "";
+        try { jsonObject.parse(JSON.stringify(complexArray), throwAfterFifthCall); } catch (e) {}
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        callCount = 0;
+        logOrderString = "";
+        try { jsonObject.parse(JSON.stringify(simpleObject), throwAfterFifthCall); } catch (e) {}
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        callCount = 0;
+        logOrderString = "";
+        try { jsonObject.parse(JSON.stringify(complexObject), throwAfterFifthCall); } catch (e) {}
+        return logOrderString;
+    }
+PASS JSON.stringify(tests[i](nativeJSON)) is JSON.stringify(tests[i](JSON))
+function (jsonObject){
+        return jsonObject.parse(JSON.stringify(unicode));
+    }
+PASS tests[i](nativeJSON) is tests[i].unstringifiedExpected
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/js/invalid-syntax-for-function-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/js/invalid-syntax-for-function-expected.txt
new file mode 100644
index 0000000..dc56c4c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/js/invalid-syntax-for-function-expected.txt
@@ -0,0 +1,3 @@
+CONSOLE ERROR: line 1: Uncaught SyntaxError: Unexpected token ILLEGAL
+This test ensures we don't crash when we are given garbage for an attribute expecting a function.
+https://bugs.webkit.org/show_bug.cgi?id=19025
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/regex/non-pattern-characters-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/regex/non-pattern-characters-expected.txt
new file mode 100644
index 0000000..ee54c5c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/regex/non-pattern-characters-expected.txt
@@ -0,0 +1,173 @@
+This page tests handling of characters which, according to ECMA 262, are not regular expression PatternCharacters. Those characters are: ^ $ . * + ? ( ) [ ] { } |
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Testing regexp: /^/g
+PASS regexp.test('') is true
+PASS regexp.lastIndex is 0
+
+Testing regexp: /\n^/gm
+PASS regexp.test('\n\n') is true
+PASS regexp.lastIndex is 1
+
+Testing regexp: /$/g
+PASS regexp.test('') is true
+PASS regexp.lastIndex is 0
+
+Testing regexp: /\n$/gm
+PASS regexp.test('\n\n') is true
+PASS regexp.lastIndex is 1
+
+Testing regexp: /\z/
+PASS regexp.test('z') is true
+
+Testing regexp: /a\z/
+PASS regexp.test('az') is true
+
+Testing regexp: /\_/
+PASS regexp.test('_') is true
+
+Testing regexp: /a\_/
+PASS regexp.test('a_') is true
+
+Testing regexp: [invalid \ variations]
+PASS /\/ threw exception SyntaxError: Invalid regular expression: missing /.
+PASS /a\/ threw exception SyntaxError: Invalid regular expression: missing /.
+
+Testing regexp: /./
+PASS regexp.test('a') is true
+PASS regexp.test('\n') is false
+
+Testing regexp: /a./
+PASS regexp.test('aa') is true
+PASS regexp.test('a\n') is false
+
+Testing regexp: /a*/gm
+PASS regexp.test('b') is true
+PASS regexp.lastIndex is 0
+PASS regexp.test('aaba') is true
+PASS regexp.lastIndex is 2
+
+Testing regexp: [invalid * variations]
+PASS /*/ threw exception SyntaxError: Unexpected token ILLEGAL.
+PASS /^*/ threw exception SyntaxError: Invalid regular expression: /^*/: Nothing to repeat.
+
+Testing regexp: /a+/gm
+PASS regexp.test('b') is false
+PASS regexp.test('aaba') is true
+PASS regexp.lastIndex is 2
+
+Testing regexp: [invalid + variations]
+PASS /+/ threw exception SyntaxError: Invalid regular expression: /+/: Nothing to repeat.
+
+Testing regexp: /a?/gm
+PASS regexp.test('b') is true
+PASS regexp.lastIndex is 0
+PASS regexp.test('aaba') is true
+PASS regexp.lastIndex is 1
+
+Testing regexp: [invalid ? variations]
+PASS /?/ threw exception SyntaxError: Invalid regular expression: /?/: Nothing to repeat.
+
+Testing regexp: [invalid ( variations]
+PASS /(/ threw exception SyntaxError: Invalid regular expression: /(/: Unterminated group.
+PASS /a(/ threw exception SyntaxError: Invalid regular expression: /a(/: Unterminated group.
+
+Testing regexp: [invalid ) variations]
+PASS /)/ threw exception SyntaxError: Invalid regular expression: /)/: Unmatched ')'.
+PASS /a)/ threw exception SyntaxError: Invalid regular expression: /a)/: Unmatched ')'.
+
+Testing regexp: [invalid [ variations]
+PASS /[/ threw exception SyntaxError: Invalid regular expression: missing /.
+PASS /a[/ threw exception SyntaxError: Invalid regular expression: missing /.
+PASS /[b-a]/ threw exception SyntaxError: Invalid regular expression: /[b-a]/: Range out of order in character class.
+PASS /a[b-a]/ threw exception SyntaxError: Invalid regular expression: /a[b-a]/: Range out of order in character class.
+
+Testing regexp: /]/gm
+PASS regexp.test(']') is true
+PASS regexp.lastIndex is 1
+
+Testing regexp: /a]/gm
+PASS regexp.test('a]') is true
+PASS regexp.lastIndex is 2
+
+Testing regexp: /{/gm
+PASS regexp.test('{') is true
+PASS regexp.lastIndex is 1
+
+Testing regexp: /a{/gm
+PASS regexp.test('a{') is true
+PASS regexp.lastIndex is 2
+
+Testing regexp: /{a/gm
+PASS regexp.test('{a') is true
+PASS regexp.lastIndex is 2
+
+Testing regexp: /a{a/gm
+PASS regexp.test('a{a') is true
+PASS regexp.lastIndex is 3
+
+Testing regexp: /{1,/gm
+PASS regexp.test('{1,') is true
+PASS regexp.lastIndex is 3
+
+Testing regexp: /a{1,/gm
+PASS regexp.test('a{1,') is true
+PASS regexp.lastIndex is 4
+
+Testing regexp: /{1,a/gm
+PASS regexp.test('{1,a') is true
+PASS regexp.lastIndex is 4
+
+Testing regexp: /{1,0/gm
+PASS regexp.test('{1,0') is true
+PASS regexp.lastIndex is 4
+
+Testing regexp: /{1, 0}/gm
+PASS regexp.test('{1, 0}') is true
+PASS regexp.lastIndex is 6
+
+Testing regexp: /a{1, 0}/gm
+PASS regexp.test('a{1, 0}') is true
+PASS regexp.lastIndex is 7
+
+Testing regexp: /a{1,0/gm
+PASS regexp.test('a{1,0') is true
+PASS regexp.lastIndex is 5
+
+Testing regexp: /a{0}/gm
+PASS regexp.test('a') is true
+PASS regexp.lastIndex is 0
+PASS regexp.test('b') is true
+PASS regexp.lastIndex is 0
+
+Testing regexp: [invalid {} variations]
+PASS /{0}/ threw exception SyntaxError: Invalid regular expression: /{0}/: Nothing to repeat.
+PASS /{1,0}/ threw exception SyntaxError: Invalid regular expression: /{1,0}/: Nothing to repeat.
+PASS /a{1,0}/ threw exception SyntaxError: Invalid regular expression: /a{1,0}/: numbers out of order in {} quantifier.
+
+Testing regexp: /}/gm
+PASS regexp.test('}') is true
+PASS regexp.lastIndex is 1
+
+Testing regexp: /a}/gm
+PASS regexp.test('a}') is true
+PASS regexp.lastIndex is 2
+
+Testing regexp: /(?:)/gm
+PASS regexp.test('') is true
+PASS regexp.lastIndex is 0
+
+Testing regexp: /|/gm
+PASS regexp.test('|') is true
+PASS regexp.lastIndex is 0
+
+Testing regexp: /a|/gm
+PASS regexp.test('|') is true
+PASS regexp.lastIndex is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/writing-mode/border-image-vertical-lr-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/writing-mode/border-image-vertical-lr-expected.txt
new file mode 100644
index 0000000..8ac6ede
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/writing-mode/border-image-vertical-lr-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 460x600
+  LayoutBlockFlow {HTML} at (0,0) size 460x600
+    LayoutBlockFlow {BODY} at (8,8) size 444x584
+      LayoutInline {SPAN} at (0,0) size 321x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+        LayoutBlockFlow {DIV} at (99,101) size 0x25
+        LayoutBR {BR} at (78,126) size 98x0
+        LayoutBlockFlow {DIV} at (271,50) size 0x50
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/writing-mode/border-image-vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/writing-mode/border-image-vertical-rl-expected.txt
new file mode 100644
index 0000000..1238566d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/fast/writing-mode/border-image-vertical-rl-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (340,0) size 460x600
+  LayoutBlockFlow {HTML} at (0,0) size 460x600
+    LayoutBlockFlow {BODY} at (8,8) size 444x584
+      LayoutInline {SPAN} at (0,0) size 321x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+        LayoutBlockFlow {DIV} at (164,101) size 0x25
+        LayoutBR {BR} at (87,126) size 98x0
+        LayoutBlockFlow {DIV} at (336,50) size 0x50
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt b/third_party/WebKit/LayoutTests/platform/android/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt
new file mode 100644
index 0000000..e21f673
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/http/tests/websocket/bad-sub-protocol-control-chars-expected.txt
@@ -0,0 +1,15 @@
+Test WebSocket bad sub-protocol names by control characters.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS new WebSocket("ws://127.0.0.1:8880/simple", "\0") threw exception SyntaxError: Failed to construct 'WebSocket': The subprotocol '\u0000' is invalid..
+PASS new WebSocket("ws://127.0.0.1:8880/simple", "	") threw exception SyntaxError: Failed to construct 'WebSocket': The subprotocol '\u0009' is invalid..
+PASS new WebSocket("ws://127.0.0.1:8880/simple", "
+") threw exception SyntaxError: Unexpected token ILLEGAL.
+PASS new WebSocket("ws://127.0.0.1:8880/simple", "
+") threw exception SyntaxError: Unexpected token ILLEGAL.
+PASS new WebSocket("ws://127.0.0.1:8880/simple", "") threw exception SyntaxError: Failed to construct 'WebSocket': The subprotocol '\u001B' is invalid..
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/platform/android/inspector/console/console-control-characters-expected.txt b/third_party/WebKit/LayoutTests/platform/android/inspector/console/console-control-characters-expected.txt
new file mode 100644
index 0000000..c840aac3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/inspector/console/console-control-characters-expected.txt
@@ -0,0 +1,5 @@
+Verify that control characters are substituted with printable characters.
+
+var� i = 0;
+ Uncaught SyntaxError: Unexpected token ILLEGAL(…)
+
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/as-border-image/svg-as-border-image-2-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/as-border-image/svg-as-border-image-2-expected.txt
new file mode 100644
index 0000000..098c2f04
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/as-border-image/svg-as-border-image-2-expected.txt
@@ -0,0 +1,42 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (0,0) size 370x438.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x27
+          LayoutText {#text} at (0,0) size 194x26
+            text run at (0,0) width 194: "SVG border-image"
+        LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,165) size 4x19
+            text run at (180,165) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,165) size 4x19
+            text run at (364,165) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x19
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (370,417) size 4x19
+        text run at (370,417) width 4: " "
+      LayoutBlockFlow {DIV} at (374,0) size 370x438.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x27
+          LayoutText {#text} at (0,0) size 196x26
+            text run at (0,0) width 196: "PNG border-image"
+        LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,165) size 4x19
+            text run at (180,165) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,165) size 4x19
+            text run at (364,165) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x19
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/as-border-image/svg-as-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/as-border-image/svg-as-border-image-expected.txt
new file mode 100644
index 0000000..098c2f04
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/as-border-image/svg-as-border-image-expected.txt
@@ -0,0 +1,42 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (0,0) size 370x438.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x27
+          LayoutText {#text} at (0,0) size 194x26
+            text run at (0,0) width 194: "SVG border-image"
+        LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,165) size 4x19
+            text run at (180,165) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,165) size 4x19
+            text run at (364,165) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x19
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (370,417) size 4x19
+        text run at (370,417) width 4: " "
+      LayoutBlockFlow {DIV} at (374,0) size 370x438.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x27
+          LayoutText {#text} at (0,0) size 196x26
+            text run at (0,0) width 196: "PNG border-image"
+        LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,165) size 4x19
+            text run at (180,165) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,165) size 4x19
+            text run at (364,165) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x19
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/batik/paints/patternRegions-expected.png
new file mode 100644
index 0000000..9ac1d9e9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/batik/paints/patternRegions-positioned-objects-expected.png
new file mode 100644
index 0000000..b52ccc2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
new file mode 100644
index 0000000..231980d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/custom/stroked-pattern-expected.png
new file mode 100644
index 0000000..a992869
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/4145535Crash-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/4145535Crash-expected.txt
new file mode 100644
index 0000000..7a162dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/4145535Crash-expected.txt
@@ -0,0 +1,8 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow (anonymous) at (0,0) size 784x0
+        LayoutImage {EMBED} at (0,0) size 0x0
+      LayoutTable {TABLE} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-01-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-01-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-01-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-01-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.txt
index 235e337..f3c8c5e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.txt
@@ -5,14 +5,14 @@
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutText {#text} at (0,131) size 504x19
         text run at (0,131) width 504: "This test checks to make sure the border-image is not clipped by the border radius. "
-      LayoutBlockFlow {DIV} at (513.67,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (513.67,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,312) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,312) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,433) size 4x19
         text run at (146,433) width 4: " "
-      LayoutBlockFlow {DIV} at (160,312) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,312) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-longhand-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-longhand-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-longhand-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-longhand-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-massive-scale-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-massive-scale-expected.txt
index 7a4be60..ca121cf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-massive-scale-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-massive-scale-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x726 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x726
     LayoutBlockFlow {BODY} at (8,8) size 784x710
-      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (350,335) size 4x19
         text run at (350,335) width 4: " "
-      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (704,335) size 4x19
         text run at (704,335) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,365) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (10,365) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (350,690) size 4x19
         text run at (350,690) width 4: " "
-      LayoutBlockFlow {DIV} at (364,365) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (364,365) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-expected.txt
index 52233d4..cc623b7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,171) size 4x19
         text run at (186,171) width 4: " "
-      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (376,171) size 4x19
         text run at (376,171) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (30,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,221) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,362) size 4x19
         text run at (186,362) width 4: " "
-      LayoutBlockFlow {DIV} at (220,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,221) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-in-shorthand-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-in-shorthand-expected.txt
index 52233d4..cc623b7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-in-shorthand-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-in-shorthand-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,171) size 4x19
         text run at (186,171) width 4: " "
-      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (376,171) size 4x19
         text run at (376,171) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (30,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,221) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,362) size 4x19
         text run at (186,362) width 4: " "
-      LayoutBlockFlow {DIV} at (220,221) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,221) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.txt
index 3cc218a3..6792e434 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.txt
@@ -4,7 +4,7 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DIV} at (0,0) size 784x350
-        LayoutInline {SPAN} at (0,0) size 36x230 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+        LayoutInline {SPAN} at (0,0) size 36x230 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
           LayoutText {#text} at (46,85) size 6x29
             text run at (46,85) width 6: " "
           LayoutBR {BR} at (52,108) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-round-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-round-expected.txt
index b417721..e18fcc0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-round-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-repeat-round-expected.txt
@@ -3,13 +3,13 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (154,116) size 4x19
         text run at (154,116) width 4: " "
-      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (312,116) size 4x19
         text run at (312,116) width 4: " "
-      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (470,116) size 4x19
         text run at (470,116) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-rotate-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-rotate-transform-expected.txt
index 8ed98f0..c40c232 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-rotate-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-rotate-transform-expected.txt
@@ -4,15 +4,15 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
 layer at (8,8) size 784x584
   LayoutBlockFlow {BODY} at (8,8) size 784x584
-    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,131) size 4x19
       text run at (146,131) width 4: " "
-    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (296,131) size 4x19
       text run at (296,131) width 4: " "
     LayoutBR {BR} at (0,0) size 0x0
-    LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,282) size 4x19
       text run at (146,282) width 4: " "
-    LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scale-transform-expected.txt
index 14d7d9d..4cbdb47 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scale-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scale-transform-expected.txt
@@ -4,15 +4,15 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
 layer at (8,8) size 784x584
   LayoutBlockFlow {BODY} at (8,8) size 784x584
-    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,131) size 4x19
       text run at (146,131) width 4: " "
-    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (296,131) size 4x19
       text run at (296,131) width 4: " "
     LayoutBR {BR} at (0,0) size 0x0
-    LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,282) size 4x19
       text run at (146,282) width 4: " "
-    LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-expected.txt
index 40ad848..fd36f4d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-expected.txt
@@ -8,15 +8,15 @@
           text run at (0,0) width 780: "The purpose of this test case is to illustrate the legacy behavior of -webkit-border-image. The specified border widths actually end"
           text run at (0,20) width 595: "up becoming the real border widths. The border-image property in the specification doesn't do this."
       LayoutBlockFlow (anonymous) at (0,56) size 784x554
-        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (272,257) size 4x19
           text run at (272,257) width 4: " "
-        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (548,257) size 4x19
           text run at (548,257) width 4: " "
         LayoutBR {BR} at (0,0) size 0x0
-        LayoutBlockFlow {DIV} at (10,287) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (10,287) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (272,534) size 4x19
           text run at (272,534) width 4: " "
-        LayoutBlockFlow {DIV} at (286,287) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (286,287) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scrambled-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scrambled-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scrambled-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scrambled-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-side-reduction-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-side-reduction-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-side-reduction-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-side-reduction-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slice-constrained-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slice-constrained-expected.txt
index 54b61815..67050bae 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slice-constrained-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slice-constrained-expected.txt
@@ -3,8 +3,8 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (191,176) size 4x19
         text run at (191,176) width 4: " "
-      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slices-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slices-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slices-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-slices-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-source-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-source-expected.txt
index 47ad2e73..c6297f9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-source-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-source-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,131) size 4x19
         text run at (146,131) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,131) size 4x19
         text run at (296,131) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x19
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,161) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.txt
index dc0b445..3faecd6 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.txt
@@ -3,8 +3,8 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,10) size 784x570
-      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutBlockFlow (anonymous) at (0,136) size 784x20
         LayoutText {#text} at (0,0) size 381x19
           text run at (0,0) width 381: "This should look like the above, only scaled up by a factor of 2:"
-      LayoutBlockFlow {DIV} at (20,176) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+      LayoutBlockFlow {DIV} at (20,176) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-background-clip-text-expected.png
index 64097a35..0137e57 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-svg-fill-text-expected.png
index 6a012ac..c0ddf7c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.png
index 95742233..a0100330 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.txt
index c4f0586d..2275d552 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/replaced/replaced-breaking-expected.txt
@@ -45,6 +45,8 @@
         LayoutBlockFlow {INPUT} at (6,390) size 13x13
         LayoutText {#text} at (0,0) size 0x0
         LayoutText {#text} at (0,0) size 0x0
+        LayoutImage {EMBED} at (1,457) size 27x27 [border: (1px solid #000000)]
+        LayoutImage {EMBED} at (1,484) size 27x27 [border: (1px solid #000000)]
         LayoutText {#text} at (0,0) size 0x0
 layer at (11,12) size 150x16
   LayoutBlockFlow {DIV} at (2,3) size 150x16
@@ -74,7 +76,3 @@
     layer at (0,0) size 25x25
       LayoutBlockFlow {HTML} at (0,0) size 25x25
         LayoutBlockFlow {BODY} at (8,8) size 9x9
-layer at (9,465) size 27x27
-  LayoutEmbeddedObject {EMBED} at (1,457) size 27x27 [border: (1px solid #000000)]
-layer at (9,492) size 27x27
-  LayoutEmbeddedObject {EMBED} at (1,484) size 27x27 [border: (1px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.txt
index 8ac6ede..7bdb4337 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 460x600
   LayoutBlockFlow {HTML} at (0,0) size 460x600
     LayoutBlockFlow {BODY} at (8,8) size 444x584
-      LayoutInline {SPAN} at (0,0) size 321x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutInline {SPAN} at (0,0) size 321x80 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
         LayoutBlockFlow {DIV} at (99,101) size 0x25
         LayoutBR {BR} at (78,126) size 98x0
         LayoutBlockFlow {DIV} at (271,50) size 0x50
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.txt
index 1238566d..5204250 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.txt
@@ -3,7 +3,7 @@
 layer at (340,0) size 460x600
   LayoutBlockFlow {HTML} at (0,0) size 460x600
     LayoutBlockFlow {BODY} at (8,8) size 444x584
-      LayoutInline {SPAN} at (0,0) size 321x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutInline {SPAN} at (0,0) size 321x80 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
         LayoutBlockFlow {DIV} at (164,101) size 0x25
         LayoutBR {BR} at (87,126) size 98x0
         LayoutBlockFlow {DIV} at (336,50) size 0x50
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-2-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-2-expected.txt
index 098c2f04..a1435cd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-2-expected.txt
@@ -8,17 +8,17 @@
           LayoutText {#text} at (0,0) size 194x26
             text run at (0,0) width 194: "SVG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,165) size 4x19
             text run at (180,165) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,165) size 4x19
             text run at (364,165) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x19
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (370,417) size 4x19
         text run at (370,417) width 4: " "
@@ -27,16 +27,16 @@
           LayoutText {#text} at (0,0) size 196x26
             text run at (0,0) width 196: "PNG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,165) size 4x19
             text run at (180,165) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,165) size 4x19
             text run at (364,165) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x19
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.txt
index 098c2f04..a1435cd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.txt
@@ -8,17 +8,17 @@
           LayoutText {#text} at (0,0) size 194x26
             text run at (0,0) width 194: "SVG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,165) size 4x19
             text run at (180,165) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,165) size 4x19
             text run at (364,165) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x19
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (370,417) size 4x19
         text run at (370,417) width 4: " "
@@ -27,16 +27,16 @@
           LayoutText {#text} at (0,0) size 196x26
             text run at (0,0) width 196: "PNG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x370
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,165) size 4x19
             text run at (180,165) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,165) size 4x19
             text run at (364,165) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x19
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,195) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png
index 9ac1d9e9..10db30c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png
index b52ccc2..65650dbf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
index 231980d..9fe4861 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
index 260df43..ccc9f51 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
@@ -6,16 +6,16 @@
       "contentsOpaque": true,
       "drawsContent": true,
       "repaintRects": [
-        [109, 173, 100, 100],
-        [34, 173, 25, 25],
-        [9, 148, 50, 50],
-        [9, 148, 50, 50],
-        [9, 148, 50, 50],
-        [9, 148, 25, 25],
+        [209, 273, 200, 200],
+        [59, 273, 50, 50],
+        [9, 223, 100, 100],
+        [9, 223, 100, 100],
+        [9, 223, 100, 100],
+        [9, 223, 50, 50],
+        [9, 73, 400, 400],
+        [9, 73, 400, 400],
+        [9, 73, 400, 400],
         [9, 73, 200, 200],
-        [9, 73, 200, 200],
-        [9, 73, 200, 200],
-        [9, 73, 100, 100],
         [8, 72, 402, 405],
         [8, 72, 102, 405]
       ],
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png
index a992869..54c2fc7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/images/color-profile-background-clip-text-expected.png
new file mode 100644
index 0000000..ca007d5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/images/color-profile-svg-fill-text-expected.png
new file mode 100644
index 0000000..30ee5bd1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt
new file mode 100644
index 0000000..27d6abd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt
@@ -0,0 +1,128 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently do. Setting 'border-style' will be required in M51, around May 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutText {#text} at (165,0) size 4x18
+        text run at (165,0) width 4: " "
+      LayoutText {#text} at (334,0) size 4x18
+        text run at (334,0) width 4: " "
+      LayoutText {#text} at (503,0) size 4x18
+        text run at (503,0) width 4: " "
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (165,140) size 4x18
+        text run at (165,140) width 4: " "
+      LayoutText {#text} at (334,140) size 4x18
+        text run at (334,140) width 4: " "
+      LayoutText {#text} at (0,0) size 0x0
+layer at (28,28) size 125x100 clip at (29,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (197,28) size 125x100 clip at (198,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (366,28) size 125x100 clip at (367,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (535,28) size 125x100 clip at (536,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (28,168) size 125x100 clip at (29,169) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (197,168) size 125x100 clip at (198,169) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (366,168) size 125x100 clip at (367,169) size 110x98
+  LayoutListBox {SELECT} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-background-clip-text-expected.png
index 1fb4adc4..04aa11d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-svg-fill-text-expected.png
index 8153fce..9ed0fb2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/scrollbars/listbox-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/scrollbars/listbox-scrollbar-combinations-expected.txt
new file mode 100644
index 0000000..6d3101e6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/scrollbars/listbox-scrollbar-combinations-expected.txt
@@ -0,0 +1,127 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutText {#text} at (165,0) size 4x18
+        text run at (165,0) width 4: " "
+      LayoutText {#text} at (334,0) size 4x18
+        text run at (334,0) width 4: " "
+      LayoutText {#text} at (503,0) size 4x18
+        text run at (503,0) width 4: " "
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (165,140) size 4x18
+        text run at (165,140) width 4: " "
+      LayoutText {#text} at (334,140) size 4x18
+        text run at (334,140) width 4: " "
+      LayoutText {#text} at (0,0) size 0x0
+layer at (28,28) size 125x100 clip at (29,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (197,28) size 125x100 clip at (198,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (366,28) size 125x100 clip at (367,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (535,28) size 125x100 clip at (536,29) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (28,168) size 125x100 clip at (29,169) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (197,168) size 125x100 clip at (198,169) size 110x98 scrollHeight 100
+  LayoutListBox {SELECT} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
+    LayoutBlockFlow {OPTION} at (11,43) size 90x16
+      LayoutText {#text} at (2,0) size 35x15
+        text run at (2,0) width 35: "Three"
+    LayoutBlockFlow {OPTION} at (11,59) size 90x16
+      LayoutText {#text} at (2,0) size 27x15
+        text run at (2,0) width 27: "Four"
+    LayoutBlockFlow {OPTION} at (11,75) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Five"
+layer at (366,168) size 125x100 clip at (367,169) size 110x98
+  LayoutListBox {SELECT} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
+    LayoutBlockFlow {OPTION} at (11,11) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "One"
+    LayoutBlockFlow {OPTION} at (11,27) size 90x16
+      LayoutText {#text} at (2,0) size 25x15
+        text run at (2,0) width 25: "Two"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/images/webp-flip-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/images/webp-flip-expected.png
deleted file mode 100644
index f3d974c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/images/webp-flip-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt
new file mode 100644
index 0000000..828795e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt
@@ -0,0 +1,43 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently do. Setting 'border-style' will be required in M51, around May 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (0,0) size 370x437.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x28
+          LayoutText {#text} at (0,0) size 195x28
+            text run at (0,0) width 195: "SVG border-image"
+        LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,166) size 4x18
+            text run at (180,166) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,166) size 4x18
+            text run at (364,166) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x18
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (370,418) size 4x18
+        text run at (370,418) width 4: " "
+      LayoutBlockFlow {DIV} at (374,0) size 370x437.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x28
+          LayoutText {#text} at (0,0) size 196x28
+            text run at (0,0) width 196: "PNG border-image"
+        LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,166) size 4x18
+            text run at (180,166) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,166) size 4x18
+            text run at (364,166) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x18
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt
new file mode 100644
index 0000000..828795e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt
@@ -0,0 +1,43 @@
+CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently do. Setting 'border-style' will be required in M51, around May 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {DIV} at (0,0) size 370x437.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x28
+          LayoutText {#text} at (0,0) size 195x28
+            text run at (0,0) width 195: "SVG border-image"
+        LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,166) size 4x18
+            text run at (180,166) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,166) size 4x18
+            text run at (364,166) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x18
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (370,418) size 4x18
+        text run at (370,418) width 4: " "
+      LayoutBlockFlow {DIV} at (374,0) size 370x437.81 [border: (1px solid #000000)]
+        LayoutBlockFlow {H2} at (1,20.91) size 368x28
+          LayoutText {#text} at (0,0) size 196x28
+            text run at (0,0) width 196: "PNG border-image"
+        LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,166) size 4x18
+            text run at (180,166) width 4: " "
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (364,166) size 4x18
+            text run at (364,166) width 4: " "
+          LayoutBR {BR} at (0,0) size 0x0
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (180,350) size 4x18
+            text run at (180,350) width 4: " "
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.txt
index d17d7f7..ef71b6e4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.txt
@@ -5,14 +5,14 @@
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutText {#text} at (0,132) size 532x18
         text run at (0,132) width 532: "This test checks to make sure the border-image is not clipped by the border radius. "
-      LayoutBlockFlow {DIV} at (541.97,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (541.97,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,310) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,310) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,432) size 4x18
         text run at (146,432) width 4: " "
-      LayoutBlockFlow {DIV} at (160,310) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,310) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-massive-scale-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-massive-scale-expected.txt
index 8f8c9217..918181d1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-massive-scale-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-massive-scale-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x724 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x724
     LayoutBlockFlow {BODY} at (8,8) size 784x708
-      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (350,336) size 4x18
         text run at (350,336) width 4: " "
-      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (704,336) size 4x18
         text run at (704,336) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,364) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (10,364) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (350,690) size 4x18
         text run at (350,690) width 4: " "
-      LayoutBlockFlow {DIV} at (364,364) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (364,364) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.txt
index 58dd4ee..da99402 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,172) size 4x18
         text run at (186,172) width 4: " "
-      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (376,172) size 4x18
         text run at (376,172) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,362) size 4x18
         text run at (186,362) width 4: " "
-      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.txt
index 58dd4ee..da99402 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,172) size 4x18
         text run at (186,172) width 4: " "
-      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (376,172) size 4x18
         text run at (376,172) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,362) size 4x18
         text run at (186,362) width 4: " "
-      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.txt
index 955029b3..7fcab455 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.txt
@@ -4,7 +4,7 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DIV} at (0,0) size 784x350
-        LayoutInline {SPAN} at (0,0) size 37x230 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+        LayoutInline {SPAN} at (0,0) size 37x230 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
           LayoutText {#text} at (46,85) size 7x29
             text run at (46,85) width 7: " "
           LayoutBR {BR} at (52,108) size 1x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.txt
index 95c9dce..3e138d9a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.txt
@@ -3,13 +3,13 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (154,117) size 4x18
         text run at (154,117) width 4: " "
-      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (312,117) size 4x18
         text run at (312,117) width 4: " "
-      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (470,117) size 4x18
         text run at (470,117) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-rotate-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-rotate-transform-expected.txt
index 326b20c..5947cad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-rotate-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-rotate-transform-expected.txt
@@ -4,15 +4,15 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
 layer at (8,8) size 784x584
   LayoutBlockFlow {BODY} at (8,8) size 784x584
-    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,132) size 4x18
       text run at (146,132) width 4: " "
-    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (296,132) size 4x18
       text run at (296,132) width 4: " "
     LayoutBR {BR} at (0,0) size 0x0
-    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,282) size 4x18
       text run at (146,282) width 4: " "
-    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scale-transform-expected.txt
index e8fa693..cbe2b613 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scale-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scale-transform-expected.txt
@@ -4,15 +4,15 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
 layer at (8,8) size 784x584
   LayoutBlockFlow {BODY} at (8,8) size 784x584
-    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,132) size 4x18
       text run at (146,132) width 4: " "
-    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (296,132) size 4x18
       text run at (296,132) width 4: " "
     LayoutBR {BR} at (0,0) size 0x0
-    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,282) size 4x18
       text run at (146,282) width 4: " "
-    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scaled-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scaled-expected.txt
index 9511db97..fe4fcf5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scaled-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scaled-expected.txt
@@ -8,15 +8,15 @@
           text run at (0,0) width 750: "The purpose of this test case is to illustrate the legacy behavior of -webkit-border-image. The specified border widths"
           text run at (0,18) width 715: "actually end up becoming the real border widths. The border-image property in the specification doesn't do this."
       LayoutBlockFlow (anonymous) at (0,52) size 784x552
-        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (272,258) size 4x18
           text run at (272,258) width 4: " "
-        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (548,258) size 4x18
           text run at (548,258) width 4: " "
         LayoutBR {BR} at (0,0) size 0x0
-        LayoutBlockFlow {DIV} at (10,286) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (10,286) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (272,534) size 4x18
           text run at (272,534) width 4: " "
-        LayoutBlockFlow {DIV} at (286,286) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (286,286) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-side-reduction-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-side-reduction-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-side-reduction-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-side-reduction-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slice-constrained-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slice-constrained-expected.txt
index 374eb45..58bbbf8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slice-constrained-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slice-constrained-expected.txt
@@ -3,8 +3,8 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (191,177) size 4x18
         text run at (191,177) width 4: " "
-      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.txt
index 5b19f18..cfd78d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x18
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x18
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x18
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.txt
index 1d58b52a..f0e76f7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.txt
@@ -3,8 +3,8 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,10) size 784x570
-      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutBlockFlow (anonymous) at (0,136) size 784x18
         LayoutText {#text} at (0,0) size 408x18
           text run at (0,0) width 408: "This should look like the above, only scaled up by a factor of 2:"
-      LayoutBlockFlow {DIV} at (20,174) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+      LayoutBlockFlow {DIV} at (20,174) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-background-clip-text-expected.png
index 84ee67ac..8bf8d78 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-svg-fill-text-expected.png
index 3750cc5..484c1152 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/webp-flip-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/webp-flip-expected.png
deleted file mode 100644
index f3d974c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/images/webp-flip-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/webp-flip-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/images/webp-flip-expected.txt
deleted file mode 100644
index 73cb718..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/images/webp-flip-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow {P} at (0,0) size 162.80x6 [border: (3px none #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.txt
index 47505a85..636c3923 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 460x600
   LayoutBlockFlow {HTML} at (0,0) size 460x600
     LayoutBlockFlow {BODY} at (8,8) size 444x584
-      LayoutInline {SPAN} at (0,0) size 323x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutInline {SPAN} at (0,0) size 323x80 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
         LayoutBlockFlow {DIV} at (99,101) size 0x25
         LayoutBR {BR} at (77,126) size 100x0
         LayoutBlockFlow {DIV} at (271,50) size 0x50
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.txt
index a331d81..58793a9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.txt
@@ -3,7 +3,7 @@
 layer at (340,0) size 460x600
   LayoutBlockFlow {HTML} at (0,0) size 460x600
     LayoutBlockFlow {BODY} at (8,8) size 444x584
-      LayoutInline {SPAN} at (0,0) size 323x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutInline {SPAN} at (0,0) size 323x80 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
         LayoutBlockFlow {DIV} at (164,101) size 0x25
         LayoutBR {BR} at (86,126) size 100x0
         LayoutBlockFlow {DIV} at (336,50) size 0x50
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.txt
index 3e79f696..290e3de 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.txt
@@ -8,17 +8,17 @@
           LayoutText {#text} at (0,0) size 195x28
             text run at (0,0) width 195: "SVG border-image"
         LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x18
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x18
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x18
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (370,418) size 4x18
         text run at (370,418) width 4: " "
@@ -27,16 +27,16 @@
           LayoutText {#text} at (0,0) size 196x28
             text run at (0,0) width 196: "PNG border-image"
         LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x18
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x18
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x18
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-expected.txt
index 3e79f696..290e3de 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-expected.txt
@@ -8,17 +8,17 @@
           LayoutText {#text} at (0,0) size 195x28
             text run at (0,0) width 195: "SVG border-image"
         LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x18
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x18
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x18
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (370,418) size 4x18
         text run at (370,418) width 4: " "
@@ -27,16 +27,16 @@
           LayoutText {#text} at (0,0) size 196x28
             text run at (0,0) width 196: "PNG border-image"
         LayoutBlockFlow (anonymous) at (1,68.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x18
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x18
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x18
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png
index 83bacd7..49c6c64 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png
index c0d5d19e..b057f85f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
index 1def9877..d56ff3f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
index 7fc2d25..f72402a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
@@ -6,16 +6,16 @@
       "contentsOpaque": true,
       "drawsContent": true,
       "repaintRects": [
-        [109, 169, 100, 100],
-        [34, 169, 25, 25],
-        [9, 144, 50, 50],
-        [9, 144, 50, 50],
-        [9, 144, 50, 50],
-        [9, 144, 25, 25],
+        [209, 269, 200, 200],
+        [59, 269, 50, 50],
+        [9, 219, 100, 100],
+        [9, 219, 100, 100],
+        [9, 219, 100, 100],
+        [9, 219, 50, 50],
+        [9, 69, 400, 400],
+        [9, 69, 400, 400],
+        [9, 69, 400, 400],
         [9, 69, 200, 200],
-        [9, 69, 200, 200],
-        [9, 69, 200, 200],
-        [9, 69, 100, 100],
         [8, 68, 402, 405],
         [8, 68, 102, 405]
       ],
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png
index adbb3f41..50049e51 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.txt
index b0ddeee..6d8c111 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.txt
@@ -5,14 +5,14 @@
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutText {#text} at (0,132) size 532x17
         text run at (0,132) width 532: "This test checks to make sure the border-image is not clipped by the border radius. "
-      LayoutBlockFlow {DIV} at (541.97,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (541.97,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,310) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,310) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,432) size 4x17
         text run at (146,432) width 4: " "
-      LayoutBlockFlow {DIV} at (160,310) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,310) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-massive-scale-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-massive-scale-expected.txt
index a07c0c54..21a5f3f9b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-massive-scale-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-massive-scale-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x724 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x724
     LayoutBlockFlow {BODY} at (8,8) size 784x708
-      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (350,336) size 4x17
         text run at (350,336) width 4: " "
-      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (364,10) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (704,336) size 4x17
         text run at (704,336) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,364) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (10,364) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (350,690) size 4x17
         text run at (350,690) width 4: " "
-      LayoutBlockFlow {DIV} at (364,364) size 330x330 [border: (105px none #000000) (150px none #000000) (105px none #000000)]
+      LayoutBlockFlow {DIV} at (364,364) size 330x330 [border: (105px solid #000000) (150px solid #000000) (105px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.txt
index bde674b..5cb21dd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,172) size 4x17
         text run at (186,172) width 4: " "
-      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (376,172) size 4x17
         text run at (376,172) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,362) size 4x17
         text run at (186,362) width 4: " "
-      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.txt
index bde674b..5cb21dd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,172) size 4x17
         text run at (186,172) width 4: " "
-      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,30) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (376,172) size 4x17
         text run at (376,172) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (30,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (186,362) size 4x17
         text run at (186,362) width 4: " "
-      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (220,220) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.txt
index bdae2c4..c2a8bd3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.txt
@@ -4,7 +4,7 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DIV} at (0,0) size 784x350
-        LayoutInline {SPAN} at (0,0) size 37x228 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+        LayoutInline {SPAN} at (0,0) size 37x228 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
           LayoutText {#text} at (46,86) size 7x27
             text run at (46,86) width 7: " "
           LayoutBR {BR} at (52,108) size 1x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.txt
index 35b08db..ba601f6 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.txt
@@ -3,13 +3,13 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (154,117) size 4x17
         text run at (154,117) width 4: " "
-      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (168,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (312,117) size 4x17
         text run at (312,117) width 4: " "
-      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (326,10) size 134x111 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (470,117) size 4x17
         text run at (470,117) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-rotate-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-rotate-transform-expected.txt
index 612c3ea..b89068a8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-rotate-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-rotate-transform-expected.txt
@@ -4,15 +4,15 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
 layer at (8,8) size 784x584
   LayoutBlockFlow {BODY} at (8,8) size 784x584
-    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,132) size 4x17
       text run at (146,132) width 4: " "
-    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (296,132) size 4x17
       text run at (296,132) width 4: " "
     LayoutBR {BR} at (0,0) size 0x0
-    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,282) size 4x17
       text run at (146,282) width 4: " "
-    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scale-transform-expected.txt
index 18f667a..81e23ce1 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scale-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scale-transform-expected.txt
@@ -4,15 +4,15 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x600
 layer at (8,8) size 784x584
   LayoutBlockFlow {BODY} at (8,8) size 784x584
-    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,132) size 4x17
       text run at (146,132) width 4: " "
-    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (296,132) size 4x17
       text run at (296,132) width 4: " "
     LayoutBR {BR} at (0,0) size 0x0
-    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (146,282) size 4x17
       text run at (146,282) width 4: " "
-    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+    LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
     LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scaled-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scaled-expected.txt
index decf062..3e8b92b5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scaled-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scaled-expected.txt
@@ -8,15 +8,15 @@
           text run at (0,0) width 751: "The purpose of this test case is to illustrate the legacy behavior of -webkit-border-image. The specified border widths"
           text run at (0,18) width 716: "actually end up becoming the real border widths. The border-image property in the specification doesn't do this."
       LayoutBlockFlow (anonymous) at (0,52) size 784x552
-        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (10,10) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (272,258) size 4x17
           text run at (272,258) width 4: " "
-        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (286,10) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (548,258) size 4x17
           text run at (548,258) width 4: " "
         LayoutBR {BR} at (0,0) size 0x0
-        LayoutBlockFlow {DIV} at (10,286) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (10,286) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (272,534) size 4x17
           text run at (272,534) width 4: " "
-        LayoutBlockFlow {DIV} at (286,286) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+        LayoutBlockFlow {DIV} at (286,286) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-side-reduction-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-side-reduction-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-side-reduction-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-side-reduction-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slice-constrained-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slice-constrained-expected.txt
index c4f3701..f1948cd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slice-constrained-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slice-constrained-expected.txt
@@ -3,8 +3,8 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 171x171 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (191,177) size 4x17
         text run at (191,177) width 4: " "
-      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (205,10) size 171x171 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.txt
index 54afc03..b9b7b0d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.txt
@@ -3,15 +3,15 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,132) size 4x17
         text run at (146,132) width 4: " "
-      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,10) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (296,132) size 4x17
         text run at (296,132) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (146,282) size 4x17
         text run at (146,282) width 4: " "
-      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (160,160) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.txt
index aca4343..4bb9c75e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.txt
@@ -3,8 +3,8 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,10) size 784x570
-      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutBlockFlow {DIV} at (10,0) size 126x126 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
       LayoutBlockFlow (anonymous) at (0,136) size 784x18
         LayoutText {#text} at (0,0) size 408x17
           text run at (0,0) width 408: "This should look like the above, only scaled up by a factor of 2:"
-      LayoutBlockFlow {DIV} at (20,174) size 252x252 [border: (42px none #000000) (60px none #000000) (42px none #000000)]
+      LayoutBlockFlow {DIV} at (20,174) size 252x252 [border: (42px solid #000000) (60px solid #000000) (42px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/webp-flip-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/images/webp-flip-expected.png
deleted file mode 100644
index b5daa85..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/images/webp-flip-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/webp-flip-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/images/webp-flip-expected.txt
deleted file mode 100644
index 73cb718..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/images/webp-flip-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow {P} at (0,0) size 162.80x6 [border: (3px none #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.txt
index d2b44e7..78b31c8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 460x600
   LayoutBlockFlow {HTML} at (0,0) size 460x600
     LayoutBlockFlow {BODY} at (8,8) size 444x584
-      LayoutInline {SPAN} at (0,0) size 319x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutInline {SPAN} at (0,0) size 319x80 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
         LayoutBlockFlow {DIV} at (98,101) size 0x25
         LayoutBR {BR} at (79,126) size 96x0
         LayoutBlockFlow {DIV} at (270,50) size 0x50
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.txt
index 97bc44e2..a9f64c16 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.txt
@@ -3,7 +3,7 @@
 layer at (340,0) size 460x600
   LayoutBlockFlow {HTML} at (0,0) size 460x600
     LayoutBlockFlow {BODY} at (8,8) size 444x584
-      LayoutInline {SPAN} at (0,0) size 319x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
+      LayoutInline {SPAN} at (0,0) size 319x80 [border: (21px solid #000000) (30px solid #000000) (21px solid #000000)]
         LayoutBlockFlow {DIV} at (165,101) size 0x25
         LayoutBR {BR} at (88,126) size 96x0
         LayoutBlockFlow {DIV} at (337,50) size 0x50
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-2-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-2-expected.txt
index 3d925c7..cbfca172 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-2-expected.txt
@@ -8,17 +8,17 @@
           LayoutText {#text} at (0,0) size 195x26
             text run at (0,0) width 195: "SVG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x17
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x17
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x17
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (370,417) size 4x17
         text run at (370,417) width 4: " "
@@ -27,16 +27,16 @@
           LayoutText {#text} at (0,0) size 196x26
             text run at (0,0) width 196: "PNG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x17
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x17
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x17
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.txt
index 3d925c7..cbfca172 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.txt
@@ -8,17 +8,17 @@
           LayoutText {#text} at (0,0) size 195x26
             text run at (0,0) width 195: "SVG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x17
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x17
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x17
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (370,417) size 4x17
         text run at (370,417) width 4: " "
@@ -27,16 +27,16 @@
           LayoutText {#text} at (0,0) size 196x26
             text run at (0,0) width 196: "PNG border-image"
         LayoutBlockFlow (anonymous) at (1,67.81) size 368x368
-          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,166) size 4x17
             text run at (180,166) width 4: " "
-          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (364,166) size 4x17
             text run at (364,166) width 4: " "
           LayoutBR {BR} at (0,0) size 0x0
-          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (180,350) size 4x17
             text run at (180,350) width 4: " "
-          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)]
+          LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)]
           LayoutText {#text} at (0,0) size 0x0
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png
index c5a13c6..d633a61 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png
index ac48a5ce..97a026a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
index ea3027c..e19ac74 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
index 31b9699e..bfca28b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/relative-sized-shadow-tree-content-with-symbol-expected.txt
@@ -6,16 +6,16 @@
       "contentsOpaque": true,
       "drawsContent": true,
       "repaintRects": [
-        [109, 169, 100, 100],
-        [34, 169, 25, 25],
-        [9, 144, 50, 50],
-        [9, 144, 50, 50],
-        [9, 144, 50, 50],
-        [9, 144, 25, 25],
+        [209, 269, 200, 200],
+        [59, 269, 50, 50],
+        [9, 219, 100, 100],
+        [9, 219, 100, 100],
+        [9, 219, 100, 100],
+        [9, 219, 50, 50],
+        [9, 69, 400, 400],
+        [9, 69, 400, 400],
+        [9, 69, 400, 400],
         [9, 69, 200, 200],
-        [9, 69, 200, 200],
-        [9, 69, 200, 200],
-        [9, 69, 100, 100],
         [8, 68, 402, 404],
         [8, 68, 102, 404]
       ],
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png
index 9dba16f..7158360a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/scrollbars/listbox-scrollbar-combinations.html b/third_party/WebKit/LayoutTests/scrollbars/listbox-scrollbar-combinations.html
index f451a57..e4c3514 100644
--- a/third_party/WebKit/LayoutTests/scrollbars/listbox-scrollbar-combinations.html
+++ b/third_party/WebKit/LayoutTests/scrollbars/listbox-scrollbar-combinations.html
@@ -287,6 +287,7 @@
     border-color: transparent;
     border-width: 13px 0;
     min-height: 20px;
+    border-style: solid;
 }
 
 ::-webkit-scrollbar-thumb:vertical:hover {
@@ -339,6 +340,7 @@
     -webkit-border-image: url(resources/vertical-track-disabled.png) 13 0 13 0;
     border-color: transparent;
     border-width: 13px 0;
+    border-style: solid;
 }
 
 ::-webkit-scrollbar-track-piece:vertical:decrement {
diff --git a/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image-2.html b/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image-2.html
index cd9d1b42..57346e0 100644
--- a/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image-2.html
+++ b/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image-2.html
@@ -1,6 +1,9 @@
 <html>
 <head>
 <style>
+    div {
+      border-style: solid;
+    }
     .svg, .image {
       display: inline-block;
       border: 1px solid black;
diff --git a/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image.html b/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image.html
index a3ba496e..a9bf8b9f 100644
--- a/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image.html
+++ b/third_party/WebKit/LayoutTests/svg/as-border-image/svg-as-border-image.html
@@ -1,6 +1,9 @@
 <html>
 <head>
 <style>
+    div {
+      border-style: solid;
+    }
     .svg, .image {
       display: inline-block;
       border: 1px solid black;
diff --git a/third_party/WebKit/LayoutTests/svg/dom/svg-document-set-title-mutations.html b/third_party/WebKit/LayoutTests/svg/dom/svg-document-set-title-mutations.html
deleted file mode 100644
index 6323c96e..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/svg-document-set-title-mutations.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-test(function() {
-  var doc = document.implementation.createDocument("http://www.w3.org/2000/svg", "svg", null);
-  doc.title = 'old';
-  var titleElement = doc.querySelector('title');
-  var observer = new MutationObserver(function(mutations) {
-    assert_equals(mutations.length, 1);
-    assert_equals(mutations[0].type, 'childList');
-    assert_equals(mutations[0].addedNodes[0].data, 'new');
-    assert_equals(mutations[0].addedNodes.length, 1);
-    assert_equals(mutations[0].removedNodes[0].data, 'old');
-    assert_equals(mutations[0].removedNodes.length, 1);
-  });
-
-  observer.observe(titleElement, { childList: true });
-  doc.title = 'new';
-}, "Test for mutations to childList when setting title of svg document.");
-</script>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-shape-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-shape-expected.html
new file mode 100644
index 0000000..f718ea6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-shape-expected.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-shape.html b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-shape.html
new file mode 100644
index 0000000..bc8f608d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-shape.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<svg>
+  <rect width="100" height="100" fill="green" style="transform: translate(100px, 100px)"/>
+</svg>
+<script>
+runAfterLayoutAndPaint(function() {
+  document.querySelector('rect').style.transform = 'none';
+}, true);
+</script>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-text-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-text-expected.html
new file mode 100644
index 0000000..f718ea6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-text-expected.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-text.html b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-text.html
new file mode 100644
index 0000000..5959517
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/change-transform-to-none-text.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script src="../../resources/ahem.js"></script>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<svg>
+  <text y="80" font-size="100" fill="green" font-family="Ahem" style="transform: translate(100px, 100px)">X</text>
+</svg>
+<script>
+runAfterLayoutAndPaint(function() {
+  document.querySelector('text').style.transform = 'none';
+}, true);
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-capture-expected.txt b/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-capture-expected.txt
new file mode 100644
index 0000000..3948d36
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-capture-expected.txt
@@ -0,0 +1,147 @@
+Verifies that pointer capture works for mouse.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+ ======= Set pointer capture and release implicitly  ======= 
+    **** Move to green box & mouse press & jiggle ***** 
+green received pointerover
+green received mouseover
+grey received pointerenter
+grey received mouseenter
+green received pointerenter
+green received mouseenter
+green received pointermove
+green received mousemove
+green received pointerdown
+    **** Set Pointer Capture  ***** 
+green received mousedown
+green received pointermove
+green received mousemove
+    **** Move to grey box & jiggle ***** 
+green received pointerout
+green received mouseout
+green received pointerleave
+green received mouseleave
+grey received pointerleave
+grey received mouseleave
+green received pointermove
+green received mousemove
+green received pointermove
+green received mousemove
+    **** Move to blue box & jiggle ****
+green received pointermove
+green received mousemove
+green received pointermove
+green received mousemove
+green received pointermove
+green received mousemove
+    **** Move back to green & again to blue & mouse release  ***** 
+green received pointerover
+green received mouseover
+grey received pointerenter
+grey received mouseenter
+green received pointerenter
+green received mouseenter
+green received pointermove
+green received mousemove
+green received pointerout
+green received mouseout
+green received pointerleave
+green received mouseleave
+grey received pointerleave
+grey received mouseleave
+green received pointermove
+green received mousemove
+green received pointerup
+green received mouseup
+    **** Jiggle in blue box ***** 
+blue received pointerover
+blue received mouseover
+blue received pointerenter
+blue received mouseenter
+blue received pointermove
+blue received mousemove
+    **** Move to (0,0) ***** 
+blue received pointerout
+blue received mouseout
+blue received pointerleave
+blue received mouseleave
+
+ ======= Set pointer capture and release explicitly  ======= 
+    **** Move to green box & mouse press & jiggle ***** 
+green received pointerover
+green received mouseover
+grey received pointerenter
+grey received mouseenter
+green received pointerenter
+green received mouseenter
+green received pointermove
+green received mousemove
+green received pointerdown
+    **** Set Pointer Capture  ***** 
+green received mousedown
+green received pointermove
+green received mousemove
+    **** Move to grey box & jiggle ***** 
+green received pointerout
+green received mouseout
+green received pointerleave
+green received mouseleave
+grey received pointerleave
+grey received mouseleave
+green received pointermove
+green received mousemove
+green received pointermove
+green received mousemove
+    **** Move to blue box & jiggle ****
+green received pointermove
+    **** Release Pointer Capture  ***** 
+green received mousemove
+blue received pointerover
+blue received mouseover
+blue received pointerenter
+blue received mouseenter
+blue received pointermove
+blue received mousemove
+blue received pointermove
+blue received mousemove
+    **** Move back to green & again to blue & mouse release  ***** 
+blue received pointerout
+blue received mouseout
+blue received pointerleave
+blue received mouseleave
+green received pointerover
+green received mouseover
+grey received pointerenter
+grey received mouseenter
+green received pointerenter
+green received mouseenter
+green received pointermove
+green received mousemove
+green received pointerout
+green received mouseout
+green received pointerleave
+green received mouseleave
+grey received pointerleave
+grey received mouseleave
+blue received pointerover
+blue received mouseover
+blue received pointerenter
+blue received mouseenter
+blue received pointermove
+blue received mousemove
+blue received pointerup
+blue received mouseup
+    **** Jiggle in blue box ***** 
+blue received pointermove
+blue received mousemove
+    **** Move to (0,0) ***** 
+blue received pointerout
+blue received mouseout
+blue received pointerleave
+blue received mouseleave
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-capture.html b/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-capture.html
new file mode 100644
index 0000000..dfaecf24
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-capture.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML>
+<script src="../../../../../resources/js-test.js"></script>
+<style>
+div.box {
+  margin: 5px;
+  padding: 20px;
+  float: left;
+}
+</style>
+
+<div id="grey" class="box" style="background-color:grey">
+  <div id="green" class="box" style="background-color:green;">
+  </div>
+</div>
+<div id="blue" class="box" style="background-color:blue;">
+</div>
+
+<div id="console"></div>
+
+<script>
+description("Verifies that pointer capture works for mouse.");
+
+var implicitRelease = false;
+var pointerMoveCount = 0;
+
+var rect = document.getElementById("green").getBoundingClientRect();
+var x1 = rect.left + 5;
+var y1 = rect.top + 5;
+
+var rect = document.getElementById("grey").getBoundingClientRect();
+var x2 = rect.left + 5;
+var y2 = rect.top + 5;
+
+var rect = document.getElementById("blue").getBoundingClientRect();
+var x3 = rect.left + 5;
+var y3 = rect.top + 5;
+
+function init() {
+  var eventList = ["mouseenter", "mouseleave", "mouseover", "mouseout", "mousemove", "mousedown", "mouseup",
+                   "pointerenter", "pointerleave", "pointerover", "pointerout", "pointermove", "pointerdown", "pointerup"];
+
+  ["grey", "green", "blue"].forEach(function(id) {
+    var targetDiv = document.getElementById(id);
+    eventList.forEach(function(eventName) {
+      targetDiv.addEventListener(eventName, function(event) {
+        if (event.eventPhase == Event.AT_TARGET) {
+          debug(id + " received " + event.type);
+          if (id == "green" && event.type == "pointerdown") {
+            debug("    **** Set Pointer Capture  ***** ");
+            targetDiv.setPointerCapture(event.pointerId);
+          }
+          if (implicitRelease && id == "green" && event.type == "pointermove") {
+            if (pointerMoveCount++ > 3) {
+              debug("    **** Release Pointer Capture  ***** ");
+              targetDiv.releasePointerCapture(event.pointerId);
+              implicitRelease = false;
+            }
+          }
+        }
+      });
+    });
+
+  });
+}
+
+function testScenario() {
+  debug("    **** Move to green box & mouse press & jiggle ***** ");
+  eventSender.mouseMoveTo(x1, y1);
+  eventSender.mouseDown(1);
+  eventSender.mouseMoveTo(x1+1, y1+1);
+
+  debug("    **** Move to grey box & jiggle ***** ");
+  eventSender.mouseMoveTo(x2, y2);
+  eventSender.mouseMoveTo(x2+1, y2+1);
+
+  debug("    **** Move to blue box & jiggle ****");
+  eventSender.mouseMoveTo(x3, y3);
+  eventSender.mouseMoveTo(x3+1, y3+1);
+  eventSender.mouseMoveTo(x3, y3);
+  
+  debug("    **** Move back to green & again to blue & mouse release  ***** ");
+  eventSender.mouseMoveTo(x1, y1);
+  eventSender.mouseMoveTo(x3, y3);
+  eventSender.mouseUp(1);
+
+  debug("    **** Jiggle in blue box ***** ");
+  eventSender.mouseMoveTo(x3+1, y3+1);
+
+  debug("    **** Move to (0,0) ***** ");
+  eventSender.mouseMoveTo(0, 0);
+}
+
+function runTests() {
+  debug(" ======= Set pointer capture and release implicitly  ======= ");
+  testScenario();
+
+  implicitRelease = true;
+  debug("");
+  debug(" ======= Set pointer capture and release explicitly  ======= ");
+  testScenario();
+  }
+
+init();
+if (window.eventSender)
+  runTests();
+else
+  debug("This test requires eventSender");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index a8a68ba..2e2f139 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -11,27 +11,7 @@
 CONSOLE WARNING: 'webkitIDBCursor' is deprecated. Please use 'IDBCursor' instead.
 CONSOLE WARNING: 'webkitIndexedDB' is deprecated. Please use 'indexedDB' instead.
 CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
 CONSOLE WARNING: 'webkitURL' is deprecated. Please use 'URL' instead.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
-CONSOLE ERROR: The 'WebBluetooth' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.
 This test documents all interface attributes and methods on the global window object and element instances.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-premature-death-expected.txt b/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-premature-death-expected.txt
index cc0a24f..ea5bedf 100644
--- a/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-premature-death-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/scriptprocessornode-premature-death-expected.txt
@@ -7,8 +7,8 @@
 PASS wasCollectedPrematurely is false
 PASS wasCalled is true
 Testing without explicitly keeping a reference to the script processor node alive.
-FAIL wasCollectedPrematurely should be false. Was true.
-FAIL wasCalled should be true. Was false.
+PASS wasCollectedPrematurely is false
+PASS wasCalled is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/PerformanceTests/Canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html b/third_party/WebKit/PerformanceTests/Canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html
index 07c74ef6..11fc67dd 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html
@@ -9,7 +9,7 @@
 var canvas3D = document.createElement('canvas');
 var gl = canvas3D.getContext('webgl');
 if (!gl)
-    CanvasRunner.logFatalError("\nWebGL is not supported or enabled on this platform!\n");
+    CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!");
 
 function setSize(canvas2DWidth, canvas2DHeight, webglWidth, webglHeight) {
     canvas2D.width = canvas2DWidth;
diff --git a/third_party/WebKit/PerformanceTests/Canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html b/third_party/WebKit/PerformanceTests/Canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html
index 96afbd6..28cec73 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html
@@ -9,7 +9,7 @@
 var canvas3D = document.createElement('canvas');
 var gl = canvas3D.getContext('webgl');
 if (!gl)
-    CanvasRunner.logFatalError("\nWebGL is not supported or enabled on this platform!\n");
+    CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!");
 
 function setSize(canvas2DWidth, canvas2DHeight, webglWidth, webglHeight) {
     canvas2D.width = canvas2DWidth;
diff --git a/third_party/WebKit/PerformanceTests/Canvas/draw-video-to-hw-accelerated-canvas-2d.html b/third_party/WebKit/PerformanceTests/Canvas/draw-video-to-hw-accelerated-canvas-2d.html
index 8498c379..783a3d37 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/draw-video-to-hw-accelerated-canvas-2d.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/draw-video-to-hw-accelerated-canvas-2d.html
@@ -14,22 +14,6 @@
     destCanvas2D.height = height;
 }
 
-function addPlayCallback(videoElement) {
-    // This logic makes sure this perf test starts after playing the video.
-    videoElement.addEventListener("canplaythrough", startVideo, true);
-    videoElement.addEventListener("play", startPerfTest, true);
-    videoElement.addEventListener('error', function(ev) {
-        CanvasRunner.logFatalError("\nmp4 codec is not supported on this platform. Received error event:" + ev.target.error.code + "\n");
-    }, false);
-    videoElement.src = "../resources/bear-1280x720.mp4";
-}
-
-function startVideo() {
-    // loop can emit this event again.
-    videoElement.removeEventListener("canplaythrough", startVideo, true);
-    videoElement.play();
-}
-
 function startPerfTest() {
     CanvasRunner.start({
         description: "This bench test checks the speed on drawing Video element to HW accelerated Canvas2D(1024x1024).",
@@ -53,7 +37,12 @@
     // but this API is not available in JS or WebPage. Assume the threshold size is 256x257
     // and the dest canvas is HW accelerated Canvas when setting its size to 1024x1024.
     setSize(1024, 1024);
-    addPlayCallback(videoElement);
+
+    videoElement.src = "resources/bear-1280x720.mp4";
+    if(!videoElement.canPlayType('video/mp4').replace(/no/, '')) {
+      CanvasRunner.logFatalError("video/mp4 is unsupported");
+    };
+    CanvasRunner.startPlayingAndWaitForVideo(videoElement, startPerfTest);
 }
 
 </script>
diff --git a/third_party/WebKit/PerformanceTests/resources/bear-1280x720.mp4 b/third_party/WebKit/PerformanceTests/Canvas/resources/bear-1280x720.mp4
similarity index 100%
rename from third_party/WebKit/PerformanceTests/resources/bear-1280x720.mp4
rename to third_party/WebKit/PerformanceTests/Canvas/resources/bear-1280x720.mp4
Binary files differ
diff --git a/third_party/WebKit/PerformanceTests/Canvas/resources/canvas_runner.js b/third_party/WebKit/PerformanceTests/Canvas/resources/canvas_runner.js
index 8f102804..21c3fe11 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/resources/canvas_runner.js
+++ b/third_party/WebKit/PerformanceTests/Canvas/resources/canvas_runner.js
@@ -12,7 +12,7 @@
         PerfTestRunner.prepareToMeasureValuesAsync({unit: 'runs/s',
             description: test.description, done: testDone});
         if (!test.doRun) {
-            CanvasRunner.logFatalError("\ndoRun must be set.\n");
+            CanvasRunner.logFatalError("doRun must be set.");
             return;
         }
         currentTest = test;
@@ -40,7 +40,7 @@
 
             PerfTestRunner.measureValueAsync(MEASURE_DRAW_TIMES * count * 1000 / elapsedTime);
         } catch(err) {
-            CanvasRunner.logFatalError("\ntest fails due to GPU issue. " + err + "\n");
+            CanvasRunner.logFatalError("test fails due to GPU issue. " + err);
             return;
         }
 
@@ -56,5 +56,39 @@
         PerfTestRunner.logFatalError(text);
     }
 
+    CanvasRunner.startPlayingAndWaitForVideo = function (video, callback) {
+        var gotPlaying = false;
+        var gotTimeUpdate = false;
+
+        var maybeCallCallback = function() {
+            if (gotPlaying && gotTimeUpdate && callback) {
+                callback(video);
+                callback = undefined;
+                video.removeEventListener('playing', playingListener, true);
+                video.removeEventListener('timeupdate', timeupdateListener, true);
+            }
+        };
+
+        var playingListener = function() {
+            gotPlaying = true;
+            maybeCallCallback();
+        };
+
+        var timeupdateListener = function() {
+            // Checking to make sure the current time has advanced beyond
+            // the start time seems to be a reliable heuristic that the
+            // video element has data that can be consumed.
+            if (video.currentTime > 0.0) {
+                gotTimeUpdate = true;
+                maybeCallCallback();
+            }
+        };
+
+        video.addEventListener('playing', playingListener, true);
+        video.addEventListener('timeupdate', timeupdateListener, true);
+        video.loop = true;
+        video.play();
+    }
+
     window.CanvasRunner = CanvasRunner;
 })();
diff --git a/third_party/WebKit/PerformanceTests/Canvas/upload-canvas-2d-to-texture.html b/third_party/WebKit/PerformanceTests/Canvas/upload-canvas-2d-to-texture.html
index f7c2d17..d94ef1d6 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/upload-canvas-2d-to-texture.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/upload-canvas-2d-to-texture.html
@@ -10,7 +10,7 @@
 var canvas3D = document.createElement('canvas');
 var gl = canvas3D.getContext('webgl');
 if(!gl)
-    CanvasRunner.logFatalError("\nWebGL is not supported or enabled on this platform!\n");
+    CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!");
 var tex = null;
 
 function setSize(width, height) {
diff --git a/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-sub-texture.html b/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-sub-texture.html
index eb79c7d..80d3e08 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-sub-texture.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-sub-texture.html
@@ -9,30 +9,13 @@
 var canvas3D = document.createElement('canvas');
 var gl = canvas3D.getContext('webgl');
 if(!gl)
-    CanvasRunner.logFatalError("\nWebGL is not supported or enabled on this platform!\n");
+    CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!");
 
 function setSize(width, height) {
     canvas3D.width = width;
     canvas3D.height = height;
 }
 
-function addPlayCallback(videoElement) {
-    // This logic makes sure this perf test starts after playing the video.
-    videoElement.addEventListener("canplaythrough", startVideo, true);
-    videoElement.addEventListener("play", startPerfTest, true);
-    videoElement.addEventListener('error', function(ev) {
-        CanvasRunner.logFatalError("\nmp4 codec is not supported on this platform. Received error event:" + ev.target.error.code + "\n");
-    }, false);
-    videoElement.src = "../resources/bear-1280x720.mp4";
-}
-
-function startVideo() {
-    // loop can emit this event again.
-    videoElement.removeEventListener("canplaythrough", startVideo, true);
-    videoElement.play();
-}
-
-
 function startPerfTest() {
     CanvasRunner.start({
         description: "This bench test checks the speed on texSubImage2D(Video) on Webgl.",
@@ -74,7 +57,12 @@
 
 window.onload = function () {
     setSize(1, 1);
-    addPlayCallback(videoElement);
+
+    videoElement.src = "resources/bear-1280x720.mp4";
+    if(!videoElement.canPlayType('video/mp4').replace(/no/, '')) {
+      CanvasRunner.logFatalError("video/mp4 is unsupported");
+    };
+    CanvasRunner.startPlayingAndWaitForVideo(videoElement, startPerfTest);
 }
 
 </script>
diff --git a/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-texture.html b/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-texture.html
index f19b22f3..55034ab 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-texture.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/upload-video-to-texture.html
@@ -9,29 +9,13 @@
 var canvas3D = document.createElement('canvas');
 var gl = canvas3D.getContext('webgl');
 if(!gl)
-    CanvasRunner.logFatalError("\nWebGL is not supported or enabled on this platform!\n");
+    CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!");
 
 function setSize(width, height) {
     canvas3D.width = width;
     canvas3D.height = height;
 }
 
-function addPlayCallback(videoElement) {
-    // This logic makes sure this perf test starts after playing the video.
-    videoElement.addEventListener("canplaythrough", startVideo, true);
-    videoElement.addEventListener("play", startPerfTest, true);
-    videoElement.addEventListener('error', function(ev) {
-        CanvasRunner.logFatalError("\nmp4 codec is not supported on this platform. Received error event:" + ev.target.error.code + "\n");
-    }, false);
-    videoElement.src = "../resources/bear-1280x720.mp4";
-}
-
-function startVideo() {
-    // loop can emit this event again.
-    videoElement.removeEventListener("canplaythrough", startVideo, true);
-    videoElement.play();
-}
-
 function startPerfTest() {
     CanvasRunner.start({
         description: "This bench test checks the speed on texImage2D(Video) on Webgl.",
@@ -72,7 +56,12 @@
 
 window.onload = function () {
     setSize(1, 1);
-    addPlayCallback(videoElement);
+
+    videoElement.src = "resources/bear-1280x720.mp4";
+    if(!videoElement.canPlayType('video/mp4').replace(/no/, '')) {
+      CanvasRunner.logFatalError("video/mp4 is unsupported");
+    };
+    CanvasRunner.startPlayingAndWaitForVideo(videoElement, startPerfTest);
 }
 
 </script>
diff --git a/third_party/WebKit/PerformanceTests/Canvas/upload-webgl-to-texture.html b/third_party/WebKit/PerformanceTests/Canvas/upload-webgl-to-texture.html
index 45b9c39..07a2cf97 100644
--- a/third_party/WebKit/PerformanceTests/Canvas/upload-webgl-to-texture.html
+++ b/third_party/WebKit/PerformanceTests/Canvas/upload-webgl-to-texture.html
@@ -10,7 +10,7 @@
 var destCanvas3D = document.createElement('canvas');
 var destCtx = destCanvas3D.getContext('webgl');
 if (!sourceCtx || !destCtx)
-    CanvasRunner.logFatalError("\nWebGL is not supported or enabled on this platform!\n");
+    CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!");
 var tex = null;
  
 function setSize(width, height) {
diff --git a/third_party/WebKit/PerformanceTests/resources/runner.js b/third_party/WebKit/PerformanceTests/resources/runner.js
index ff74d8d..7874e394 100644
--- a/third_party/WebKit/PerformanceTests/resources/runner.js
+++ b/third_party/WebKit/PerformanceTests/resources/runner.js
@@ -133,7 +133,7 @@
     }
 
     PerfTestRunner.logFatalError = function (text) {
-        PerfTestRunner.log(text);
+        PerfTestRunner.log("FATAL: " + text);
         finish();
     }
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/PrivateScriptRunner.js b/third_party/WebKit/Source/bindings/core/v8/PrivateScriptRunner.js
index 9dc27f0..bab7c4c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/PrivateScriptRunner.js
+++ b/third_party/WebKit/Source/bindings/core/v8/PrivateScriptRunner.js
@@ -63,6 +63,9 @@
 
         // Push API
         "PermissionDeniedError",
+
+        // Pointer Events
+        "InvalidPointerId",
     ];
 
     // This list must be in sync with the enum in ExceptionCode.h. The order matters.
diff --git a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
index a76e6d0..49ddfe5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
@@ -12,6 +12,7 @@
 #include "bindings/core/v8/V8BindingForTesting.h"
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8IteratorResultValue.h"
+#include "bindings/core/v8/V8RecursionScope.h"
 #include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Document.h"
 #include "core/streams/ReadableStreamController.h"
@@ -138,7 +139,7 @@
     ~ReadableStreamOperationsTest() override
     {
         // Execute all pending microtasks
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         EXPECT_FALSE(m_block.HasCaught());
     }
 
@@ -149,6 +150,7 @@
     {
         v8::Local<v8::String> source;
         v8::Local<v8::Script> script;
+        V8RecursionScope::MicrotaskSuppression microtasks(isolate());
         if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
             ADD_FAILURE();
             return ScriptValue();
@@ -253,12 +255,12 @@
         Function::createFunction(scriptState(), it2),
         NotReached::createFunction(scriptState()));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_FALSE(it1->isSet());
     EXPECT_FALSE(it2->isSet());
 
     ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").isEmpty());
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(it1->isSet());
     EXPECT_TRUE(it1->isValid());
     EXPECT_FALSE(it1->isDone());
@@ -266,7 +268,7 @@
     EXPECT_FALSE(it2->isSet());
 
     ASSERT_FALSE(evalWithPrintingError("controller.close()").isEmpty());
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(it1->isSet());
     EXPECT_TRUE(it1->isValid());
     EXPECT_FALSE(it1->isDone());
@@ -309,7 +311,7 @@
     ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it2), NotReached::createFunction(scriptState()));
     ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it3), NotReached::createFunction(scriptState()));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(10, underlyingSource->desiredSize());
 
@@ -326,7 +328,7 @@
     EXPECT_FALSE(it3->isSet());
 
     underlyingSource->close();
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(it3->isSet());
     EXPECT_TRUE(it3->isValid());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
index 34f2d7ca..f6601dd3 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
@@ -281,7 +281,7 @@
     property()->resolve(value);
     EXPECT_EQ(Property::Resolved, property()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(1u, nOtherResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
@@ -307,7 +307,7 @@
     property()->resolve(value);
     EXPECT_EQ(Property::Resolved, property()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(0u, nOtherResolveCalls);
 
@@ -316,7 +316,7 @@
         otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
     }
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(1u, nOtherResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
@@ -343,7 +343,7 @@
         property()->promise(otherWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), otherActual, nOtherRejectCalls));
     }
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nRejectCalls);
     EXPECT_EQ(wrap(mainWorld(), reason), actual);
     EXPECT_EQ(1u, nOtherRejectCalls);
@@ -374,7 +374,7 @@
     property()->resolve(new GarbageCollectedScriptWrappable("value"));
     EXPECT_EQ(Property::Pending, property()->getState());
 
-    v8::Isolate::GetCurrent()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(v8::Isolate::GetCurrent());
 }
 
 TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset)
@@ -405,7 +405,7 @@
     EXPECT_EQ(0u, nOldResolveCalls);
     EXPECT_EQ(0u, nNewRejectCalls);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nOldResolveCalls);
     EXPECT_EQ(1u, nNewRejectCalls);
     EXPECT_NE(oldPromise, newPromise);
@@ -445,7 +445,7 @@
     property()->resolve(value.get());
     EXPECT_EQ(Property::Resolved, property()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
 }
@@ -464,7 +464,7 @@
     property()->reject(reason);
     EXPECT_EQ(Property::Rejected, property()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nRejectCalls);
     EXPECT_EQ(wrap(mainWorld(), reason), actual);
 }
@@ -514,7 +514,7 @@
             property->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actualValue, nResolveCalls), notReached(currentScriptState()));
         }
         property->resolve(value);
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         {
             ScriptState::Scope scope(mainScriptState());
             actual = toCoreString(actualValue.v8Value()->ToString(mainScriptState()->context()).ToLocalChecked());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
index b6cf586..1c946d9 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
@@ -60,7 +60,7 @@
         createClosure(callback, v8::Undefined(isolate()), isolate());
 
         // Execute all pending microtasks
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
     }
 
     OwnPtr<DummyPageHolder> m_pageHolder;
@@ -96,7 +96,7 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -111,14 +111,14 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
     resolver->resolve("bye");
     resolver->reject("bye");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -144,7 +144,7 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -159,14 +159,14 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("hello", onRejected);
 
     resolver->resolve("bye");
     resolver->reject("bye");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("hello", onRejected);
@@ -196,7 +196,7 @@
     }
 
     resolver->resolve("hello");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -321,7 +321,7 @@
     }
 
     resolver->resolve();
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -345,7 +345,7 @@
     }
 
     resolver->reject();
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("undefined", onRejected);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
index 5c3fec7..01d144e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
@@ -83,7 +83,7 @@
         createClosure(callback, v8::Undefined(m_scope.isolate()), m_scope.isolate());
 
         // Execute all pending microtasks
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
     }
 
     String toString(const ScriptValue& value)
@@ -124,13 +124,13 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     resolver.resolve(v8String(isolate(), "hello"));
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", toString(onFulfilled));
     EXPECT_TRUE(onRejected.isEmpty());
@@ -148,7 +148,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", toString(onFulfilled));
     EXPECT_TRUE(onRejected.isEmpty());
@@ -165,13 +165,13 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     resolver.reject(v8String(isolate(), "hello"));
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -189,7 +189,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -226,7 +226,7 @@
     EXPECT_TRUE(onRejected1.isEmpty());
     EXPECT_TRUE(onRejected2.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", toString(onFulfilled1));
     EXPECT_EQ("hello", toString(onFulfilled2));
@@ -248,7 +248,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -264,7 +264,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("SyntaxError: some syntax error", toString(onRejected));
@@ -282,7 +282,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(onFulfilled.isEmpty());
     EXPECT_TRUE(toStringArray(onFulfilled).isEmpty());
@@ -304,7 +304,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(onFulfilled.isEmpty());
     Vector<String> values = toStringArray(onFulfilled);
@@ -329,7 +329,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_FALSE(onRejected.isEmpty());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
index 24a9820..bde9a20 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
@@ -53,7 +53,7 @@
     return s_sharedThread;
 }
 
-void ScriptStreamerThread::postTask(PassOwnPtr<Closure> task)
+void ScriptStreamerThread::postTask(PassOwnPtr<CrossThreadClosure> task)
 {
     ASSERT(isMainThread());
     MutexLocker locker(m_mutex);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.h b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.h
index 7fd2f87c..8af85a4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.h
@@ -27,7 +27,7 @@
     static void shutdown();
     static ScriptStreamerThread* shared();
 
-    void postTask(WTF::PassOwnPtr<WTF::Closure>);
+    void postTask(WTF::PassOwnPtr<WTF::CrossThreadClosure>);
 
     bool isRunningTask() const
     {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index 04de69e..f0a8dfd 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -321,7 +321,7 @@
 
     v8::Debug::SetLiveEditEnabled(isolate, false);
 
-    isolate->SetAutorunMicrotasks(false);
+    isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
 }
 
 namespace {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
index 0a2cfcb9..65c02bc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -30,7 +30,6 @@
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8HiddenValue.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
-#include "bindings/core/v8/V8RecursionScope.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "core/frame/Deprecation.h"
 #include "core/inspector/MainThreadDebugger.h"
@@ -53,18 +52,6 @@
     V8PerIsolateData::from(isolate)->runEndOfScopeTasks();
 }
 
-#if ENABLE(ASSERT)
-static void assertV8RecursionScope(v8::Isolate* isolate)
-{
-    ASSERT(V8RecursionScope::properlyUsed(isolate));
-}
-
-static bool runningUnitTest()
-{
-    return Platform::current()->unitTestSupport();
-}
-#endif
-
 static void useCounterCallback(v8::Isolate* isolate, v8::Isolate::UseCounterFeature feature)
 {
     UseCounter::Feature blinkFeature;
@@ -143,25 +130,15 @@
 }
 
 V8PerIsolateData::V8PerIsolateData()
-    : m_destructionPending(false)
-    , m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
+    : m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
     , m_stringCache(adoptPtr(new StringCache(isolate())))
     , m_hiddenValue(V8HiddenValue::create())
     , m_constructorMode(ConstructorMode::CreateNewObject)
-    , m_recursionLevel(0)
     , m_isHandlingRecursionLevelError(false)
     , m_isReportingException(false)
-#if ENABLE(ASSERT)
-    , m_internalScriptRecursionLevel(0)
-#endif
-    , m_performingMicrotaskCheckpoint(false)
 {
     // FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
     isolate()->Enter();
-#if ENABLE(ASSERT)
-    if (!runningUnitTest())
-        isolate()->AddCallCompletedCallback(&assertV8RecursionScope);
-#endif
     isolate()->AddBeforeCallEnteredCallback(&beforeCallEnteredCallback);
     isolate()->AddMicrotasksCompletedCallback(&microtasksCompletedCallback);
     if (isMainThread())
@@ -206,9 +183,6 @@
 {
     V8PerIsolateData* data = from(isolate);
 
-    ASSERT(!data->m_destructionPending);
-    data->m_destructionPending = true;
-
     data->m_threadDebugger.clear();
     // Clear any data that may have handles into the heap,
     // prior to calling ThreadState::detach().
@@ -219,10 +193,6 @@
 // gets called but before the Isolate exits.
 void V8PerIsolateData::destroy(v8::Isolate* isolate)
 {
-#if ENABLE(ASSERT)
-    if (!runningUnitTest())
-        isolate->RemoveCallCompletedCallback(&assertV8RecursionScope);
-#endif
     isolate->RemoveBeforeCallEnteredCallback(&beforeCallEnteredCallback);
     isolate->RemoveMicrotasksCompletedCallback(&microtasksCompletedCallback);
     V8PerIsolateData* data = from(isolate);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
index 5d709e736..33ed8dc8 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
@@ -74,31 +74,18 @@
 
     static void enableIdleTasks(v8::Isolate*, PassOwnPtr<gin::V8IdleTaskRunner>);
 
-    bool destructionPending() const { return m_destructionPending; }
     v8::Isolate* isolate() { return m_isolateHolder->isolate(); }
 
     StringCache* stringCache() { return m_stringCache.get(); }
 
     v8::Persistent<v8::Value>& ensureLiveRoot();
 
-    int recursionLevel() const { return m_recursionLevel; }
-    int incrementRecursionLevel() { return ++m_recursionLevel; }
-    int decrementRecursionLevel() { return --m_recursionLevel; }
     bool isHandlingRecursionLevelError() const { return m_isHandlingRecursionLevelError; }
     void setIsHandlingRecursionLevelError(bool value) { m_isHandlingRecursionLevelError = value; }
 
     bool isReportingException() const { return m_isReportingException; }
     void setReportingException(bool value) { m_isReportingException = value; }
 
-    bool performingMicrotaskCheckpoint() const { return m_performingMicrotaskCheckpoint; }
-    void setPerformingMicrotaskCheckpoint(bool performingMicrotaskCheckpoint) { m_performingMicrotaskCheckpoint = performingMicrotaskCheckpoint; }
-
-#if ENABLE(ASSERT)
-    int internalScriptRecursionLevel() const { return m_internalScriptRecursionLevel; }
-    int incrementInternalScriptRecursionLevel() { return ++m_internalScriptRecursionLevel; }
-    int decrementInternalScriptRecursionLevel() { return --m_internalScriptRecursionLevel; }
-#endif
-
     V8HiddenValue* hiddenValue() { return m_hiddenValue.get(); }
 
     v8::Local<v8::FunctionTemplate> domTemplate(const void* domTemplateKey, v8::FunctionCallback = 0, v8::Local<v8::Value> data = v8::Local<v8::Value>(), v8::Local<v8::Signature> = v8::Local<v8::Signature>(), int length = 0);
@@ -131,7 +118,6 @@
     bool hasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value>, DOMTemplateMap&);
     v8::Local<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Local<v8::Value>, DOMTemplateMap&);
 
-    bool m_destructionPending;
     OwnPtr<gin::IsolateHolder> m_isolateHolder;
     DOMTemplateMap m_domTemplateMapForMainWorld;
     DOMTemplateMap m_domTemplateMapForNonMainWorld;
@@ -143,15 +129,9 @@
     bool m_constructorMode;
     friend class ConstructorMode;
 
-    int m_recursionLevel;
     bool m_isHandlingRecursionLevelError;
     bool m_isReportingException;
 
-#if ENABLE(ASSERT)
-    int m_internalScriptRecursionLevel;
-#endif
-    bool m_performingMicrotaskCheckpoint;
-
     Vector<OwnPtr<EndOfScopeTask>> m_endOfScopeTasks;
     OwnPtr<ThreadDebugger> m_threadDebugger;
 };
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
index ed10e864..b4c3acf7 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
@@ -30,13 +30,6 @@
 
 #include "bindings/core/v8/V8RecursionScope.h"
 
-#include "core/dom/Microtask.h"
-
 namespace blink {
 
-void V8RecursionScope::didLeaveScriptContext()
-{
-    Microtask::performCheckpoint(m_isolate);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
index dd9a51f..8bbd26c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
@@ -59,63 +59,39 @@
     STACK_ALLOCATED();
 public:
     explicit V8RecursionScope(v8::Isolate* isolate)
-        : m_isolate(isolate)
+        : m_scope(isolate, v8::MicrotasksScope::kRunMicrotasks)
     {
-        V8PerIsolateData::from(m_isolate)->incrementRecursionLevel();
-        // If you want V8 to autorun microtasks, this class needs to have a
-        // v8::Isolate::SuppressMicrotaskExecutionScope member.
-        ASSERT(!isolate->WillAutorunMicrotasks());
+        ASSERT(isolate->GetMicrotasksPolicy() == v8::MicrotasksPolicy::kScoped);
     }
 
     ~V8RecursionScope()
     {
-        if (!V8PerIsolateData::from(m_isolate)->decrementRecursionLevel())
-            didLeaveScriptContext();
     }
 
     static int recursionLevel(v8::Isolate* isolate)
     {
-        return V8PerIsolateData::from(isolate)->recursionLevel();
+        return v8::MicrotasksScope::GetCurrentDepth(isolate);
     }
 
-#if ENABLE(ASSERT)
-    static bool properlyUsed(v8::Isolate* isolate)
-    {
-        return recursionLevel(isolate) > 0 || V8PerIsolateData::from(isolate)->internalScriptRecursionLevel() > 0;
-    }
-#endif
-
     class MicrotaskSuppression {
         USING_FAST_MALLOC(MicrotaskSuppression);
         WTF_MAKE_NONCOPYABLE(MicrotaskSuppression);
     public:
-        MicrotaskSuppression(v8::Isolate* isolate)
-#if ENABLE(ASSERT)
-            : m_isolate(isolate)
-#endif
+        explicit MicrotaskSuppression(v8::Isolate* isolate)
+            : m_scope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks)
         {
-#if ENABLE(ASSERT)
-            V8PerIsolateData::from(m_isolate)->incrementInternalScriptRecursionLevel();
-#endif
         }
 
         ~MicrotaskSuppression()
         {
-#if ENABLE(ASSERT)
-            V8PerIsolateData::from(m_isolate)->decrementInternalScriptRecursionLevel();
-#endif
         }
 
     private:
-#if ENABLE(ASSERT)
-        v8::Isolate* m_isolate;
-#endif
+        v8::MicrotasksScope m_scope;
     };
 
 private:
-    void didLeaveScriptContext();
-
-    v8::Isolate* m_isolate;
+    v8::MicrotasksScope m_scope;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
index 37c26020..c95d7fb 100644
--- a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
@@ -3,35 +3,63 @@
 
 #include "core/origin_trials/OriginTrials.h"
 
+#include "core/dom/ExecutionContext.h"
 #include "core/origin_trials/OriginTrialContext.h"
 #include "platform/RuntimeEnabledFeatures.h"
 
 namespace blink {
+
+OriginTrials::OriginTrials(PassOwnPtrWillBeRawPtr<OriginTrialContext> originTrialContext)
+    : m_originTrialContext(originTrialContext) {}
+
+// static
+const char* OriginTrials::supplementName()
+{
+   return "OriginTrials";
+}
+
+// static
+OriginTrials* OriginTrials::from(ExecutionContext* host)
+{
+    OriginTrials* originTrials = reinterpret_cast<OriginTrials*>(WillBeHeapSupplement<ExecutionContext>::from(host, supplementName()));
+    if (!originTrials) {
+        originTrials = new OriginTrials(host->createOriginTrialContext());
+        WillBeHeapSupplement<ExecutionContext>::provideTo(*host, supplementName(), adoptPtrWillBeNoop(originTrials));
+    }
+    return originTrials;
+}
+
 {% for feature in features %}
 {% if feature.origin_trial_feature_name %}
 
 // static
 bool OriginTrials::{{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext, String& errorMessage) {
-    return {{feature.first_lowered_name}}EnabledImpl(executionContext, &errorMessage);
+    return OriginTrials::from(executionContext)->{{feature.first_lowered_name}}EnabledImpl(&errorMessage);
 }
 
 // static
 bool OriginTrials::{{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext) {
-    return {{feature.first_lowered_name}}EnabledImpl(executionContext, nullptr);
+    return OriginTrials::from(executionContext)->{{feature.first_lowered_name}}EnabledImpl(nullptr);
 }
+
 {% endif %}
 {% endfor %}
 
 {% for feature in features %}
 {% if feature.origin_trial_feature_name %}
 
-// static
-bool OriginTrials::{{feature.first_lowered_name}}EnabledImpl(ExecutionContext* executionContext, String* errorMessage) {
+bool OriginTrials::{{feature.first_lowered_name}}EnabledImpl(String* errorMessage) {
     if (RuntimeEnabledFeatures::{{feature.first_lowered_name}}Enabled())
         return true;
-    return OriginTrialContext::isFeatureEnabled(executionContext, "{{feature.origin_trial_feature_name}}", errorMessage);
+    if (!m_originTrialContext) return false;
+    return m_originTrialContext->isFeatureEnabled("{{feature.origin_trial_feature_name}}", errorMessage);
 }
 {% endif %}
 {% endfor %}
 
+DEFINE_TRACE(OriginTrials)
+{
+    visitor->trace(m_originTrialContext);
+    WillBeHeapSupplement<ExecutionContext>::trace(visitor);
+}
 } // namespace blink
diff --git a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
index f49790e..d7f4d54 100644
--- a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
@@ -5,32 +5,43 @@
 #define OriginTrials_h
 
 #include "core/CoreExport.h"
+#include "platform/Supplementable.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
 
 class ExecutionContext;
+class OriginTrialContext;
 
 // A class that stores dynamic tests for experimental features which can be
 // enabled through the experimental framework via API keys.
 
-class CORE_EXPORT OriginTrials {
+class CORE_EXPORT OriginTrials final : public NoBaseWillBeGarbageCollected<OriginTrials>, public WillBeHeapSupplement<ExecutionContext> {
+WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(OriginTrials)
 public:
+    OriginTrials(PassOwnPtrWillBeRawPtr<OriginTrialContext>);
+
+    static const char* supplementName();
+    static OriginTrials* from(ExecutionContext*);
+
     {% for feature in features %}
     {% if feature.origin_trial_feature_name %}
+
     static bool {{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext, String& errorMessage);
     static bool {{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext);
     {% endif %}
     {% endfor %}
 
-private:
-    OriginTrials() { }
+    DECLARE_TRACE();
 
+private:
     {% for feature in features %}
     {% if feature.origin_trial_feature_name %}
-    static bool {{feature.first_lowered_name}}EnabledImpl(ExecutionContext* executionContext, String* errorMessage);
+    bool {{feature.first_lowered_name}}EnabledImpl(String* errorMessage);
     {% endif %}
     {% endfor %}
+
+    OwnPtrWillBeMember<OriginTrialContext> m_originTrialContext;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/build/win/precompile.gypi b/third_party/WebKit/Source/build/win/precompile.gypi
index 8cb3a9e..29ce35f 100644
--- a/third_party/WebKit/Source/build/win/precompile.gypi
+++ b/third_party/WebKit/Source/build/win/precompile.gypi
@@ -33,9 +33,10 @@
   'conditions': [
       ['OS=="win" and chromium_win_pch==1', {
           'target_defaults': {
-              'msvs_precompiled_header': '<(DEPTH)/third_party/WebKit/Source/build/win/Precompile.h',
+              'msvs_precompiled_header': 'third_party/WebKit/Source/build/win/Precompile.h',
               'msvs_precompiled_source': '<(DEPTH)/third_party/WebKit/Source/build/win/Precompile.cpp',
               'sources': ['<(DEPTH)/third_party/WebKit/Source/build/win/Precompile.cpp'],
+              'include_dirs': [ '<(DEPTH)' ],
           }
       }],
   ],
diff --git a/third_party/WebKit/Source/core/Init.cpp b/third_party/WebKit/Source/core/Init.cpp
index 886a982..0561218 100644
--- a/third_party/WebKit/Source/core/Init.cpp
+++ b/third_party/WebKit/Source/core/Init.cpp
@@ -74,8 +74,8 @@
 
 void CoreInitializer::init()
 {
-    ASSERT(!m_isInited);
-    m_isInited = true;
+    ASSERT(!isInitialized());
+    m_isInitialized = true;
     // Note: in order to add core static strings for a new module (1)
     // the value of 'coreStaticStringsCount' must be updated with the
     // added strings count, (2) if the added strings are quialified names
@@ -143,17 +143,14 @@
     ScriptStreamerThread::init();
 }
 
-void CoreInitializer::terminateThreads()
+void CoreInitializer::shutdown()
 {
     // Make sure we stop the HTMLParserThread before Platform::current() is
     // cleared.
+    ASSERT(Platform::current());
     HTMLParserThread::shutdown();
 
     WorkerThread::terminateAndWaitForAllWorkers();
 }
 
-void CoreInitializer::shutdown()
-{
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/Init.h b/third_party/WebKit/Source/core/Init.h
index e527a93..fd33daf 100644
--- a/third_party/WebKit/Source/core/Init.h
+++ b/third_party/WebKit/Source/core/Init.h
@@ -38,23 +38,22 @@
 
 class CORE_EXPORT CoreInitializer {
     USING_FAST_MALLOC(CoreInitializer);
+    WTF_MAKE_NONCOPYABLE(CoreInitializer);
 public:
-    CoreInitializer() : m_isInited(false) { }
+    CoreInitializer() : m_isInitialized(false) { }
+    virtual ~CoreInitializer() { }
+
     // Should be called by clients before trying to create Frames.
     virtual void init();
-
-    static void terminateThreads();
-
-    // FIXME: Why is this function static?
-    static void shutdown();
+    virtual void shutdown();
 
 protected:
-    bool isInitialized() const { return m_isInited; }
+    bool isInitialized() const { return m_isInitialized; }
 
 private:
     void registerEventFactory();
 
-    bool m_isInited;
+    bool m_isInitialized;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp b/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp
index 4b57452f..3c2c41f 100644
--- a/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp
+++ b/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp
@@ -291,9 +291,9 @@
         result = style.strokeWidth().length();
         return true;
     case CSSPropertyVerticalAlign:
-        if (style.verticalAlign() != LENGTH)
+        if (style.verticalAlign() != VerticalAlignLength)
             return false;
-        result = style.verticalAlignLength();
+        result = style.getVerticalAlignLength();
         return true;
     case CSSPropertyColumnWidth:
         if (style.hasAutoColumnWidth())
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
index 90cd914..da5ac9d 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
+++ b/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
@@ -573,8 +573,8 @@
     case CSSPropertyWordSpacing:
         return createFromDouble(style.wordSpacing());
     case CSSPropertyVerticalAlign:
-        if (style.verticalAlign() == LENGTH)
-            return createFromLength(style.verticalAlignLength(), style);
+        if (style.verticalAlign() == VerticalAlignLength)
+            return createFromLength(style.getVerticalAlignLength(), style);
         return AnimatableUnknown::create(CSSPrimitiveValue::create(style.verticalAlign()));
     case CSSPropertyVisibility:
         return AnimatableVisibility::create(style.visibility());
diff --git a/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp b/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp
index 32d0d897..9355fee8 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp
+++ b/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp
@@ -240,7 +240,7 @@
         return a.top() == b.top();
     case CSSPropertyVerticalAlign:
         return a.verticalAlign() == b.verticalAlign()
-            && (a.verticalAlign() != LENGTH || a.verticalAlignLength() == b.verticalAlignLength());
+            && (a.verticalAlign() != VerticalAlignLength || a.getVerticalAlignLength() == b.getVerticalAlignLength());
     case CSSPropertyVisibility:
         return a.visibility() == b.visibility();
     case CSSPropertyWebkitBorderHorizontalSpacing:
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index d26fff3..ebc628c8 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -509,6 +509,8 @@
             'layout/api/LayoutImageItem.h',
             'layout/api/LayoutItem.h',
             'layout/api/LayoutLIItem.h',
+            'layout/api/LayoutMediaItem.h',
+            'layout/api/LayoutMenuListItem.h',
             'layout/api/LayoutPartItem.h',
             'layout/api/LayoutTextControlItem.h',
             'layout/api/LayoutTextFragmentItem.h',
@@ -1916,6 +1918,8 @@
             'loader/appcache/ApplicationCache.h',
             'loader/appcache/ApplicationCacheHost.cpp',
             'loader/appcache/ApplicationCacheHost.h',
+            'origin_trials/DocumentOriginTrialContext.cpp',
+            'origin_trials/DocumentOriginTrialContext.h',
             'origin_trials/OriginTrialContext.cpp',
             'origin_trials/OriginTrialContext.h',
             'page/AutoscrollController.cpp',
@@ -4030,6 +4034,7 @@
             'loader/LinkHeaderTest.cpp',
             'loader/LinkLoaderTest.cpp',
             'loader/MixedContentCheckerTest.cpp',
+            'origin_trials/DocumentOriginTrialContextTest.cpp',
             'origin_trials/OriginTrialContextTest.cpp',
             'page/ChromeClientTest.cpp',
             'page/ContextMenuControllerTest.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
index f852653..426c6b5 100644
--- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
@@ -88,7 +88,7 @@
 {
     ImageResource* cachedImage = cachedImageForCSSValue(value, &layoutObject->document());
 
-    if (!cachedImage || !cachedImage->canRender())
+    if (!cachedImage || cachedImage->errorOccurred() || cachedImage->image()->isNull())
         return nullptr;
 
     return cachedImage->image();
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index cf2a87d..f1a6349 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -955,16 +955,16 @@
 {
     init(UnitType::ValueID);
     switch (e) {
-    case CAPLEFT:
+    case CaptionSideLeft:
         m_value.valueID = CSSValueLeft;
         break;
-    case CAPRIGHT:
+    case CaptionSideRight:
         m_value.valueID = CSSValueRight;
         break;
-    case CAPTOP:
+    case CaptionSideTop:
         m_value.valueID = CSSValueTop;
         break;
-    case CAPBOTTOM:
+    case CaptionSideBottom:
         m_value.valueID = CSSValueBottom;
         break;
     }
@@ -975,19 +975,19 @@
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueLeft:
-        return CAPLEFT;
+        return CaptionSideLeft;
     case CSSValueRight:
-        return CAPRIGHT;
+        return CaptionSideRight;
     case CSSValueTop:
-        return CAPTOP;
+        return CaptionSideTop;
     case CSSValueBottom:
-        return CAPBOTTOM;
+        return CaptionSideBottom;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return CAPTOP;
+    return CaptionSideTop;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EClear e)
@@ -995,16 +995,16 @@
 {
     init(UnitType::ValueID);
     switch (e) {
-    case CNONE:
+    case ClearNone:
         m_value.valueID = CSSValueNone;
         break;
-    case CLEFT:
+    case ClearLeft:
         m_value.valueID = CSSValueLeft;
         break;
-    case CRIGHT:
+    case ClearRight:
         m_value.valueID = CSSValueRight;
         break;
-    case CBOTH:
+    case ClearBoth:
         m_value.valueID = CSSValueBoth;
         break;
     }
@@ -1015,19 +1015,19 @@
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueNone:
-        return CNONE;
+        return ClearNone;
     case CSSValueLeft:
-        return CLEFT;
+        return ClearLeft;
     case CSSValueRight:
-        return CRIGHT;
+        return ClearRight;
     case CSSValueBoth:
-        return CBOTH;
+        return ClearBoth;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return CNONE;
+    return ClearNone;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ECursor e)
@@ -1250,34 +1250,34 @@
     return display;
 }
 
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EEmptyCell e)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EEmptyCells e)
     : CSSValue(PrimitiveClass)
 {
     init(UnitType::ValueID);
     switch (e) {
-    case SHOW:
+    case EmptyCellsShow:
         m_value.valueID = CSSValueShow;
         break;
-    case HIDE:
+    case EmptyCellsHide:
         m_value.valueID = CSSValueHide;
         break;
     }
 }
 
-template<> inline EEmptyCell CSSPrimitiveValue::convertTo() const
+template<> inline EEmptyCells CSSPrimitiveValue::convertTo() const
 {
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueShow:
-        return SHOW;
+        return EmptyCellsShow;
     case CSSValueHide:
-        return HIDE;
+        return EmptyCellsHide;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return SHOW;
+    return EmptyCellsShow;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexDirection e)
@@ -1440,10 +1440,10 @@
 {
     init(UnitType::ValueID);
     switch (e) {
-    case OUTSIDE:
+    case ListStylePositionOutside:
         m_value.valueID = CSSValueOutside;
         break;
-    case INSIDE:
+    case ListStylePositionInside:
         m_value.valueID = CSSValueInside;
         break;
     }
@@ -1454,15 +1454,15 @@
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueOutside:
-        return OUTSIDE;
+        return ListStylePositionOutside;
     case CSSValueInside:
-        return INSIDE;
+        return ListStylePositionInside;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return OUTSIDE;
+    return ListStylePositionOutside;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EListStyleType e)
@@ -1692,25 +1692,25 @@
 {
     init(UnitType::ValueID);
     switch (e) {
-    case OVISIBLE:
+    case OverflowVisible:
         m_value.valueID = CSSValueVisible;
         break;
-    case OHIDDEN:
+    case OverflowHidden:
         m_value.valueID = CSSValueHidden;
         break;
-    case OSCROLL:
+    case OverflowScroll:
         m_value.valueID = CSSValueScroll;
         break;
-    case OAUTO:
+    case OverflowAuto:
         m_value.valueID = CSSValueAuto;
         break;
-    case OOVERLAY:
+    case OverflowOverlay:
         m_value.valueID = CSSValueOverlay;
         break;
-    case OPAGEDX:
+    case OverflowPagedX:
         m_value.valueID = CSSValueWebkitPagedX;
         break;
-    case OPAGEDY:
+    case OverflowPagedY:
         m_value.valueID = CSSValueWebkitPagedY;
         break;
     }
@@ -1721,25 +1721,25 @@
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueVisible:
-        return OVISIBLE;
+        return OverflowVisible;
     case CSSValueHidden:
-        return OHIDDEN;
+        return OverflowHidden;
     case CSSValueScroll:
-        return OSCROLL;
+        return OverflowScroll;
     case CSSValueAuto:
-        return OAUTO;
+        return OverflowAuto;
     case CSSValueOverlay:
-        return OOVERLAY;
+        return OverflowOverlay;
     case CSSValueWebkitPagedX:
-        return OPAGEDX;
+        return OverflowPagedX;
     case CSSValueWebkitPagedY:
-        return OPAGEDY;
+        return OverflowPagedY;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return OVISIBLE;
+    return OverflowVisible;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBreak e)
@@ -1909,10 +1909,10 @@
 {
     init(UnitType::ValueID);
     switch (e) {
-    case TAUTO:
+    case TableLayoutAuto:
         m_value.valueID = CSSValueAuto;
         break;
-    case TFIXED:
+    case TableLayoutFixed:
         m_value.valueID = CSSValueFixed;
         break;
     }
@@ -1923,15 +1923,15 @@
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueFixed:
-        return TFIXED;
+        return TableLayoutFixed;
     case CSSValueAuto:
-        return TAUTO;
+        return TableLayoutAuto;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return TAUTO;
+    return TableLayoutAuto;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextAlign e)
@@ -2402,34 +2402,34 @@
 {
     init(UnitType::ValueID);
     switch (a) {
-    case TOP:
+    case VerticalAlignTop:
         m_value.valueID = CSSValueTop;
         break;
-    case BOTTOM:
+    case VerticalAlignBottom:
         m_value.valueID = CSSValueBottom;
         break;
-    case MIDDLE:
+    case VerticalAlignMiddle:
         m_value.valueID = CSSValueMiddle;
         break;
-    case BASELINE:
+    case VerticalAlignBaseline:
         m_value.valueID = CSSValueBaseline;
         break;
-    case TEXT_BOTTOM:
+    case VerticalAlignTextBottom:
         m_value.valueID = CSSValueTextBottom;
         break;
-    case TEXT_TOP:
+    case VerticalAlignTextTop:
         m_value.valueID = CSSValueTextTop;
         break;
-    case SUB:
+    case VerticalAlignSub:
         m_value.valueID = CSSValueSub;
         break;
-    case SUPER:
+    case VerticalAlignSuper:
         m_value.valueID = CSSValueSuper;
         break;
-    case BASELINE_MIDDLE:
+    case VerticalAlignBaselineMiddle:
         m_value.valueID = CSSValueWebkitBaselineMiddle;
         break;
-    case LENGTH:
+    case VerticalAlignLength:
         m_value.valueID = CSSValueInvalid;
     }
 }
@@ -2439,29 +2439,29 @@
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueTop:
-        return TOP;
+        return VerticalAlignTop;
     case CSSValueBottom:
-        return BOTTOM;
+        return VerticalAlignBottom;
     case CSSValueMiddle:
-        return MIDDLE;
+        return VerticalAlignMiddle;
     case CSSValueBaseline:
-        return BASELINE;
+        return VerticalAlignBaseline;
     case CSSValueTextBottom:
-        return TEXT_BOTTOM;
+        return VerticalAlignTextBottom;
     case CSSValueTextTop:
-        return TEXT_TOP;
+        return VerticalAlignTextTop;
     case CSSValueSub:
-        return SUB;
+        return VerticalAlignSub;
     case CSSValueSuper:
-        return SUPER;
+        return VerticalAlignSuper;
     case CSSValueWebkitBaselineMiddle:
-        return BASELINE_MIDDLE;
+        return VerticalAlignBaselineMiddle;
     default:
         break;
     }
 
     ASSERT_NOT_REACHED();
-    return TOP;
+    return VerticalAlignTop;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EVisibility e)
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in
index 3badfc8..b37a3d4 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -176,7 +176,7 @@
 d runtime_flag=CSSPropertyD, interpolable, svg, converter=convertPathOrNone
 display
 dominant-baseline inherited, svg
-empty-cells inherited, type_name=EEmptyCell
+empty-cells inherited, type_name=EEmptyCells
 fill interpolable, inherited, svg, setter=setFillPaint, custom_all
 fill-opacity interpolable, inherited, svg, converter=convertNumberOrPercentage
 fill-rule inherited, svg, type_name=WindRule
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index aaf667e..719b130e 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2036,26 +2036,26 @@
         return cssValuePool().createValue(style.unicodeBidi());
     case CSSPropertyVerticalAlign:
         switch (style.verticalAlign()) {
-        case BASELINE:
+        case VerticalAlignBaseline:
             return cssValuePool().createIdentifierValue(CSSValueBaseline);
-        case MIDDLE:
+        case VerticalAlignMiddle:
             return cssValuePool().createIdentifierValue(CSSValueMiddle);
-        case SUB:
+        case VerticalAlignSub:
             return cssValuePool().createIdentifierValue(CSSValueSub);
-        case SUPER:
+        case VerticalAlignSuper:
             return cssValuePool().createIdentifierValue(CSSValueSuper);
-        case TEXT_TOP:
+        case VerticalAlignTextTop:
             return cssValuePool().createIdentifierValue(CSSValueTextTop);
-        case TEXT_BOTTOM:
+        case VerticalAlignTextBottom:
             return cssValuePool().createIdentifierValue(CSSValueTextBottom);
-        case TOP:
+        case VerticalAlignTop:
             return cssValuePool().createIdentifierValue(CSSValueTop);
-        case BOTTOM:
+        case VerticalAlignBottom:
             return cssValuePool().createIdentifierValue(CSSValueBottom);
-        case BASELINE_MIDDLE:
+        case VerticalAlignBaselineMiddle:
             return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
-        case LENGTH:
-            return zoomAdjustedPixelValueForLength(style.verticalAlignLength(), style);
+        case VerticalAlignLength:
+            return zoomAdjustedPixelValueForLength(style.getVerticalAlignLength(), style);
         }
         ASSERT_NOT_REACHED();
         return nullptr;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserMode.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserMode.cpp
index f8ba7ff9..78e69dd9 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserMode.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserMode.cpp
@@ -29,11 +29,14 @@
 #include "core/dom/Document.h"
 #include "core/frame/Settings.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+#include "core/html/imports/HTMLImportsController.h"
 
 namespace blink {
 
 CSSParserContext::CSSParserContext(CSSParserMode mode, UseCounter* useCounter)
     : m_mode(mode)
+    , m_matchMode(mode)
     , m_isHTMLDocument(false)
     , m_useLegacyBackgroundSizeShorthandBehavior(false)
     , m_shouldCheckContentSecurityPolicy(DoNotCheckContentSecurityPolicy)
@@ -55,12 +58,18 @@
         m_shouldCheckContentSecurityPolicy = DoNotCheckContentSecurityPolicy;
     else
         m_shouldCheckContentSecurityPolicy = CheckContentSecurityPolicy;
+
+    if (HTMLImportsController* importsController = document.importsController())
+        m_matchMode = importsController->master()->inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode;
+    else
+        m_matchMode = m_mode;
 }
 
 CSSParserContext::CSSParserContext(const CSSParserContext& other, UseCounter* useCounter)
     : m_baseURL(other.m_baseURL)
     , m_charset(other.m_charset)
     , m_mode(other.m_mode)
+    , m_matchMode(other.m_matchMode)
     , m_referrer(other.m_referrer)
     , m_isHTMLDocument(other.m_isHTMLDocument)
     , m_useLegacyBackgroundSizeShorthandBehavior(other.m_useLegacyBackgroundSizeShorthandBehavior)
@@ -74,6 +83,7 @@
     return m_baseURL == other.m_baseURL
         && m_charset == other.m_charset
         && m_mode == other.m_mode
+        && m_matchMode == other.m_matchMode
         && m_isHTMLDocument == other.m_isHTMLDocument
         && m_useLegacyBackgroundSizeShorthandBehavior == other.m_useLegacyBackgroundSizeShorthandBehavior;
 }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserMode.h b/third_party/WebKit/Source/core/css/parser/CSSParserMode.h
index 8e01dcc..a9d3047 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserMode.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserMode.h
@@ -98,6 +98,7 @@
     bool operator!=(const CSSParserContext& other) const { return !(*this == other); }
 
     CSSParserMode mode() const { return m_mode; }
+    CSSParserMode matchMode() const { return m_matchMode; }
     const KURL& baseURL() const { return m_baseURL; }
     const String& charset() const { return m_charset; }
     const Referrer& referrer() const { return m_referrer; }
@@ -127,6 +128,7 @@
     KURL m_baseURL;
     String m_charset;
     CSSParserMode m_mode;
+    CSSParserMode m_matchMode;
     Referrer m_referrer;
     bool m_isHTMLDocument;
     bool m_useLegacyBackgroundSizeShorthandBehavior;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
index c3f496e5..eab0f7ea 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -390,7 +390,7 @@
     OwnPtr<CSSParserSelector> selector = CSSParserSelector::create();
     selector->setMatch(CSSSelector::Id);
     const AtomicString& value = range.consume().value();
-    selector->setValue(value, isQuirksModeBehavior(m_context.mode()));
+    selector->setValue(value, isQuirksModeBehavior(m_context.matchMode()));
     return selector.release();
 }
 
@@ -404,7 +404,7 @@
     OwnPtr<CSSParserSelector> selector = CSSParserSelector::create();
     selector->setMatch(CSSSelector::Class);
     const AtomicString& value = range.consume().value();
-    selector->setValue(value, isQuirksModeBehavior(m_context.mode()));
+    selector->setValue(value, isQuirksModeBehavior(m_context.matchMode()));
     return selector.release();
 }
 
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
index 974e53d8..be054837 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
@@ -210,7 +210,7 @@
 
     style.applyTextDecorations();
 
-    if (style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE)
+    if (style.overflowX() != OverflowVisible || style.overflowY() != OverflowVisible)
         adjustOverflow(style);
 
     // Cull out any useless layers and also repeat patterns into additional layers.
@@ -226,8 +226,8 @@
         style.setUnique();
 
     // FIXME: when dropping the -webkit prefix on transform-style, we should also have opacity < 1 cause flattening.
-    if (style.preserves3D() && (style.overflowX() != OVISIBLE
-        || style.overflowY() != OVISIBLE
+    if (style.preserves3D() && (style.overflowX() != OverflowVisible
+        || style.overflowY() != OverflowVisible
         || style.hasFilter()))
         style.setTransformStyle3D(TransformStyle3DFlat);
 
@@ -343,15 +343,15 @@
 
     if (isHTMLMarqueeElement(element)) {
         // For now, <marquee> requires an overflow clip to work properly.
-        style.setOverflowX(OHIDDEN);
-        style.setOverflowY(OHIDDEN);
+        style.setOverflowX(OverflowHidden);
+        style.setOverflowY(OverflowHidden);
         return;
     }
 
     if (isHTMLTextAreaElement(element)) {
         // Textarea considers overflow visible as auto.
-        style.setOverflowX(style.overflowX() == OVISIBLE ? OAUTO : style.overflowX());
-        style.setOverflowY(style.overflowY() == OVISIBLE ? OAUTO : style.overflowY());
+        style.setOverflowX(style.overflowX() == OverflowVisible ? OverflowAuto : style.overflowX());
+        style.setOverflowY(style.overflowY() == OverflowVisible ? OverflowAuto : style.overflowY());
         return;
     }
 
@@ -363,7 +363,7 @@
 
 void StyleAdjuster::adjustOverflow(ComputedStyle& style)
 {
-    ASSERT(style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE);
+    ASSERT(style.overflowX() != OverflowVisible || style.overflowY() != OverflowVisible);
 
     if (style.display() == TABLE || style.display() == INLINE_TABLE) {
         // Tables only support overflow:hidden and overflow:visible and ignore anything else,
@@ -371,30 +371,30 @@
         // container box the rules for resolving conflicting x and y values in CSS Overflow Module
         // Level 3 do not apply. Arguably overflow-x and overflow-y aren't allowed on tables but
         // all UAs allow it.
-        if (style.overflowX() != OHIDDEN)
-            style.setOverflowX(OVISIBLE);
-        if (style.overflowY() != OHIDDEN)
-            style.setOverflowY(OVISIBLE);
+        if (style.overflowX() != OverflowHidden)
+            style.setOverflowX(OverflowVisible);
+        if (style.overflowY() != OverflowHidden)
+            style.setOverflowY(OverflowVisible);
         // If we are left with conflicting overflow values for the x and y axes on a table then resolve
-        // both to OVISIBLE. This is interoperable behaviour but is not specced anywhere.
-        if (style.overflowX() == OVISIBLE)
-            style.setOverflowY(OVISIBLE);
-        else if (style.overflowY() == OVISIBLE)
-            style.setOverflowX(OVISIBLE);
-    } else if (style.overflowX() == OVISIBLE && style.overflowY() != OVISIBLE) {
+        // both to OverflowVisible. This is interoperable behaviour but is not specced anywhere.
+        if (style.overflowX() == OverflowVisible)
+            style.setOverflowY(OverflowVisible);
+        else if (style.overflowY() == OverflowVisible)
+            style.setOverflowX(OverflowVisible);
+    } else if (style.overflowX() == OverflowVisible && style.overflowY() != OverflowVisible) {
         // If either overflow value is not visible, change to auto.
         // FIXME: Once we implement pagination controls, overflow-x should default to hidden
         // if overflow-y is set to -webkit-paged-x or -webkit-page-y. For now, we'll let it
         // default to auto so we can at least scroll through the pages.
-        style.setOverflowX(OAUTO);
-    } else if (style.overflowY() == OVISIBLE && style.overflowX() != OVISIBLE) {
-        style.setOverflowY(OAUTO);
+        style.setOverflowX(OverflowAuto);
+    } else if (style.overflowY() == OverflowVisible && style.overflowX() != OverflowVisible) {
+        style.setOverflowY(OverflowAuto);
     }
 
     // Menulists should have visible overflow
     if (style.appearance() == MenulistPart) {
-        style.setOverflowX(OVISIBLE);
-        style.setOverflowY(OVISIBLE);
+        style.setOverflowX(OverflowVisible);
+        style.setOverflowY(OverflowVisible);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
index 1cfe2559c..d942f6a 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -470,8 +470,8 @@
 {
     EVerticalAlign verticalAlign = state.parentStyle()->verticalAlign();
     state.style()->setVerticalAlign(verticalAlign);
-    if (verticalAlign == LENGTH)
-        state.style()->setVerticalAlignLength(state.parentStyle()->verticalAlignLength());
+    if (verticalAlign == VerticalAlignLength)
+        state.style()->setVerticalAlignLength(state.parentStyle()->getVerticalAlignLength());
 }
 
 void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value)
diff --git a/third_party/WebKit/Source/core/dom/CrossThreadTask.h b/third_party/WebKit/Source/core/dom/CrossThreadTask.h
index 7bb35c8d..0e032a8b 100644
--- a/third_party/WebKit/Source/core/dom/CrossThreadTask.h
+++ b/third_party/WebKit/Source/core/dom/CrossThreadTask.h
@@ -89,33 +89,6 @@
 //     |ptr| is assumed safe to be passed across threads, and
 //     AllowCrossThreadAccess() is applied automatically.
 
-namespace internal {
-
-class CallClosureWithExecutionContextTask final : public CallClosureTaskBase<void(ExecutionContext*)> {
-public:
-    // Do not use |create| other than in createCrossThreadTask and
-    // createSameThreadTask.
-    // See http://crbug.com/390851
-    static PassOwnPtr<CallClosureWithExecutionContextTask> create(PassOwnPtr<Function<void(ExecutionContext*)>> closure, bool isSameThread = false)
-    {
-        return adoptPtr(new CallClosureWithExecutionContextTask(closure, isSameThread));
-    }
-
-    void performTask(ExecutionContext* context) override
-    {
-        checkThread();
-        (*m_closure)(context);
-    }
-
-private:
-    CallClosureWithExecutionContextTask(PassOwnPtr<Function<void(ExecutionContext*)>> closure, bool isSameThread)
-        : CallClosureTaskBase<void(ExecutionContext*)>(closure, isSameThread)
-    {
-    }
-};
-
-} // namespace internal
-
 // RETTYPE, PS, and MPS are added as template parameters to circumvent MSVC 18.00.21005.1 (VS 2013) issues.
 
 // [1] createCrossThreadTask() for non-member functions (with ExecutionContext* argument).
@@ -124,7 +97,7 @@
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
 typename std::enable_if<PS + 1 == MPS, RETTYPE>::type createCrossThreadTask(void (*function)(MP...), const P&... parameters)
 {
-    return internal::CallClosureWithExecutionContextTask::create(threadSafeBind<ExecutionContext*>(function, parameters...));
+    return internal::CallClosureWithExecutionContextTask<WTF::CrossThreadAffinity>::create(threadSafeBind<ExecutionContext*>(function, parameters...));
 }
 
 // [2] createCrossThreadTask() for member functions of class C (with ExecutionContext* argument) + raw pointer (C*).
@@ -133,7 +106,7 @@
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
 typename std::enable_if<PS + 1 == MPS, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), C* p, const P&... parameters)
 {
-    return internal::CallClosureWithExecutionContextTask::create(threadSafeBind<ExecutionContext*>(function, AllowCrossThreadAccess(p), parameters...));
+    return internal::CallClosureWithExecutionContextTask<WTF::CrossThreadAffinity>::create(threadSafeBind<ExecutionContext*>(function, AllowCrossThreadAccess(p), parameters...));
 }
 
 // [3] createCrossThreadTask() for non-member functions
@@ -142,7 +115,7 @@
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
 typename std::enable_if<PS == MPS, RETTYPE>::type createCrossThreadTask(void (*function)(MP...), const P&... parameters)
 {
-    return internal::CallClosureTask::create(threadSafeBind(function, parameters...));
+    return internal::CallClosureTask<WTF::CrossThreadAffinity>::create(threadSafeBind(function, parameters...));
 }
 
 // [4] createCrossThreadTask() for member functions of class C + raw pointer (C*)
@@ -152,14 +125,14 @@
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
 typename std::enable_if<PS == MPS, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), C* p, const P&... parameters)
 {
-    return internal::CallClosureTask::create(threadSafeBind(function, AllowCrossThreadAccess(p), parameters...));
+    return internal::CallClosureTask<WTF::CrossThreadAffinity>::create(threadSafeBind(function, AllowCrossThreadAccess(p), parameters...));
 }
 
 template<typename C, typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
 typename std::enable_if<PS == MPS, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), const WeakPtr<C>& p, const P&... parameters)
 {
-    return internal::CallClosureTask::create(threadSafeBind(function, AllowCrossThreadAccess(p), parameters...));
+    return internal::CallClosureTask<WTF::CrossThreadAffinity>::create(threadSafeBind(function, AllowCrossThreadAccess(p), parameters...));
 }
 
 // [6] createCrossThreadTask() for member functions + pointers to class C other than C* or const WeakPtr<C>&
@@ -168,7 +141,7 @@
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
 typename std::enable_if<PS == MPS + 1, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), const P&... parameters)
 {
-    return internal::CallClosureTask::create(threadSafeBind(function, parameters...));
+    return internal::CallClosureTask<WTF::CrossThreadAffinity>::create(threadSafeBind(function, parameters...));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/DOMException.cpp b/third_party/WebKit/Source/core/dom/DOMException.cpp
index 7936f52..fe9e1b8 100644
--- a/third_party/WebKit/Source/core/dom/DOMException.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMException.cpp
@@ -85,6 +85,9 @@
 
     // Used by HTML and Media Session API.
     { "NotAllowedError", "The request is not allowed by the user agent or the platform in the current context.", 0 },
+
+    // Pointer Event
+    { "InvalidPointerId", "PointerId was invalid.", 0 },
 };
 
 static const CoreException* getErrorEntry(ExceptionCode ec)
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index ec2aa95a..81263fb2 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -184,6 +184,7 @@
 #include "core/loader/ImageLoader.h"
 #include "core/loader/NavigationScheduler.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
+#include "core/origin_trials/DocumentOriginTrialContext.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/EventWithHitTestResults.h"
 #include "core/page/FocusController.h"
@@ -1287,29 +1288,18 @@
 void Document::setTitle(const String& title)
 {
     // Title set by JavaScript -- overrides any title elements.
-    if (!m_titleElement) {
-        if (isHTMLDocument() || isXHTMLDocument()) {
-            HTMLElement* headElement = head();
-            if (!headElement)
-                return;
-            m_titleElement = HTMLTitleElement::create(*this);
-            headElement->appendChild(m_titleElement.get());
-        } else if (isSVGDocument()) {
-            Element* element = documentElement();
-            if (!isSVGSVGElement(element))
-                return;
-            m_titleElement = SVGTitleElement::create(*this);
-            element->insertBefore(m_titleElement.get(), element->firstChild());
-        }
-    } else {
-        if (!isHTMLDocument() && !isXHTMLDocument() && !isSVGDocument())
-            m_titleElement = nullptr;
+    if (!isHTMLDocument() && !isXHTMLDocument()) {
+        m_titleElement = nullptr;
+    } else if (!m_titleElement) {
+        HTMLElement* headElement = head();
+        if (!headElement)
+            return;
+        m_titleElement = HTMLTitleElement::create(*this);
+        headElement->appendChild(m_titleElement.get());
     }
 
     if (isHTMLTitleElement(m_titleElement))
         toHTMLTitleElement(m_titleElement)->setText(title);
-    else if (isSVGTitleElement(m_titleElement))
-        toSVGTitleElement(m_titleElement)->setText(title);
     else
         updateTitle(title);
 }
@@ -1327,25 +1317,6 @@
         m_titleElement = titleElement;
     }
 
-
-    if (isSVGDocument()) {
-        // If the root element that is <svg> element in the svg namespace is not the parent of <title> element,
-        // ignore <title> element.
-        if (isSVGSVGElement(documentElement()) && documentElement() != m_titleElement->parentNode()) {
-            m_titleElement = nullptr;
-            return;
-        }
-
-        // If the root element is not <svg> element in the svg namespace and <title> element is in the svg namespace,
-        // or the root element is <svg> element in the svg namespace and <title> element is not in the svg namespace,
-        // ignore <title> element.
-        if ((!isSVGSVGElement(m_titleElement->parentNode()) && isSVGTitleElement(m_titleElement))
-            || (isSVGSVGElement(m_titleElement->parentNode()) && !isSVGTitleElement(m_titleElement))) {
-            m_titleElement = nullptr;
-            return;
-        }
-    }
-
     if (isHTMLTitleElement(m_titleElement))
         updateTitle(toHTMLTitleElement(m_titleElement)->text());
     else if (isSVGTitleElement(m_titleElement))
@@ -1676,17 +1647,17 @@
         documentElement()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::FontSizeChange));
     }
 
-    EOverflow overflowX = OAUTO;
-    EOverflow overflowY = OAUTO;
+    EOverflow overflowX = OverflowAuto;
+    EOverflow overflowY = OverflowAuto;
     float columnGap = 0;
     if (overflowStyle) {
         overflowX = overflowStyle->overflowX();
         overflowY = overflowStyle->overflowY();
         // Visible overflow on the viewport is meaningless, and the spec says to treat it as 'auto':
-        if (overflowX == OVISIBLE)
-            overflowX = OAUTO;
-        if (overflowY == OVISIBLE)
-            overflowY = OAUTO;
+        if (overflowX == OverflowVisible)
+            overflowX = OverflowAuto;
+        if (overflowY == OverflowVisible)
+            overflowY = OverflowAuto;
         // Column-gap is (ab)used by the current paged overflow implementation (in lack of other
         // ways to specify gaps between pages), so we have to propagate it too.
         columnGap = overflowStyle->columnGap();
@@ -5946,6 +5917,11 @@
         frame()->loader().client()->didEnforceStrictMixedContentChecking();
 }
 
+PassOwnPtrWillBeRawPtr<OriginTrialContext> Document::createOriginTrialContext()
+{
+    return adoptPtrWillBeNoop(new DocumentOriginTrialContext(this));
+}
+
 DEFINE_TRACE(Document)
 {
 #if ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 3088fc82..c13baa7 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -140,6 +140,7 @@
 class NodeIterator;
 class NthIndexCache;
 class OriginAccessEntry;
+class OriginTrialContext;
 class Page;
 class PlatformMouseEvent;
 class ProcessingInstruction;
@@ -1079,6 +1080,7 @@
     ParserSynchronizationPolicy getParserSynchronizationPolicy() const { return m_parserSyncPolicy; }
 
 private:
+    friend class DocumentOriginTrialContextTest;
     friend class IgnoreDestructiveWriteCountIncrementer;
     friend class NthIndexCache;
 
@@ -1162,6 +1164,8 @@
 
     const OriginAccessEntry& accessEntryFromURL();
 
+    PassOwnPtrWillBeRawPtr<OriginTrialContext> createOriginTrialContext() override;
+
     DocumentLifecycle m_lifecycle;
 
     bool m_hasNodesWithPlaceholderStyle;
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 49cf2f7..2a96efc 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -105,6 +105,7 @@
 #include "core/html/HTMLTableRowsCollection.h"
 #include "core/html/HTMLTemplateElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
+#include "core/input/EventHandler.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/layout/LayoutTextFragment.h"
 #include "core/layout/LayoutView.h"
@@ -1507,6 +1508,9 @@
         if (data->intersectionObserverData())
             data->intersectionObserverData()->deactivateAllIntersectionObservers(*this);
     }
+
+    if (document().frame())
+        document().frame()->eventHandler().elementRemoved(this);
 }
 
 void Element::attach(const AttachContext& context)
@@ -2642,6 +2646,28 @@
     insertAdjacent(where, fragment.get(), exceptionState);
 }
 
+void Element::setPointerCapture(int pointerId, ExceptionState& exceptionState)
+{
+    if (document().frame()) {
+        if (!document().frame()->eventHandler().isPointerEventActive(pointerId))
+            exceptionState.throwDOMException(InvalidPointerId, "InvalidPointerId");
+        else if (!inDocument())
+            exceptionState.throwDOMException(InvalidStateError, "InvalidStateError");
+        else
+            document().frame()->eventHandler().setPointerCapture(pointerId, this);
+    }
+}
+
+void Element::releasePointerCapture(int pointerId, ExceptionState& exceptionState)
+{
+    if (document().frame()) {
+        if (!document().frame()->eventHandler().isPointerEventActive(pointerId))
+            exceptionState.throwDOMException(InvalidPointerId, "InvalidPointerId");
+        else
+            document().frame()->eventHandler().releasePointerCapture(pointerId, this);
+    }
+}
+
 String Element::innerText()
 {
     // We need to update layout, since plainText uses line boxes in the layout tree.
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h
index 58c168c3..b93d13e8 100644
--- a/third_party/WebKit/Source/core/dom/Element.h
+++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -435,6 +435,9 @@
     void insertAdjacentText(const String& where, const String& text, ExceptionState&);
     void insertAdjacentHTML(const String& where, const String& html, ExceptionState&);
 
+    void setPointerCapture(int pointerId, ExceptionState&);
+    void releasePointerCapture(int pointerId, ExceptionState&);
+
     String textFromChildren();
 
     virtual String title() const { return String(); }
diff --git a/third_party/WebKit/Source/core/dom/Element.idl b/third_party/WebKit/Source/core/dom/Element.idl
index a516e09..4d55f55 100644
--- a/third_party/WebKit/Source/core/dom/Element.idl
+++ b/third_party/WebKit/Source/core/dom/Element.idl
@@ -35,6 +35,10 @@
     [Reflect=class] attribute DOMString className;
     [SameObject, PerWorldBindings, PutForwards=value] readonly attribute DOMTokenList classList;
 
+    // PointerEvent (http://www.w3.org/TR/pointerevents/#extensions-to-the-element-interface)
+    [RuntimeEnabled=PointerEvent, RaisesException] void setPointerCapture (long pointerId);
+    [RuntimeEnabled=PointerEvent, RaisesException] void releasePointerCapture (long pointerId);
+
     [MeasureAs=HasAttributes] boolean hasAttributes();
     [SameObject, PerWorldBindings, ImplementedAs=attributesForBindings] readonly attribute NamedNodeMap attributes;
     DOMString? getAttribute(DOMString name);
diff --git a/third_party/WebKit/Source/core/dom/ExceptionCode.h b/third_party/WebKit/Source/core/dom/ExceptionCode.h
index f1ab4fda..5bda96b 100644
--- a/third_party/WebKit/Source/core/dom/ExceptionCode.h
+++ b/third_party/WebKit/Source/core/dom/ExceptionCode.h
@@ -28,7 +28,7 @@
 typedef int ExceptionCode;
 
 
-// This list must be in sync with the |domExceptions| in PrivateScriptRunner.h.
+// This list must be in sync with the |domExceptions| in PrivateScriptRunner.js and |coreExceptions| in DOMExceptions.cpp.
 // Some of these are considered historical since they have been
 // changed or removed from the specifications.
 enum {
@@ -86,6 +86,9 @@
     PermissionDeniedError,
 
     NotAllowedError,
+
+    // Pointer Events
+    InvalidPointerId,
 };
 
 enum V8ErrorType {
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index bb89d5a..bda769b 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -36,6 +36,7 @@
 #include "core/frame/UseCounter.h"
 #include "core/html/PublicURLManager.h"
 #include "core/inspector/InspectorInstrumentation.h"
+#include "core/origin_trials/OriginTrialContext.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "core/workers/WorkerThread.h"
 #include "wtf/MainThread.h"
@@ -265,6 +266,11 @@
     m_referrerPolicy = referrerPolicy;
 }
 
+PassOwnPtrWillBeRawPtr<OriginTrialContext> ExecutionContext::createOriginTrialContext()
+{
+    return nullptr;
+}
+
 void ExecutionContext::removeURLFromMemoryCache(const KURL& url)
 {
     memoryCache()->removeURLFromCache(url);
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.h b/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 8bb226b..e5e67bc 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -53,6 +53,7 @@
 class EventTarget;
 class ExecutionContextTask;
 class LocalDOMWindow;
+class OriginTrialContext;
 class PublicURLManager;
 class SecurityOrigin;
 class ScriptCallStack;
@@ -155,6 +156,9 @@
     virtual void setReferrerPolicy(ReferrerPolicy);
     ReferrerPolicy getReferrerPolicy() const { return m_referrerPolicy; }
 
+    // Override to enable experimental features through origin trials
+    virtual PassOwnPtrWillBeRawPtr<OriginTrialContext> createOriginTrialContext();
+
 protected:
     ExecutionContext();
     virtual ~ExecutionContext();
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContextTask.h b/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
index 1d7f4ec8..67b50b34 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
@@ -50,55 +50,59 @@
 
 namespace internal {
 
-template<typename T>
+template<typename T, WTF::FunctionThreadAffinity threadAffinity>
 class CallClosureTaskBase : public ExecutionContextTask {
 protected:
-    CallClosureTaskBase(PassOwnPtr<Function<T>> closure, bool isSameThread)
+    explicit CallClosureTaskBase(PassOwnPtr<Function<T, threadAffinity>> closure)
         : m_closure(std::move(closure))
-#if ENABLE(ASSERT)
-        , m_isSameThread(isSameThread)
-        , m_createdThread(currentThread())
-#endif
     {
     }
 
-    void checkThread()
-    {
-#if ENABLE(ASSERT)
-        if (m_isSameThread) {
-            RELEASE_ASSERT(m_createdThread == currentThread());
-        }
-#endif
-    }
-
-    OwnPtr<Function<T>> m_closure;
-
-private:
-#if ENABLE(ASSERT)
-    bool m_isSameThread;
-    ThreadIdentifier m_createdThread;
-#endif
+    OwnPtr<Function<T, threadAffinity>> m_closure;
 };
 
-class CallClosureTask final : public CallClosureTaskBase<void()> {
+template<WTF::FunctionThreadAffinity threadAffinity>
+class CallClosureTask final : public CallClosureTaskBase<void(), threadAffinity> {
 public:
     // Do not use |create| other than in createCrossThreadTask and
     // createSameThreadTask.
     // See http://crbug.com/390851
-    static PassOwnPtr<CallClosureTask> create(PassOwnPtr<Closure> closure, bool isSameThread = false)
+    static PassOwnPtr<CallClosureTask<threadAffinity>> create(PassOwnPtr<Function<void(), threadAffinity>> closure)
     {
-        return adoptPtr(new CallClosureTask(std::move(closure), isSameThread));
+        return adoptPtr(new CallClosureTask<threadAffinity>(std::move(closure)));
     }
 
     void performTask(ExecutionContext*) override
     {
-        checkThread();
-        (*m_closure)();
+        (*this->m_closure)();
     }
 
 private:
-    CallClosureTask(PassOwnPtr<Closure> closure, bool isSameThread)
-        : CallClosureTaskBase<void()>(std::move(closure), isSameThread)
+    explicit CallClosureTask(PassOwnPtr<Function<void(), threadAffinity>> closure)
+        : CallClosureTaskBase<void(), threadAffinity>(std::move(closure))
+    {
+    }
+};
+
+template<WTF::FunctionThreadAffinity threadAffinity>
+class CallClosureWithExecutionContextTask final : public CallClosureTaskBase<void(ExecutionContext*), threadAffinity> {
+public:
+    // Do not use |create| other than in createCrossThreadTask and
+    // createSameThreadTask.
+    // See http://crbug.com/390851
+    static PassOwnPtr<CallClosureWithExecutionContextTask> create(PassOwnPtr<Function<void(ExecutionContext*), threadAffinity>> closure)
+    {
+        return adoptPtr(new CallClosureWithExecutionContextTask(std::move(closure)));
+    }
+
+    void performTask(ExecutionContext* context) override
+    {
+        (*this->m_closure)(context);
+    }
+
+private:
+    explicit CallClosureWithExecutionContextTask(PassOwnPtr<Function<void(ExecutionContext*), threadAffinity>> closure)
+        : CallClosureTaskBase<void(ExecutionContext*), threadAffinity>(std::move(closure))
     {
     }
 };
@@ -114,7 +118,7 @@
 PassOwnPtr<ExecutionContextTask> createSameThreadTask(
     FunctionType function, const P&... parameters)
 {
-    return internal::CallClosureTask::create(bind(function, parameters...), true);
+    return internal::CallClosureTask<WTF::SameThreadAffinity>::create(bind(function, parameters...));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Microtask.cpp b/third_party/WebKit/Source/core/dom/Microtask.cpp
index 488c577..344c9e01 100644
--- a/third_party/WebKit/Source/core/dom/Microtask.cpp
+++ b/third_party/WebKit/Source/core/dom/Microtask.cpp
@@ -40,13 +40,9 @@
 
 void Microtask::performCheckpoint(v8::Isolate* isolate)
 {
-    V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
-    ASSERT(isolateData);
-    if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint() || isolateData->destructionPending() || ScriptForbiddenScope::isScriptForbidden())
+    if (ScriptForbiddenScope::isScriptForbidden())
         return;
-    isolateData->setPerformingMicrotaskCheckpoint(true);
-    isolate->RunMicrotasks();
-    isolateData->setPerformingMicrotaskCheckpoint(false);
+    v8::MicrotasksScope::PerformCheckpoint(isolate);
 }
 
 static void microtaskFunctionCallback(void* data)
@@ -61,9 +57,9 @@
     isolate->EnqueueMicrotask(&microtaskFunctionCallback, callback.leakPtr());
 }
 
-void Microtask::enqueueMicrotask(PassOwnPtr<Closure> callback)
+void Microtask::enqueueMicrotask(PassOwnPtr<SameThreadClosure> callback)
 {
-    enqueueMicrotask(adoptPtr(new Task(callback)));
+    enqueueMicrotask(adoptPtr(new SameThreadTask(callback)));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Microtask.h b/third_party/WebKit/Source/core/dom/Microtask.h
index 688b6061..82ac7d1 100644
--- a/third_party/WebKit/Source/core/dom/Microtask.h
+++ b/third_party/WebKit/Source/core/dom/Microtask.h
@@ -50,7 +50,7 @@
     // executed in. Until then, all microtasks have to keep track of their
     // ScriptState themselves.
     static void enqueueMicrotask(PassOwnPtr<WebTaskRunner::Task>);
-    static void enqueueMicrotask(PassOwnPtr<Closure>);
+    static void enqueueMicrotask(PassOwnPtr<SameThreadClosure>);
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index f80bd883..046db31 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -276,7 +276,7 @@
     const ComputedStyle* style = layoutBox.style();
     if (!style)
         return 0;
-    if (!(style->overflowY() == OSCROLL || style->overflowY() == OAUTO || focusedElement->hasEditableStyle()))
+    if (!(style->overflowY() == OverflowScroll || style->overflowY() == OverflowAuto || focusedElement->hasEditableStyle()))
         return 0;
     int height = std::min<int>(layoutBox.clientHeight(), frame.view()->visibleHeight());
     return static_cast<unsigned>(max(max<int>(height * ScrollableArea::minFractionToStepWhenPaging(), height - ScrollableArea::maxOverlapBetweenPages()), 1));
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
index 5c51a07..3c7ef36 100644
--- a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
+++ b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
@@ -90,6 +90,7 @@
     pointerEventInit.setScreenY(mouseEvent.globalPosition().y());
     pointerEventInit.setClientX(mouseEvent.position().x());
     pointerEventInit.setClientY(mouseEvent.position().y());
+
     if (pointerEventName == EventTypeNames::pointerdown
         || pointerEventName == EventTypeNames::pointerup) {
         pointerEventInit.setButton(mouseEvent.button());
@@ -266,13 +267,13 @@
     return mappedId;
 }
 
-void PointerEventFactory::remove(
+bool PointerEventFactory::remove(
     const PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
 {
     int mappedId = pointerEvent->pointerId();
     // Do not remove mouse pointer id as it should always be there
     if (mappedId == s_mouseId || !m_pointerIdMapping.contains(mappedId))
-        return;
+        return false;
 
     IncomingId p = m_pointerIdMapping.get(mappedId).incomingId;
     int type = p.pointerType();
@@ -281,6 +282,7 @@
     if (m_primaryId[type] == mappedId)
         m_primaryId[type] = PointerEventFactory::s_invalidId;
     m_idCount[type]--;
+    return true;
 }
 
 bool PointerEventFactory::isPrimary(int mappedId) const
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.h b/third_party/WebKit/Source/core/events/PointerEventFactory.h
index 335e298d..9e34221 100644
--- a/third_party/WebKit/Source/core/events/PointerEventFactory.h
+++ b/third_party/WebKit/Source/core/events/PointerEventFactory.h
@@ -50,10 +50,11 @@
     // Clear all the existing ids.
     void clear();
 
-    // When a pointerEvent with a particular id is removed that id is considered
-    // free even though there might have been other PointerEvents that were
-    // generated with the same id before.
-    void remove(const PassRefPtrWillBeRawPtr<PointerEvent>);
+    // Returns true if pointerEvent is removed. When a pointerEvent with a
+    // particular id is removed that id is considered free even though there
+    // might have been other PointerEvents that were generated with the same id
+    // before.
+    bool remove(const PassRefPtrWillBeRawPtr<PointerEvent>);
 
     // Returns whether a pointer id exists and active
     bool isActive(const int);
@@ -84,6 +85,7 @@
     bool isPrimary(const int) const;
     void setIdTypeButtons(PointerEventInit &, const WebPointerProperties &,
         unsigned buttons);
+
     static const int s_invalidId;
     static const int s_mouseId;
 
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.h b/third_party/WebKit/Source/core/fetch/ImageResource.h
index c17849ad..afbd05f 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.h
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.h
@@ -71,9 +71,6 @@
     static std::pair<blink::Image*, float> brokenImage(float deviceScaleFactor); // Returns an image and the image's resolution scale factor.
     bool willPaintBrokenImage() const;
 
-    // Assumes that image rotation or scale doesn't effect the image size being empty or not.
-    bool canRender() { return !errorOccurred() && !imageSize(DoNotRespectImageOrientation, 1).isEmpty(); }
-
     bool usesImageContainerSize() const;
     bool imageHasRelativeSize() const;
     // The device pixel ratio we got from the server for this image, or 1.0.
diff --git a/third_party/WebKit/Source/core/frame/Console.idl b/third_party/WebKit/Source/core/frame/Console.idl
index 66e8ec31..1c503ef 100644
--- a/third_party/WebKit/Source/core/frame/Console.idl
+++ b/third_party/WebKit/Source/core/frame/Console.idl
@@ -27,8 +27,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// Console API (non-standard but widely implemented in some form)
-// https://developer.chrome.com/devtools/docs/console-api
+// Console API
+// https://console.spec.whatwg.org/#console-interface
 
 // TODO(philipj): Both Firefox and IE expose the Console interface object, and
 // that interface does not inherit from a ConsoleBase or similar interface.
diff --git a/third_party/WebKit/Source/core/frame/ConsoleBase.h b/third_party/WebKit/Source/core/frame/ConsoleBase.h
index c640514..3d0e0205 100644
--- a/third_party/WebKit/Source/core/frame/ConsoleBase.h
+++ b/third_party/WebKit/Source/core/frame/ConsoleBase.h
@@ -32,6 +32,7 @@
 
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/CoreExport.h"
 #include "core/inspector/ConsoleAPITypes.h"
 #include "core/frame/ConsoleTypes.h"
 #include "core/frame/DOMWindowProperty.h"
@@ -43,7 +44,7 @@
 class ConsoleMessage;
 class ScriptArguments;
 
-class ConsoleBase : public GarbageCollectedFinalized<ConsoleBase>, public ScriptWrappable {
+class CORE_EXPORT ConsoleBase : public GarbageCollectedFinalized<ConsoleBase>, public ScriptWrappable {
     DEFINE_WRAPPERTYPEINFO();
 public:
     void debug(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
diff --git a/third_party/WebKit/Source/core/frame/ConsoleBase.idl b/third_party/WebKit/Source/core/frame/ConsoleBase.idl
index 057aca9..f3cc08e 100644
--- a/third_party/WebKit/Source/core/frame/ConsoleBase.idl
+++ b/third_party/WebKit/Source/core/frame/ConsoleBase.idl
@@ -27,8 +27,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// Console API (non-standard but widely implemented in some form)
-// https://developer.chrome.com/devtools/docs/console-api
+// Console API
+// https://console.spec.whatwg.org/#console-interface
 
 [
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index fdb16e9dc..95256f8 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -553,15 +553,15 @@
     EOverflow overflowY = style->overflowY();
 
     if (!shouldIgnoreOverflowHidden()) {
-        if (overflowX == OHIDDEN)
+        if (overflowX == OverflowHidden)
             hMode = ScrollbarAlwaysOff;
-        if (overflowY == OHIDDEN)
+        if (overflowY == OverflowHidden)
             vMode = ScrollbarAlwaysOff;
     }
 
-    if (overflowX == OSCROLL)
+    if (overflowX == OverflowScroll)
         hMode = ScrollbarAlwaysOn;
-    if (overflowY == OSCROLL)
+    if (overflowY == OverflowScroll)
         vMode = ScrollbarAlwaysOn;
 }
 
@@ -2605,7 +2605,7 @@
     const ChildrenWidgetSet* viewChildren = children();
     for (const RefPtrWillBeMember<Widget>& child : *viewChildren) {
         if ((*child).isPluginContainer())
-            toPluginView(child.get())->layoutIfNeeded();
+            toPluginView(child.get())->updateAllLifecyclePhases();
     }
 
     RELEASE_ASSERT(!needsLayout());
@@ -3140,9 +3140,9 @@
     // http://crbug.com/426447
     LayoutObject* viewport = viewportLayoutObject();
     if (viewport && !shouldIgnoreOverflowHidden()) {
-        if (viewport->style()->overflowX() == OHIDDEN)
+        if (viewport->style()->overflowX() == OverflowHidden)
             horizontalMode = ScrollbarAlwaysOff;
-        if (viewport->style()->overflowY() == OHIDDEN)
+        if (viewport->style()->overflowY() == OverflowHidden)
             verticalMode = ScrollbarAlwaysOff;
     }
 
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl
index f73fac75..d769657 100644
--- a/third_party/WebKit/Source/core/frame/Window.idl
+++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -134,8 +134,8 @@
     // http://w3c.github.io/selection-api/#extensions-to-window-interface
     Selection? getSelection();
 
-    // Console API (non-standard but widely implemented in some form)
-    // https://developer.chrome.com/devtools/docs/console-api
+    // Console API
+    // https://console.spec.whatwg.org/#console-interface
     [Replaceable] readonly attribute Console console;
 
     // Non-standard APIs
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
index 145d9608..3549d2e 100644
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
+++ b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
@@ -12,6 +12,7 @@
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutVideo.h"
 #include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutMediaItem.h"
 #include "core/page/Page.h"
 #include "platform/Logging.h"
 #include "platform/UserGestureIndicator.h"
@@ -121,8 +122,8 @@
     }
 
     if (LayoutObject* layoutObject = element().layoutObject()) {
-        LayoutMedia* layoutMedia = toLayoutMedia(layoutObject);
-        layoutMedia->setRequestPositionUpdates(true);
+        LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(layoutObject));
+        layoutMediaItem.setRequestPositionUpdates(true);
     }
 
     // Set this unconditionally, in case we have no layout object yet.
@@ -133,8 +134,8 @@
 {
     if (m_registeredWithLayoutObject) {
         if (LayoutObject* obj = element().layoutObject()) {
-            LayoutMedia* layoutMedia = toLayoutMedia(obj);
-            layoutMedia->setRequestPositionUpdates(false);
+            LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(obj));
+            layoutMediaItem.setRequestPositionUpdates(false);
         }
     }
 
@@ -176,8 +177,8 @@
 void AutoplayExperimentHelper::updatePositionNotificationRegistration()
 {
     if (m_registeredWithLayoutObject) {
-        LayoutMedia* layoutMedia = toLayoutMedia(element().layoutObject());
-        layoutMedia->setRequestPositionUpdates(true);
+        LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(element().layoutObject()));
+        layoutMediaItem.setRequestPositionUpdates(true);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp b/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
index 42825eca..2082697 100644
--- a/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
@@ -157,8 +157,20 @@
     if (isImageType())
         return HTMLPlugInElement::layoutObjectIsNeeded(style);
 
-    // If my parent is an <object> and is not set to use fallback content, I
-    // should be ignored and not get a layoutObject.
+    // https://html.spec.whatwg.org/multipage/embedded-content.html#the-embed-element
+    // While any of the following conditions are occurring, any plugin
+    // instantiated for the element must be removed, and the embed element
+    // represents nothing:
+
+    // * The element has neither a src attribute nor a type attribute.
+    if (!fastHasAttribute(srcAttr) && !fastHasAttribute(typeAttr))
+        return false;
+
+    // * The element has a media element ancestor.
+    // -> It's realized by LayoutMedia::isChildAllowed.
+
+    // * The element has an ancestor object element that is not showing its
+    //   fallback content.
     ContainerNode* p = parentNode();
     if (isHTMLObjectElement(p)) {
         ASSERT(p->layoutObject());
diff --git a/third_party/WebKit/Source/core/html/HTMLFormElement.cpp b/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
index 001143f9..fcb3f89 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
@@ -72,7 +72,6 @@
     , m_hasElementsAssociatedByParser(false)
     , m_hasElementsAssociatedByFormAttribute(false)
     , m_didFinishParsingChildren(false)
-    , m_wasUserSubmitted(false)
     , m_isSubmittingOrInUserJSSubmitEvent(false)
     , m_shouldSubmit(false)
     , m_isInResetFunction(false)
@@ -332,12 +331,12 @@
     m_isSubmittingOrInUserJSSubmitEvent = false;
 
     if (m_shouldSubmit)
-        submit(event, true, true);
+        submit(event, true);
 }
 
 void HTMLFormElement::submitFromJavaScript()
 {
-    submit(0, false, UserGestureIndicator::processingUserGesture());
+    submit(0, false);
 }
 
 void HTMLFormElement::submitDialog(PassRefPtrWillBeRawPtr<FormSubmission> formSubmission)
@@ -350,7 +349,7 @@
     }
 }
 
-void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture)
+void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
 {
     FrameView* view = document().view();
     LocalFrame* frame = document().frame();
@@ -363,7 +362,6 @@
     }
 
     m_isSubmittingOrInUserJSSubmitEvent = true;
-    m_wasUserSubmitted = processingUserGesture;
 
     RefPtrWillBeRawPtr<HTMLFormControlElement> firstSuccessfulSubmitButton = nullptr;
     bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
@@ -668,11 +666,6 @@
     setAttribute(methodAttr, value);
 }
 
-bool HTMLFormElement::wasUserSubmitted() const
-{
-    return m_wasUserSubmitted;
-}
-
 HTMLFormControlElement* HTMLFormElement::findDefaultButton() const
 {
     for (const auto& element : associatedElements()) {
diff --git a/third_party/WebKit/Source/core/html/HTMLFormElement.h b/third_party/WebKit/Source/core/html/HTMLFormElement.h
index 9dbecb71..a9cbccc 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLFormElement.h
@@ -89,8 +89,6 @@
     String method() const;
     void setMethod(const AtomicString&);
 
-    bool wasUserSubmitted() const;
-
     // Find the 'default button.'
     // https://html.spec.whatwg.org/multipage/forms.html#default-button
     HTMLFormControlElement* findDefaultButton() const;
@@ -140,7 +138,7 @@
     void copyNonAttributePropertiesFromElement(const Element&) override;
 
     void submitDialog(PassRefPtrWillBeRawPtr<FormSubmission>);
-    void submit(Event*, bool activateSubmitButton, bool processingUserGesture);
+    void submit(Event*, bool activateSubmitButton);
 
     void scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission>);
 
@@ -179,7 +177,6 @@
     bool m_hasElementsAssociatedByFormAttribute : 1;
     bool m_didFinishParsingChildren : 1;
 
-    bool m_wasUserSubmitted : 1;
     bool m_isSubmittingOrInUserJSSubmitEvent : 1;
     bool m_shouldSubmit : 1;
 
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
index feca3ce..439bf9fd 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
@@ -87,7 +87,7 @@
     return s_sharedThread;
 }
 
-void HTMLParserThread::postTask(PassOwnPtr<Closure> closure)
+void HTMLParserThread::postTask(PassOwnPtr<CrossThreadClosure> closure)
 {
     ASSERT(isMainThread());
     if (!m_thread) {
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h b/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
index ee6b8c5..67fe62d 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
@@ -50,7 +50,7 @@
     // It is an error to call shared() before init() or after shutdown();
     static HTMLParserThread* shared();
 
-    void postTask(PassOwnPtr<Closure>);
+    void postTask(PassOwnPtr<CrossThreadClosure>);
 
 private:
     HTMLParserThread();
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index d0507f4e..6dd5400 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -1662,6 +1662,27 @@
     return toWebInputEventResult(m_nodeUnderMouse->dispatchEvent(event));
 }
 
+bool EventHandler::isPointerEventActive(int pointerId)
+{
+    return m_pointerEventManager.isActive(pointerId);
+}
+
+void EventHandler::setPointerCapture(int pointerId, EventTarget* target)
+{
+    // TODO(crbug.com/591387): This functionality should be per page not per frame.
+    m_pointerEventManager.setPointerCapture(pointerId, target);
+}
+
+void EventHandler::releasePointerCapture(int pointerId, EventTarget* target)
+{
+    m_pointerEventManager.releasePointerCapture(pointerId, target);
+}
+
+void EventHandler::elementRemoved(EventTarget* target)
+{
+    m_pointerEventManager.elementRemoved(target);
+}
+
 // TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler.
 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const AtomicString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
 {
diff --git a/third_party/WebKit/Source/core/input/EventHandler.h b/third_party/WebKit/Source/core/input/EventHandler.h
index d29d956..276d2ded 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.h
+++ b/third_party/WebKit/Source/core/input/EventHandler.h
@@ -178,6 +178,13 @@
     WebInputEventResult sendContextMenuEventForKey(Element* overrideTargetElement = nullptr);
     WebInputEventResult sendContextMenuEventForGesture(const GestureEventWithHitTestResults&);
 
+    // Returns whether pointerId is active or not
+    bool isPointerEventActive(int);
+
+    void setPointerCapture(int, EventTarget*);
+    void releasePointerCapture(int, EventTarget*);
+    void elementRemoved(EventTarget*);
+
     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
 
     static WebInputEventResult mergeEventResult(WebInputEventResult resultA, WebInputEventResult resultB);
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
index 459f2f4..1179aa8 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -36,22 +36,6 @@
     return n && n->toNode() && n->toNode()->inDocument();
 }
 
-WebInputEventResult dispatchPointerEvent(
-    PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
-    PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
-    bool checkForListener = false)
-{
-    RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
-    RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
-    if (!RuntimeEnabledFeatures::pointerEventEnabled())
-        return WebInputEventResult::NotHandled;
-    if (!checkForListener || target->hasEventListeners(pointerEvent->type())) {
-        DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent);
-        return EventHandler::toWebInputEventResult(dispatchResult);
-    }
-    return WebInputEventResult::NotHandled;
-}
-
 WebInputEventResult dispatchMouseEvent(
     PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
     const AtomicString& mouseEventType,
@@ -76,12 +60,41 @@
 
 } // namespace
 
-PassRefPtrWillBeRawPtr<Node> PointerEventManager::getEffectiveTargetForPointerEvent(
-    PassRefPtrWillBeRawPtr<Node> target,
-    PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
+WebInputEventResult PointerEventManager::dispatchPointerEvent(
+    PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
+    PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
+    bool checkForListener)
 {
-    // TODO(nzolghadr): Add APIs to set the capturing nodes and return the correct node here
-    (void) pointerEvent;
+    RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
+    RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
+
+    // Set whether node under pointer has received pointerover or not.
+    int pointerId = pointerEvent->pointerId();
+    if ((pointerEvent->type() == EventTypeNames::pointerout
+        || pointerEvent->type() == EventTypeNames::pointerover)
+        && m_nodeUnderPointer.contains(pointerId)) {
+        RefPtrWillBeRawPtr<EventTarget> targetUnderPointer =
+            m_nodeUnderPointer.get(pointerId).target;
+        if (targetUnderPointer == target) {
+            m_nodeUnderPointer.set(pointerId, EventTargetAttributes
+                (targetUnderPointer,
+                pointerEvent->type() == EventTypeNames::pointerover));
+        }
+    }
+    if (!RuntimeEnabledFeatures::pointerEventEnabled())
+        return WebInputEventResult::NotHandled;
+    if (!checkForListener || target->hasEventListeners(pointerEvent->type())) {
+        DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent);
+        return EventHandler::toWebInputEventResult(dispatchResult);
+    }
+    return WebInputEventResult::NotHandled;
+}
+
+PassRefPtrWillBeRawPtr<EventTarget> PointerEventManager::getEffectiveTargetForPointerEvent(
+    PassRefPtrWillBeRawPtr<EventTarget> target, int pointerId)
+{
+    if (EventTarget* capturingTarget = getCapturingNode(pointerId))
+        return capturingTarget;
     return target;
 }
 
@@ -92,10 +105,14 @@
     const PlatformMouseEvent& mouseEvent,
     PassRefPtrWillBeRawPtr<AbstractView> view)
 {
+    RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
+        m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent,
+        nullptr, view);
+    processPendingPointerCapture(pointerEvent, enteredNode, mouseEvent, true);
+
     // Pointer event type does not matter as it will be overridden in the sendNodeTransitionEvents
-    sendNodeTransitionEvents(exitedNode, enteredNode,
-        m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent, nullptr, view),
-        mouseEvent, true);
+    sendNodeTransitionEvents(exitedNode, enteredNode, pointerEvent, mouseEvent,
+        true);
 }
 
 void PointerEventManager::sendNodeTransitionEvents(
@@ -110,6 +127,15 @@
     if (exitedTarget == enteredTarget)
         return;
 
+    if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId())) {
+        if (capturingTarget == exitedTarget)
+            enteredTarget = nullptr;
+        else if (capturingTarget == enteredTarget)
+            exitedTarget = nullptr;
+        else
+            return;
+    }
+
     // Dispatch pointerout/mouseout events
     if (isInDocument(exitedTarget)) {
         dispatchPointerEvent(exitedTarget, m_pointerEventFactory.create(
@@ -230,15 +256,19 @@
     RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
     RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
     if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) {
-        sendNodeTransitionEvents(m_nodeUnderPointer.get(
-            pointerEvent->pointerId()), target, pointerEvent);
-        if (!target)
+        EventTargetAttributes node = m_nodeUnderPointer.get(
+            pointerEvent->pointerId());
+        if (!target) {
             m_nodeUnderPointer.remove(pointerEvent->pointerId());
-        else
-            m_nodeUnderPointer.set(pointerEvent->pointerId(), target);
+        } else {
+            m_nodeUnderPointer.set(pointerEvent->pointerId(),
+                EventTargetAttributes(target, false));
+        }
+        sendNodeTransitionEvents(node.target, target, pointerEvent);
     } else if (target) {
+        m_nodeUnderPointer.add(pointerEvent->pointerId(),
+            EventTargetAttributes(target, false));
         sendNodeTransitionEvents(nullptr, target, pointerEvent);
-        m_nodeUnderPointer.add(pointerEvent->pointerId(), target);
     }
 }
 
@@ -248,11 +278,16 @@
     RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
         m_pointerEventFactory.createPointerCancel(point);
 
-    // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
-    target->dispatchEvent(pointerEvent.get());
+    processPendingPointerCapture(pointerEvent, target);
 
-    m_pointerEventFactory.remove(pointerEvent);
+    // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
+    dispatchPointerEvent(
+        getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
+        pointerEvent.get());
+
     setNodeUnderPointer(pointerEvent, nullptr);
+
+    removePointer(pointerEvent);
 }
 
 WebInputEventResult PointerEventManager::sendTouchPointerEvent(
@@ -262,20 +297,25 @@
     const double clientX, const double clientY)
 {
     RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
+
     RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
         m_pointerEventFactory.create(
         pointerEventNameForTouchPointState(touchPoint.state()),
         touchPoint, modifiers, width, height, clientX, clientY);
 
+    processPendingPointerCapture(pointerEvent, target);
+
     setNodeUnderPointer(pointerEvent, target);
 
     // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
-    WebInputEventResult result = dispatchPointerEvent(target, pointerEvent.get());
+    WebInputEventResult result = dispatchPointerEvent(
+        getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
+        pointerEvent.get());
 
     if (touchPoint.state() == PlatformTouchPoint::TouchReleased
         || touchPoint.state() == PlatformTouchPoint::TouchCancelled) {
-        m_pointerEventFactory.remove(pointerEvent);
         setNodeUnderPointer(pointerEvent, nullptr);
+        removePointer(pointerEvent);
     }
 
     return result;
@@ -291,8 +331,13 @@
         m_pointerEventFactory.create(mouseEventType, mouseEvent,
         relatedTarget, view);
 
-    RefPtrWillBeRawPtr<Node> effectiveTarget =
-        getEffectiveTargetForPointerEvent(target, pointerEvent);
+    processPendingPointerCapture(pointerEvent, target, mouseEvent, true);
+
+    // TODO(crbug.com/587955): We should call setNodeUnderPointer here but it causes sending
+    // transition events that should be first removed from EventHandler.
+
+    RefPtrWillBeRawPtr<EventTarget> effectiveTarget =
+        getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId());
 
     WebInputEventResult result =
         dispatchPointerEvent(effectiveTarget, pointerEvent);
@@ -307,6 +352,9 @@
             nullptr, clickCount));
     }
 
+    if (pointerEvent->buttons() == 0)
+        releasePointerCapture(pointerEvent->pointerId());
+
     return result;
 }
 
@@ -335,10 +383,117 @@
         m_preventMouseEventForPointerTypeMouse = false;
 }
 
+void PointerEventManager::processPendingPointerCapture(
+    const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
+    const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
+    const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
+{
+    // TODO(nzolghadr): Process sending got/lostpointercapture
+    RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
+    RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
+    int pointerId = pointerEvent->pointerId();
+    bool hasPointerCaptureTarget = m_pointerCaptureTarget.contains(pointerId);
+    bool hasPendingPointerCaptureTarget = m_pendingPointerCaptureTarget.contains(pointerId);
+    const RefPtrWillBeRawPtr<EventTarget> pointerCaptureTarget =
+        hasPointerCaptureTarget ? m_pointerCaptureTarget.get(pointerId) : nullptr;
+    const RefPtrWillBeRawPtr<EventTarget> pendingPointerCaptureTarget =
+        hasPendingPointerCaptureTarget ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr;
+
+    if (hasPendingPointerCaptureTarget
+        && (pointerCaptureTarget != pendingPointerCaptureTarget)) {
+        if (!hasPointerCaptureTarget
+            && pendingPointerCaptureTarget != hitTestTarget
+            && m_nodeUnderPointer.contains(pointerId)
+            && m_nodeUnderPointer.get(pointerId).hasRecievedOverEvent) {
+            sendNodeTransitionEvents(hitTestTarget, nullptr, pointerEvent,
+                mouseEvent, sendMouseEvent);
+        }
+    }
+
+    // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does
+    // affect the behavior of sendNodeTransitionEvents function. So the
+    // ordering of the surrounding blocks of code is important.
+    if (!hasPendingPointerCaptureTarget)
+        m_pointerCaptureTarget.remove(pointerId);
+    else
+        m_pointerCaptureTarget.set(pointerId, m_pendingPointerCaptureTarget.get(pointerId));
+
+    if (hasPointerCaptureTarget && (pointerCaptureTarget != pendingPointerCaptureTarget)) {
+        if (!hasPendingPointerCaptureTarget && pointerCaptureTarget != hitTestTarget) {
+            sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent,
+                mouseEvent, sendMouseEvent);
+        }
+    }
+
+}
+
+void PointerEventManager::removeTargetFromPointerCapturingMapping(
+    PointerCapturingMap& map, const EventTarget* target)
+{
+    // We could have kept a reverse mapping to make this deletion possibly
+    // faster but it adds some code complication which might not be worth of
+    // the performance improvement considering there might not be a lot of
+    // active pointer or pointer captures at the same time.
+    PointerCapturingMap tmp = map;
+    for (PointerCapturingMap::iterator it = tmp.begin(); it != tmp.end(); ++it) {
+        if (it->value == target)
+            map.remove(it->key);
+    }
+}
+
+EventTarget* PointerEventManager::getCapturingNode(int pointerId)
+{
+    if (m_pointerCaptureTarget.contains(pointerId))
+        return m_pointerCaptureTarget.get(pointerId);
+    return nullptr;
+}
+
+void PointerEventManager::removePointer(
+    const PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
+{
+    if (m_pointerEventFactory.remove(pointerEvent)) {
+        int pointerId = pointerEvent->pointerId();
+        m_pendingPointerCaptureTarget.remove(pointerId);
+        m_pointerCaptureTarget.remove(pointerId);
+        m_nodeUnderPointer.remove(pointerId);
+    }
+}
+
+void PointerEventManager::elementRemoved(EventTarget* target)
+{
+    removeTargetFromPointerCapturingMapping(m_pointerCaptureTarget, target);
+    removeTargetFromPointerCapturingMapping(m_pendingPointerCaptureTarget, target);
+    // TODO(nzolghadr): Process sending lostpointercapture to the document
+}
+
+void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target)
+{
+    if (m_pointerEventFactory.isActiveButtonsState(pointerId))
+        m_pendingPointerCaptureTarget.set(pointerId, target);
+}
+
+void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* target)
+{
+    if (m_pointerCaptureTarget.get(pointerId) == target)
+        releasePointerCapture(pointerId);
+}
+
+void PointerEventManager::releasePointerCapture(int pointerId)
+{
+    m_pendingPointerCaptureTarget.remove(pointerId);
+}
+
+bool PointerEventManager::isActive(const int pointerId)
+{
+    return m_pointerEventFactory.isActive(pointerId);
+}
+
 DEFINE_TRACE(PointerEventManager)
 {
 #if ENABLE(OILPAN)
     visitor->trace(m_nodeUnderPointer);
+    visitor->trace(m_pointerCaptureTarget);
+    visitor->trace(m_pendingPointerCaptureTarget);
 #endif
 }
 
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.h b/third_party/WebKit/Source/core/input/PointerEventManager.h
index 093f739..8845521 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.h
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.h
@@ -54,11 +54,29 @@
     // https://w3c.github.io/pointerevents/#compatibility-mapping-with-mouse-events
     void conditionallyEnableMouseEventForPointerTypeMouse(unsigned);
 
+    void elementRemoved(EventTarget*);
+    void setPointerCapture(int, EventTarget*);
+    void releasePointerCapture(int, EventTarget*);
+    bool isActive(const int);
 
 private:
-    PassRefPtrWillBeRawPtr<Node> getEffectiveTargetForPointerEvent(
-        PassRefPtrWillBeRawPtr<Node>,
-        PassRefPtrWillBeRawPtr<PointerEvent>);
+    typedef WillBeHeapHashMap<int, RefPtrWillBeMember<EventTarget>> PointerCapturingMap;
+    class EventTargetAttributes {
+        DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+    public:
+        DEFINE_INLINE_TRACE()
+        {
+            visitor->trace(target);
+        }
+        RefPtrWillBeMember<EventTarget> target;
+        bool hasRecievedOverEvent;
+        EventTargetAttributes() {}
+        EventTargetAttributes(PassRefPtrWillBeRawPtr<EventTarget> target,
+            bool hasRecievedOverEvent)
+        : target(target)
+        , hasRecievedOverEvent(hasRecievedOverEvent) {}
+    };
+
     void sendNodeTransitionEvents(
         PassRefPtrWillBeRawPtr<EventTarget> exitedTarget,
         PassRefPtrWillBeRawPtr<EventTarget> enteredTarget,
@@ -67,6 +85,22 @@
         bool sendMouseEvent = false);
     void setNodeUnderPointer(PassRefPtrWillBeRawPtr<PointerEvent>,
         PassRefPtrWillBeRawPtr<EventTarget>);
+    void processPendingPointerCapture(
+        const PassRefPtrWillBeRawPtr<PointerEvent>,
+        const PassRefPtrWillBeRawPtr<EventTarget>,
+        const PlatformMouseEvent& = PlatformMouseEvent(),
+        bool sendMouseEvent = false);
+    void removeTargetFromPointerCapturingMapping(
+        PointerCapturingMap&, const EventTarget*);
+    PassRefPtrWillBeRawPtr<EventTarget> getEffectiveTargetForPointerEvent(
+        PassRefPtrWillBeRawPtr<EventTarget>, int);
+    EventTarget* getCapturingNode(int);
+    void removePointer(const PassRefPtrWillBeRawPtr<PointerEvent>);
+    WebInputEventResult dispatchPointerEvent(
+        PassRefPtrWillBeRawPtr<EventTarget>,
+        PassRefPtrWillBeRawPtr<PointerEvent>,
+        bool checkForListener = false);
+    void releasePointerCapture(int);
 
     // Prevents firing mousedown, mousemove & mouseup in-between a canceled pointerdown and next pointerup/pointercancel.
     // See "PREVENT MOUSE EVENT flag" in the spec:
@@ -77,8 +111,10 @@
     // which might be different than m_nodeUnderMouse in EventHandler. That one
     // keeps track of any compatibility mouse event positions but this map for
     // the pointer with id=1 is only taking care of true mouse related events.
-    WillBeHeapHashMap<int, RefPtrWillBeMember<EventTarget>> m_nodeUnderPointer;
+    WillBeHeapHashMap<int, EventTargetAttributes> m_nodeUnderPointer;
 
+    PointerCapturingMap m_pointerCaptureTarget;
+    PointerCapturingMap m_pendingPointerCaptureTarget;
     PointerEventFactory m_pointerEventFactory;
 };
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
index b58780e..344b77e 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
@@ -149,7 +149,7 @@
     checkDone();
 }
 
-void InspectorResourceContentLoader::ensureResourcesContentLoaded(PassOwnPtr<Closure> callback)
+void InspectorResourceContentLoader::ensureResourcesContentLoaded(PassOwnPtr<SameThreadClosure> callback)
 {
     if (!m_started)
         start();
@@ -204,7 +204,7 @@
 {
     if (!hasFinished())
         return;
-    Vector<OwnPtr<Closure>> callbacks;
+    Vector<OwnPtr<SameThreadClosure>> callbacks;
     callbacks.swap(m_callbacks);
     for (const auto& callback : callbacks)
         (*callback)();
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
index f22b146..c219f33 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
@@ -29,7 +29,7 @@
     void dispose();
     DECLARE_TRACE();
 
-    void ensureResourcesContentLoaded(PassOwnPtr<Closure> callback);
+    void ensureResourcesContentLoaded(PassOwnPtr<SameThreadClosure> callback);
     void didCommitLoadForLocalFrame(LocalFrame*);
 
 private:
@@ -42,7 +42,7 @@
     void stop();
     bool hasFinished();
 
-    Vector<OwnPtr<Closure>> m_callbacks;
+    Vector<OwnPtr<SameThreadClosure>> m_callbacks;
     bool m_allRequestsStarted;
     bool m_started;
     RawPtrWillBeMember<LocalFrame> m_inspectedFrame;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h b/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h
index 39eab97b..4802caf 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h
@@ -25,7 +25,7 @@
     InspectorTaskRunner();
     ~InspectorTaskRunner();
 
-    using Task = WTF::Closure;
+    using Task = WTF::CrossThreadClosure;
     void appendTask(PassOwnPtr<Task>);
 
     enum WaitMode { WaitForTask, DontWaitForTask };
diff --git a/third_party/WebKit/Source/core/layout/ImageQualityController.cpp b/third_party/WebKit/Source/core/layout/ImageQualityController.cpp
index 75ab1856..f85d2d84 100644
--- a/third_party/WebKit/Source/core/layout/ImageQualityController.cpp
+++ b/third_party/WebKit/Source/core/layout/ImageQualityController.cpp
@@ -89,7 +89,6 @@
 
 ImageQualityController::ImageQualityController()
     : m_timer(adoptPtr(new Timer<ImageQualityController>(this, &ImageQualityController::highQualityRepaintTimerFired)))
-    , m_liveResizeOptimizationIsActive(false)
 {
 }
 
@@ -131,13 +130,6 @@
 void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityController>*)
 {
     for (auto* layoutObject : m_objectLayerSizeMap.keys()) {
-        if (LocalFrame* frame = layoutObject->document().frame()) {
-            // If this layoutObject's containing FrameView is in live resize, punt the timer and hold back for now.
-            if (frame->view() && frame->view()->inLiveResize()) {
-                restartTimer();
-                return;
-            }
-        }
         ObjectLayerSizeMap::iterator i = m_objectLayerSizeMap.find(layoutObject);
         if (i != m_objectLayerSizeMap.end()) {
             // Only invalidate the object if it is animating.
@@ -148,8 +140,6 @@
             i->value.isResizing = false;
         }
     }
-
-    m_liveResizeOptimizationIsActive = false;
 }
 
 void ImageQualityController::restartTimer()
@@ -188,22 +178,6 @@
         }
     }
 
-    // If the containing FrameView is being resized, paint at low quality until resizing is finished.
-    if (LocalFrame* frame = object.document().frame()) {
-        bool frameViewIsCurrentlyInLiveResize = frame->view() && frame->view()->inLiveResize();
-        if (frameViewIsCurrentlyInLiveResize) {
-            set(object, innerMap, layer, layoutSize, true);
-            restartTimer();
-            m_liveResizeOptimizationIsActive = true;
-            return true;
-        }
-        if (m_liveResizeOptimizationIsActive) {
-            // Live resize has ended, paint in HQ and remove this object from the list.
-            removeLayer(object, innerMap, layer);
-            return false;
-        }
-    }
-
     if (layoutSize == image->size()) {
         // There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
         removeLayer(object, innerMap, layer);
diff --git a/third_party/WebKit/Source/core/layout/ImageQualityController.h b/third_party/WebKit/Source/core/layout/ImageQualityController.h
index 64b876c..52925b0 100644
--- a/third_party/WebKit/Source/core/layout/ImageQualityController.h
+++ b/third_party/WebKit/Source/core/layout/ImageQualityController.h
@@ -82,7 +82,6 @@
 
     ObjectLayerSizeMap m_objectLayerSizeMap;
     OwnPtr<Timer<ImageQualityController>> m_timer;
-    bool m_liveResizeOptimizationIsActive;
 
     // For calling set().
     FRIEND_TEST_ALL_PREFIXES(LayoutPartTest, DestroyUpdatesImageQualityController);
diff --git a/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp b/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp
index 6a8b62f9..c9e585a 100644
--- a/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp
+++ b/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp
@@ -122,36 +122,6 @@
     }
 };
 
-TEST_F(ImageQualityControllerTest, LowQualityFilterForLiveResize)
-{
-    MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::highQualityRepaintTimerFired);
-    controller()->setTimer(mockTimer);
-    setBodyInnerHTML("<img src='myimage'></img>");
-    LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObject());
-
-    RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality);
-
-    // Start a resize
-    document().frame()->view()->willStartLiveResize();
-    EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, testImage.get(), testImage.get(), LayoutSize(2, 2)));
-
-    document().frame()->view()->willEndLiveResize();
-
-    // End of live resize, but timer has not fired. Therefore paint at non-low quality.
-    EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(*img, testImage.get(), testImage.get(), LayoutSize(3, 3)));
-
-    // Start another resize
-    document().frame()->view()->willStartLiveResize();
-    EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, testImage.get(), testImage.get(), LayoutSize(3, 3)));
-
-    // While still in resize, expire the timer.
-    document().frame()->view()->willEndLiveResize();
-
-    mockTimer->fire();
-    // End of live resize, and timer has fired. Therefore paint at non-low quality, even though the size has changed.
-    EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(*img, testImage.get(), testImage.get(), LayoutSize(4, 4)));
-}
-
 TEST_F(ImageQualityControllerTest, LowQualityFilterForResizingImage)
 {
     MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::highQualityRepaintTimerFired);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index c32c6c3..36f2b0f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -2034,11 +2034,11 @@
         RefPtr<ComputedStyle> childStyle = child->mutableStyle();
         if (child->isFloating() || (child->isBox() && toLayoutBox(child)->avoidsFloats())) {
             LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth;
-            if (childStyle->clear() & CLEFT) {
+            if (childStyle->clear() & ClearLeft) {
                 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth);
                 floatLeftWidth = LayoutUnit();
             }
-            if (childStyle->clear() & CRIGHT) {
+            if (childStyle->clear() & ClearRight) {
                 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth);
                 floatRightWidth = LayoutUnit();
             }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index b901749..22ac50c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -1458,7 +1458,7 @@
     // If we have a 'clear' value but also have a margin we may not actually require clearance to move past any floats.
     // If that's the case we want to be sure we estimate the correct position including margins after any floats rather
     // than use 'clearance' later which could give us the wrong position.
-    if (grandchildBox->style()->clear() != CNONE && childBlockFlow->marginBeforeForChild(*grandchildBox) == 0)
+    if (grandchildBox->style()->clear() != ClearNone && childBlockFlow->marginBeforeForChild(*grandchildBox) == 0)
         return;
 
     // Collapse the margin of the grandchild box with our own to produce an estimate.
@@ -1818,18 +1818,18 @@
         return LayoutUnit();
 
     // At least one float is present. We need to perform the clearance computation.
-    bool clearSet = child->style()->clear() != CNONE;
+    bool clearSet = child->style()->clear() != ClearNone;
     LayoutUnit logicalBottom;
     switch (child->style()->clear()) {
-    case CNONE:
+    case ClearNone:
         break;
-    case CLEFT:
+    case ClearLeft:
         logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
         break;
-    case CRIGHT:
+    case ClearRight:
         logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
         break;
-    case CBOTH:
+    case ClearBoth:
         logicalBottom = lowestFloatLogicalBottom();
         break;
     }
@@ -2117,13 +2117,13 @@
     // set y position
     LayoutUnit newY;
     switch (clear) {
-    case CLEFT:
+    case ClearLeft:
         newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
         break;
-    case CRIGHT:
+    case ClearRight:
         newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
         break;
-    case CBOTH:
+    case ClearBoth:
         newY = lowestFloatLogicalBottom();
     default:
         break;
@@ -2380,9 +2380,9 @@
         childBox->setMayNeedPaintInvalidation();
 
         LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(*childBox) : marginEndForChild(*childBox);
-        if (childBox->style()->clear() & CLEFT)
+        if (childBox->style()->clear() & ClearLeft)
             logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
-        if (childBox->style()->clear() & CRIGHT)
+        if (childBox->style()->clear() & ClearRight)
             logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
 
         LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, logicalTop);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index f10e2fb8..db3c4e72 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -1332,8 +1332,8 @@
                 bool clearPreviousFloat;
                 if (child->isFloating()) {
                     clearPreviousFloat = (prevFloat
-                        && ((prevFloat->styleRef().floating() == LeftFloat && (childStyle.clear() & CLEFT))
-                            || (prevFloat->styleRef().floating() == RightFloat && (childStyle.clear() & CRIGHT))));
+                        && ((prevFloat->styleRef().floating() == LeftFloat && (childStyle.clear() & ClearLeft))
+                            || (prevFloat->styleRef().floating() == RightFloat && (childStyle.clear() & ClearRight))));
                     prevFloat = child;
                 } else {
                     clearPreviousFloat = false;
@@ -1749,7 +1749,7 @@
     if (!curr->endsWithBreak())
         return false;
     InlineBox* lastBox = style()->isLeftToRightDirection() ? curr->lastLeafChild() : curr->firstLeafChild();
-    return lastBox && lastBox->getLineLayoutItem().isBR() && lastBox->getLineLayoutItem().style()->clear() != CNONE;
+    return lastBox && lastBox->getLineLayoutItem().isBR() && lastBox->getLineLayoutItem().style()->clear() != ClearNone;
 }
 
 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 469e8e29..c48220c9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -734,7 +734,7 @@
 
 int LayoutBox::verticalScrollbarWidth() const
 {
-    if (!hasOverflowClip() || style()->overflowY() == OOVERLAY)
+    if (!hasOverflowClip() || style()->overflowY() == OverflowOverlay)
         return 0;
 
     return scrollableArea()->verticalScrollbarWidth();
@@ -742,7 +742,7 @@
 
 int LayoutBox::horizontalScrollbarHeight() const
 {
-    if (!hasOverflowClip() || style()->overflowX() == OOVERLAY)
+    if (!hasOverflowClip() || style()->overflowX() == OverflowOverlay)
         return 0;
 
     return scrollableArea()->horizontalScrollbarHeight();
@@ -755,13 +755,13 @@
 
     ASSERT(scrollableArea());
 
-    if (isHorizontalWritingMode() && style()->overflowY() == OSCROLL) {
-        // Even with OSCROLL, the scrollbar may not exist (crbug.com/415031).
+    if (isHorizontalWritingMode() && style()->overflowY() == OverflowScroll) {
+        // Even with OverflowScroll, the scrollbar may not exist (crbug.com/415031).
         return scrollableArea()->hasVerticalScrollbar() ? verticalScrollbarWidth() : 0;
     }
 
-    if (!isHorizontalWritingMode() && style()->overflowX() == OSCROLL) {
-        // Even with OSCROLL, the scrollbar may not exist (crbug.com/415031).
+    if (!isHorizontalWritingMode() && style()->overflowX() == OverflowScroll) {
+        // Even with OverflowScroll, the scrollbar may not exist (crbug.com/415031).
         return scrollableArea()->hasHorizontalScrollbar() ? horizontalScrollbarHeight() : 0;
     }
 
@@ -2079,7 +2079,7 @@
     // Width calculations
     if (treatAsReplaced) {
         computedValues.m_extent = LayoutUnit(logicalWidthLength.value()) + borderAndPaddingLogicalWidth();
-    } else if (parent()->isLayoutGrid() && style()->logicalWidth().isAuto() && style()->logicalMinWidth().isAuto() && style()->overflowX() == OVISIBLE && containerLogicalWidth < minPreferredLogicalWidth()) {
+    } else if (parent()->isLayoutGrid() && style()->logicalWidth().isAuto() && style()->logicalMinWidth().isAuto() && style()->overflowX() == OverflowVisible && containerLogicalWidth < minPreferredLogicalWidth()) {
         // TODO (lajava) Move this logic to the LayoutGrid class.
         // Implied minimum size of Grid items.
         computedValues.m_extent = constrainLogicalWidthByMinMax(minPreferredLogicalWidth(), containerLogicalWidth, cb);
@@ -2420,7 +2420,7 @@
         // https://bugs.webkit.org/show_bug.cgi?id=46418
         if (hasOverrideLogicalContentHeight()) {
             LayoutUnit contentHeight = overrideLogicalContentHeight();
-            if (parent()->isLayoutGrid() && style()->logicalMinHeight().isAuto() && style()->overflowY() == OVISIBLE) {
+            if (parent()->isLayoutGrid() && style()->logicalMinHeight().isAuto() && style()->overflowY() == OverflowVisible) {
                 ASSERT(style()->logicalHeight().isAuto());
                 LayoutUnit minContentHeight = computeContentLogicalHeight(MinSize, Length(MinContent), computedValues.m_extent - borderAndPaddingLogicalHeight());
                 contentHeight = std::max(contentHeight, constrainContentBoxLogicalHeightByMinMax(minContentHeight, computedValues.m_extent - borderAndPaddingLogicalHeight()));
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h
index 0f1f655..c2d018d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -701,15 +701,15 @@
     virtual void stopAutoscroll() { }
     virtual void panScroll(const IntPoint&);
 
-    bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OAUTO || style()->overflowY() == OPAGEDY || style()->overflowY() == OOVERLAY); }
-    bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO || style()->overflowX() == OOVERLAY); }
+    bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OverflowAuto || style()->overflowY() == OverflowPagedY || style()->overflowY() == OverflowOverlay); }
+    bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OverflowAuto || style()->overflowX() == OverflowOverlay); }
     bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); }
     virtual bool shouldPlaceBlockDirectionScrollbarOnLogicalLeft() const { return style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft(); }
 
     bool hasScrollableOverflowX() const { return scrollsOverflowX() && pixelSnappedScrollWidth() != pixelSnappedClientWidth(); }
     bool hasScrollableOverflowY() const { return scrollsOverflowY() && pixelSnappedScrollHeight() != pixelSnappedClientHeight(); }
-    virtual bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || hasAutoHorizontalScrollbar()); }
-    virtual bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || hasAutoVerticalScrollbar()); }
+    virtual bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OverflowScroll || hasAutoHorizontalScrollbar()); }
+    virtual bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OverflowScroll || hasAutoVerticalScrollbar()); }
 
     // Elements such as the <input> field override this to specify that they are scrollable
     // outside the context of the CSS overflow style
diff --git a/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp b/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp
index 6c4b14d2..e96868f3 100644
--- a/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp
@@ -134,8 +134,9 @@
 
     Widget* widget = this->widget();
     if (widget) {
+        // TODO(chrishtr): remove this code. It's now called in FrameView::updateStyleAndLayoutIfNeededRecursive.
         if (widget->isPluginView())
-            toPluginView(widget)->layoutIfNeeded();
+            toPluginView(widget)->updateAllLifecyclePhases();
     } else if (frameView()) {
         frameView()->addPartToUpdate(*this);
     }
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index 894bcc53..c4d964b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -715,7 +715,7 @@
 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(const LayoutBox& child) const
 {
     return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && (
-        hasOrthogonalFlow(child) || crossAxisOverflowForChild(child) == OAUTO);
+        hasOrthogonalFlow(child) || crossAxisOverflowForChild(child) == OverflowAuto);
 }
 
 void LayoutFlexibleBox::cacheChildMainSize(const LayoutBox& child)
@@ -994,7 +994,7 @@
         // computeMainAxisExtentForChild can return -1 when the child has a percentage
         // min size, but we have an indefinite size in that axis.
         minExtent = std::max(LayoutUnit(), minExtent);
-    } else if (min.isAuto() && mainAxisOverflowForChild(child) == OVISIBLE && !(isColumnFlow() && child.isFlexibleBox())) {
+    } else if (min.isAuto() && mainAxisOverflowForChild(child) == OverflowVisible && !(isColumnFlow() && child.isFlexibleBox())) {
         // TODO(cbiesinger): For now, we do not handle min-height: auto for nested column flexboxes. We need
         // to implement https://drafts.csswg.org/css-flexbox/#intrinsic-sizes before that produces
         // reasonable results. Tracking bug: https://crbug.com/581553
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index c49a7f40..9ccca19 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -711,13 +711,13 @@
     if (hasOrthogonalWritingMode)
         return LayoutUnit();
 
-    const Length& childMinSize = direction == ForColumns ? child.style()->logicalMinWidth() : child.style()->logicalMinHeight();
-    if (childMinSize.isAuto()) {
-        // TODO(svillar): Implement intrinsic aspect ratio support (transferred size in specs).
+    bool isRowAxis = direction == ForColumns;
+    const Length& childSize = isRowAxis ? child.styleRef().logicalWidth() : child.styleRef().logicalHeight();
+    const Length& childMinSize = isRowAxis ? child.styleRef().logicalMinWidth() : child.styleRef().logicalMinHeight();
+    if (!childSize.isAuto() || childMinSize.isAuto())
         return minContentForChild(child, direction, columnTracks);
-    }
 
-    if (direction == ForColumns)
+    if (isRowAxis)
         return child.computeLogicalWidthUsing(MinSize, childMinSize, contentLogicalWidth(), this);
 
     return child.computeContentLogicalHeight(MinSize, childMinSize, child.logicalHeight()) + child.scrollbarLogicalHeight();
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
index b067eca..c1337bf 100644
--- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -209,8 +209,8 @@
     LayoutInline* parentLayoutInline = parent()->isLayoutInline() ? toLayoutInline(parent()) : 0;
     bool checkFonts = document().inNoQuirksMode();
     bool alwaysCreateLineBoxesNew = (parentLayoutInline && parentLayoutInline->alwaysCreateLineBoxes())
-        || (parentLayoutInline && parentStyle.verticalAlign() != BASELINE)
-        || style()->verticalAlign() != BASELINE
+        || (parentLayoutInline && parentStyle.verticalAlign() != VerticalAlignBaseline)
+        || style()->verticalAlign() != VerticalAlignBaseline
         || style()->getTextEmphasisMark() != TextEmphasisMarkNone
         || (checkFonts && (!parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(style()->font().fontMetrics())
         || parentStyle.lineHeight() != style()->lineHeight()));
@@ -220,7 +220,7 @@
         const ComputedStyle& firstLineParentStyle = parent()->styleRef(true);
         const ComputedStyle& childStyle = styleRef(true);
         alwaysCreateLineBoxesNew = !firstLineParentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics())
-        || childStyle.verticalAlign() != BASELINE
+        || childStyle.verticalAlign() != VerticalAlignBaseline
         || firstLineParentStyle.lineHeight() != childStyle.lineHeight();
     }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
index 94d94ec..de63ab1 100644
--- a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
@@ -395,7 +395,7 @@
 
 bool LayoutListMarker::isInside() const
 {
-    return m_listItem->notInList() || style()->listStylePosition() == INSIDE;
+    return m_listItem->notInList() || style()->listStylePosition() == ListStylePositionInside;
 }
 
 IntRect LayoutListMarker::getRelativeMarkerRect() const
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index e551da7..c25bb9d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -489,7 +489,7 @@
         // FIXME: Collapse caption margin.
         if (!m_captions.isEmpty()) {
             for (unsigned i = 0; i < m_captions.size(); i++) {
-                if (m_captions[i]->style()->captionSide() == CAPBOTTOM)
+                if (m_captions[i]->style()->captionSide() == CaptionSideBottom)
                     continue;
                 layoutCaption(*m_captions[i]);
             }
@@ -556,7 +556,7 @@
         setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
 
         for (unsigned i = 0; i < m_captions.size(); i++) {
-            if (m_captions[i]->style()->captionSide() != CAPBOTTOM)
+            if (m_captions[i]->style()->captionSide() != CaptionSideBottom)
                 continue;
             layoutCaption(*m_captions[i]);
         }
@@ -656,7 +656,7 @@
 {
     for (unsigned i = 0; i < m_captions.size(); i++) {
         LayoutUnit captionLogicalHeight = m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
-        bool captionIsBefore = (m_captions[i]->style()->captionSide() != CAPBOTTOM) ^ style()->isFlippedBlocksWritingMode();
+        bool captionIsBefore = (m_captions[i]->style()->captionSide() != CaptionSideBottom) ^ style()->isFlippedBlocksWritingMode();
         if (style()->isHorizontalWritingMode()) {
             rect.setHeight(rect.height() - captionLogicalHeight);
             if (captionIsBefore)
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
index c985282e..c073fc0 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -177,26 +177,26 @@
 
     int intrinsicPaddingBefore = 0;
     switch (style()->verticalAlign()) {
-    case SUB:
-    case SUPER:
-    case TEXT_TOP:
-    case TEXT_BOTTOM:
-    case LENGTH:
-    case BASELINE: {
+    case VerticalAlignSub:
+    case VerticalAlignSuper:
+    case VerticalAlignTextTop:
+    case VerticalAlignTextBottom:
+    case VerticalAlignLength:
+    case VerticalAlignBaseline: {
         int baseline = cellBaselinePosition();
         if (baseline > borderBefore() + paddingBefore())
             intrinsicPaddingBefore = section()->rowBaseline(rowIndex()) - (baseline - oldIntrinsicPaddingBefore);
         break;
     }
-    case TOP:
+    case VerticalAlignTop:
         break;
-    case MIDDLE:
+    case VerticalAlignMiddle:
         intrinsicPaddingBefore = (rowHeight - logicalHeightWithoutIntrinsicPadding) / 2;
         break;
-    case BOTTOM:
+    case VerticalAlignBottom:
         intrinsicPaddingBefore = rowHeight - logicalHeightWithoutIntrinsicPadding;
         break;
-    case BASELINE_MIDDLE:
+    case VerticalAlignBaselineMiddle:
         break;
     }
 
@@ -986,7 +986,7 @@
         return;
 
     // Shrink our intrinsic padding as much as possible to accommodate the scrollbar.
-    if (style()->verticalAlign() == MIDDLE) {
+    if (style()->verticalAlign() == VerticalAlignMiddle) {
         LayoutUnit totalHeight = logicalHeight();
         LayoutUnit heightWithoutIntrinsicPadding = totalHeight - intrinsicPaddingBefore() - intrinsicPaddingAfter();
         totalHeight -= scrollbarHeight;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.h b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
index c47d0f80..881f3eb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
@@ -185,7 +185,7 @@
     bool isBaselineAligned() const
     {
         EVerticalAlign va = style()->verticalAlign();
-        return va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB || va == LENGTH;
+        return va == VerticalAlignBaseline || va == VerticalAlignTextBottom || va == VerticalAlignTextTop || va == VerticalAlignSuper || va == VerticalAlignSub || va == VerticalAlignLength;
     }
 
     void computeIntrinsicPadding(int rowHeight, SubtreeLayoutScope&);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
index e4e3bcf8..9fb9c4e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
@@ -123,8 +123,8 @@
         logicalHeight = computeControlLogicalHeight(innerEditorBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight);
 
         // We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
-        if ((isHorizontalWritingMode() && (style()->overflowX() == OSCROLL ||  (style()->overflowX() == OAUTO && innerEditor->layoutObject()->style()->overflowWrap() == NormalOverflowWrap)))
-            || (!isHorizontalWritingMode() && (style()->overflowY() == OSCROLL ||  (style()->overflowY() == OAUTO && innerEditor->layoutObject()->style()->overflowWrap() == NormalOverflowWrap))))
+        if ((isHorizontalWritingMode() && (style()->overflowX() == OverflowScroll ||  (style()->overflowX() == OverflowAuto && innerEditor->layoutObject()->style()->overflowWrap() == NormalOverflowWrap)))
+            || (!isHorizontalWritingMode() && (style()->overflowY() == OverflowScroll ||  (style()->overflowY() == OverflowAuto && innerEditor->layoutObject()->style()->overflowWrap() == NormalOverflowWrap))))
             logicalHeight += scrollbarThickness();
 
         // FIXME: The logical height of the inner text box should have been added before calling computeLogicalHeight to
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
index c952ca7a..688951d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
@@ -283,8 +283,8 @@
     if (inputElement()->shouldRevealPassword())
         textBlockStyle->setTextSecurity(TSNONE);
 
-    textBlockStyle->setOverflowX(OSCROLL);
-    textBlockStyle->setOverflowY(OSCROLL);
+    textBlockStyle->setOverflowX(OverflowScroll);
+    textBlockStyle->setOverflowY(OverflowScroll);
     RefPtr<ComputedStyle> noScrollbarStyle = ComputedStyle::create();
     noScrollbarStyle->setStyleType(SCROLLBAR);
     noScrollbarStyle->setDisplay(NONE);
diff --git a/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp b/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp
index c4cf7c77..6008d5b 100644
--- a/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp
+++ b/third_party/WebKit/Source/core/layout/MapCoordinatesTest.cpp
@@ -978,6 +978,42 @@
     EXPECT_EQ(FloatPoint(), mappedPoint);
 }
 
+TEST_F(MapCoordinatesTest, SVGShapeWithViewBoxWithNonZeroOffset)
+{
+    setBodyInnerHTML(
+        "<svg id='container' viewBox='100 100 200 200' width='400' height='200'>"
+        "    <g transform='translate(100 50)'>"
+        "        <rect id='target' transform='translate(100 100)' width='100' height='100'/>"
+        "    </g>"
+        "</svg>");
+
+    LayoutObject* target = getLayoutObjectByElementId("target");
+    LayoutBox* container = toLayoutBox(getLayoutObjectByElementId("container"));
+
+    FloatPoint mappedPoint = mapLocalToAncestor(target, container, FloatPoint());
+    EXPECT_EQ(FloatPoint(200, 50), mappedPoint);
+    mappedPoint = mapAncestorToLocal(target, container, mappedPoint);
+    EXPECT_EQ(FloatPoint(), mappedPoint);
+}
+
+TEST_F(MapCoordinatesTest, SVGShapeWithViewBoxWithNonZeroOffsetAndScale)
+{
+    setBodyInnerHTML(
+        "<svg id='container' viewBox='100 100 100 100' width='400' height='200'>"
+        "    <g transform='translate(50 50)'>"
+        "        <rect id='target' transform='translate(100 100)' width='100' height='100'/>"
+        "    </g>"
+        "</svg>");
+
+    LayoutObject* target = getLayoutObjectByElementId("target");
+    LayoutBox* container = toLayoutBox(getLayoutObjectByElementId("container"));
+
+    FloatPoint mappedPoint = mapLocalToAncestor(target, container, FloatPoint());
+    EXPECT_EQ(FloatPoint(200, 100), mappedPoint);
+    mappedPoint = mapAncestorToLocal(target, container, mappedPoint);
+    EXPECT_EQ(FloatPoint(), mappedPoint);
+}
+
 TEST_F(MapCoordinatesTest, SVGForeignObject)
 {
     setBodyInnerHTML(
diff --git a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
index 02aa2ec..cf41bf8a 100644
--- a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
+++ b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
@@ -225,7 +225,7 @@
     // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
     for (; block; block = block->containingBlock()) {
         const ComputedStyle& style = block->styleRef();
-        if (style.overflowY() >= OSCROLL)
+        if (style.overflowY() >= OverflowScroll)
             return false;
         if (style.height().isSpecified() || style.maxHeight().isSpecified() || block->isOutOfFlowPositioned()) {
             // Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
diff --git a/third_party/WebKit/Source/core/layout/api/LayoutItem.h b/third_party/WebKit/Source/core/layout/api/LayoutItem.h
index a7f6f9b3..645ed86 100644
--- a/third_party/WebKit/Source/core/layout/api/LayoutItem.h
+++ b/third_party/WebKit/Source/core/layout/api/LayoutItem.h
@@ -94,6 +94,16 @@
         return m_layoutObject->isListItem();
     }
 
+    bool isMedia() const
+    {
+        return m_layoutObject->isMedia();
+    }
+
+    bool isMenuList() const
+    {
+        return m_layoutObject->isMenuList();
+    }
+
     bool needsLayout()
     {
         return m_layoutObject->needsLayout();
diff --git a/third_party/WebKit/Source/core/layout/api/LayoutMediaItem.h b/third_party/WebKit/Source/core/layout/api/LayoutMediaItem.h
new file mode 100644
index 0000000..dfdc1903
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/api/LayoutMediaItem.h
@@ -0,0 +1,49 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LayoutMediaItem_h
+#define LayoutMediaItem_h
+
+#include "core/layout/LayoutMedia.h"
+#include "core/layout/api/LayoutImageItem.h"
+
+namespace blink {
+
+class LayoutMediaItem : public LayoutImageItem {
+public:
+    explicit LayoutMediaItem(LayoutMedia* layoutMedia)
+        : LayoutImageItem(layoutMedia)
+    {
+    }
+
+    explicit LayoutMediaItem(const LayoutItem& item)
+        : LayoutImageItem(item)
+    {
+        ASSERT(!item || item.isMedia());
+    }
+
+    explicit LayoutMediaItem(std::nullptr_t) : LayoutImageItem(nullptr) { }
+
+    LayoutMediaItem() { }
+
+    void setRequestPositionUpdates(bool want)
+    {
+        return toMedia()->setRequestPositionUpdates(want);
+    }
+
+private:
+    LayoutMedia* toMedia()
+    {
+        return toLayoutMedia(layoutObject());
+    }
+
+    const LayoutMedia* toMedia() const
+    {
+        return toLayoutMedia(layoutObject());
+    }
+};
+
+} // namespace blink
+
+#endif // LayoutMediaItem_h
diff --git a/third_party/WebKit/Source/core/layout/api/LayoutMenuListItem.h b/third_party/WebKit/Source/core/layout/api/LayoutMenuListItem.h
new file mode 100644
index 0000000..ffc6ee11
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/api/LayoutMenuListItem.h
@@ -0,0 +1,43 @@
+
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LayoutMenuListItem_h
+#define LayoutMenuListItem_h
+
+#include "core/layout/LayoutMenuList.h"
+#include "core/layout/api/LayoutBlockItem.h"
+
+namespace blink {
+
+class LayoutMenuListItem : public LayoutBlockItem {
+public:
+    explicit LayoutMenuListItem(LayoutBlock* layoutBlock)
+        : LayoutBlockItem(layoutBlock)
+    {
+    }
+
+    explicit LayoutMenuListItem(const LayoutBlockItem& item)
+        : LayoutBlockItem(item)
+    {
+        ASSERT(!item || item.isMenuList());
+    }
+
+    explicit LayoutMenuListItem(std::nullptr_t) : LayoutBlockItem(nullptr) { }
+
+    LayoutMenuListItem() { }
+
+    String text() const
+    {
+        return toMenuList()->text();
+    }
+
+private:
+    LayoutMenuList* toMenuList() { return toLayoutMenuList(layoutObject()); }
+    const LayoutMenuList* toMenuList() const { return toLayoutMenuList(layoutObject()); }
+};
+
+} // namespace blink
+
+#endif // LayoutMenuListItem_h
diff --git a/third_party/WebKit/Source/core/layout/api/LineLayoutBox.h b/third_party/WebKit/Source/core/layout/api/LineLayoutBox.h
index d508eb8..cf14b406 100644
--- a/third_party/WebKit/Source/core/layout/api/LineLayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/api/LineLayoutBox.h
@@ -114,6 +114,11 @@
         return toBox()->createInlineBox();
     }
 
+    InlineBox* inlineBoxWrapper() const
+    {
+        return toBox()->inlineBoxWrapper();
+    }
+
 private:
     LayoutBox* toBox()
     {
diff --git a/third_party/WebKit/Source/core/layout/api/LineLayoutInline.h b/third_party/WebKit/Source/core/layout/api/LineLayoutInline.h
index 87f8b71..ef596cf 100644
--- a/third_party/WebKit/Source/core/layout/api/LineLayoutInline.h
+++ b/third_party/WebKit/Source/core/layout/api/LineLayoutInline.h
@@ -87,6 +87,11 @@
         return toInline()->firstLineBoxIncludingCulling();
     }
 
+    InlineBox* lastLineBoxIncludingCulling() const
+    {
+        return toInline()->lastLineBoxIncludingCulling();
+    }
+
     LineBoxList* lineBoxes()
     {
         return toInline()->lineBoxes();
diff --git a/third_party/WebKit/Source/core/layout/api/LineLayoutText.h b/third_party/WebKit/Source/core/layout/api/LineLayoutText.h
index 867f45ae..20ed6f5b 100644
--- a/third_party/WebKit/Source/core/layout/api/LineLayoutText.h
+++ b/third_party/WebKit/Source/core/layout/api/LineLayoutText.h
@@ -34,6 +34,11 @@
         return toText()->firstTextBox();
     }
 
+    InlineTextBox* lastTextBox() const
+    {
+        return toText()->lastTextBox();
+    }
+
     InlineTextBox* createInlineTextBox(int start, unsigned short length)
     {
         return toText()->createInlineTextBox(start, length);
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
index 3f37833..f5a1e42 100644
--- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
+++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -310,7 +310,7 @@
         // A <br> with clearance always needs a linebox in case the lines below it get dirtied later and
         // need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
         // run for this object.
-        if (m_ignoringSpaces && m_currentStyle->clear() != CNONE)
+        if (m_ignoringSpaces && m_currentStyle->clear() != ClearNone)
             ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, br);
 
         if (!m_lineInfo.isEmpty())
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index c6ad72e..f4412ee 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -125,7 +125,7 @@
             if (child->getLineLayoutItem().isBR() || (child->getLineLayoutItem().parent() != getLineLayoutItem())) {
                 if (!parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics())
                     || parentStyle.lineHeight() != childStyle.lineHeight()
-                    || (parentStyle.verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle.verticalAlign() != BASELINE)
+                    || (parentStyle.verticalAlign() != VerticalAlignBaseline && !isRootInlineBox()) || childStyle.verticalAlign() != VerticalAlignBaseline)
                     shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
             }
             if (childStyle.hasTextCombine() || childStyle.getTextEmphasisMark() != TextEmphasisMarkNone)
@@ -142,7 +142,7 @@
                 if (!childFlowBox->descendantsHaveSameLineHeightAndBaseline()
                     || !parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics())
                     || parentStyle.lineHeight() != childStyle.lineHeight()
-                    || (parentStyle.verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle.verticalAlign() != BASELINE
+                    || (parentStyle.verticalAlign() != VerticalAlignBaseline && !isRootInlineBox()) || childStyle.verticalAlign() != VerticalAlignBaseline
                     || childStyle.hasBorder() || childStyle.hasPadding() || childStyle.hasTextCombine())
                     shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
             }
@@ -470,9 +470,9 @@
         // positioned elements
         if (curr->getLineLayoutItem().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
-        if (curr->verticalAlign() == TOP || curr->verticalAlign() == BOTTOM) {
+        if (curr->verticalAlign() == VerticalAlignTop || curr->verticalAlign() == VerticalAlignBottom) {
             int lineHeight = curr->lineHeight();
-            if (curr->verticalAlign() == TOP) {
+            if (curr->verticalAlign() == VerticalAlignTop) {
                 if (maxAscent + maxDescent < lineHeight)
                     maxDescent = lineHeight - maxAscent;
             } else {
@@ -548,10 +548,10 @@
         rootBox->ascentAndDescentForBox(curr, textBoxDataMap, ascent, descent, affectsAscent, affectsDescent);
 
         LayoutUnit boxHeight(ascent + descent);
-        if (curr->verticalAlign() == TOP) {
+        if (curr->verticalAlign() == VerticalAlignTop) {
             if (maxPositionTop < boxHeight)
                 maxPositionTop = boxHeight;
-        } else if (curr->verticalAlign() == BOTTOM) {
+        } else if (curr->verticalAlign() == VerticalAlignBottom) {
             if (maxPositionBottom < boxHeight)
                 maxPositionBottom = boxHeight;
         } else if (!inlineFlowBox || noQuirksMode || inlineFlowBox->hasTextChildren() || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowBox->hasTextDescendants()) || inlineFlowBox->boxModelObject().hasInlineDirectionBordersOrPadding()) {
@@ -607,9 +607,9 @@
 
         InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox(curr) : nullptr;
         bool childAffectsTopBottomPos = true;
-        if (curr->verticalAlign() == TOP) {
+        if (curr->verticalAlign() == VerticalAlignTop) {
             curr->setLogicalTop(top);
-        } else if (curr->verticalAlign() == BOTTOM) {
+        } else if (curr->verticalAlign() == VerticalAlignBottom) {
             curr->setLogicalTop((top + maxHeight - curr->lineHeight()));
         } else {
             if (!noQuirksMode && inlineFlowBox && !inlineFlowBox->hasTextChildren() && !curr->boxModelObject().hasInlineDirectionBordersOrPadding()
diff --git a/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp b/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp
index a33c0f5..c798d810 100644
--- a/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp
+++ b/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp
@@ -256,15 +256,15 @@
             continue;
 
         if (curr.isAtomicInlineLevel()) {
-            InlineBox* wrapper = toLayoutBox(curr)->inlineBoxWrapper();
+            InlineBox* wrapper = LineLayoutBox(curr).inlineBoxWrapper();
             if (wrapper)
                 box = &wrapper->root();
         } else if (curr.isText()) {
-            InlineTextBox* textBox = toLayoutText(curr)->lastTextBox();
+            InlineTextBox* textBox = LineLayoutText(curr).lastTextBox();
             if (textBox)
                 box = &textBox->root();
         } else if (curr.isLayoutInline()) {
-            InlineBox* lastSiblingBox = toLayoutInline(curr)->lastLineBoxIncludingCulling();
+            InlineBox* lastSiblingBox = LineLayoutInline(curr).lastLineBoxIncludingCulling();
             if (lastSiblingBox)
                 box = &lastSiblingBox->root();
         }
diff --git a/third_party/WebKit/Source/core/layout/line/LineBreaker.cpp b/third_party/WebKit/Source/core/layout/line/LineBreaker.cpp
index 4f28f9b2..4d12237 100644
--- a/third_party/WebKit/Source/core/layout/line/LineBreaker.cpp
+++ b/third_party/WebKit/Source/core/layout/line/LineBreaker.cpp
@@ -49,7 +49,7 @@
 {
     m_positionedObjects.clear();
     m_hyphenated = false;
-    m_clear = CNONE;
+    m_clear = ClearNone;
 }
 
 InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo,
diff --git a/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp b/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
index c054281..dfac26e 100644
--- a/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
@@ -482,7 +482,7 @@
     // This has security implications because if the LayoutObject does not
     // point to at least one line box, then that LayoutInline can be deleted
     // later without resetting the lineBreakObj, leading to use-after-free.
-    ASSERT_WITH_SECURITY_IMPLICATION(!obj || obj.isText() || !(obj.isLayoutInline() && obj.isBox() && !toLayoutBox(obj)->inlineBoxWrapper()));
+    ASSERT_WITH_SECURITY_IMPLICATION(!obj || obj.isText() || !(obj.isLayoutInline() && obj.isBox() && !LineLayoutBox(obj).inlineBoxWrapper()));
 
     m_lineBreakObj = obj;
     m_lineBreakPos = breakPos;
@@ -630,45 +630,45 @@
 
     LayoutUnit verticalPosition;
     EVerticalAlign verticalAlign = boxModel.style()->verticalAlign();
-    if (verticalAlign == TOP || verticalAlign == BOTTOM)
+    if (verticalAlign == VerticalAlignTop || verticalAlign == VerticalAlignBottom)
         return LayoutUnit();
 
     LineLayoutItem parent = boxModel.parent();
-    if (parent.isLayoutInline() && parent.style()->verticalAlign() != TOP && parent.style()->verticalAlign() != BOTTOM)
+    if (parent.isLayoutInline() && parent.style()->verticalAlign() != VerticalAlignTop && parent.style()->verticalAlign() != VerticalAlignBottom)
         verticalPosition = box->parent()->logicalTop();
 
-    if (verticalAlign != BASELINE) {
+    if (verticalAlign != VerticalAlignBaseline) {
         const Font& font = parent.style(firstLine)->font();
         const FontMetrics& fontMetrics = font.fontMetrics();
         int fontSize = font.fontDescription().computedPixelSize();
 
         LineDirectionMode lineDirection = parent.isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
 
-        if (verticalAlign == SUB) {
+        if (verticalAlign == VerticalAlignSub) {
             verticalPosition += fontSize / 5 + 1;
-        } else if (verticalAlign == SUPER) {
+        } else if (verticalAlign == VerticalAlignSuper) {
             verticalPosition -= fontSize / 3 + 1;
-        } else if (verticalAlign == TEXT_TOP) {
+        } else if (verticalAlign == VerticalAlignTextTop) {
             verticalPosition += boxModel.baselinePosition(baselineType(), firstLine, lineDirection) - fontMetrics.ascent(baselineType());
-        } else if (verticalAlign == MIDDLE) {
+        } else if (verticalAlign == VerticalAlignMiddle) {
             verticalPosition = LayoutUnit((verticalPosition - LayoutUnit(fontMetrics.xHeight() / 2)
                 - boxModel.lineHeight(firstLine, lineDirection) / 2
                 + boxModel.baselinePosition(baselineType(), firstLine, lineDirection)).round());
-        } else if (verticalAlign == TEXT_BOTTOM) {
+        } else if (verticalAlign == VerticalAlignTextBottom) {
             verticalPosition += fontMetrics.descent(baselineType());
             // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
             if (!boxModel.isAtomicInlineLevel() || boxModel.isInlineBlockOrInlineTable())
                 verticalPosition -= (boxModel.lineHeight(firstLine, lineDirection) - boxModel.baselinePosition(baselineType(), firstLine, lineDirection));
-        } else if (verticalAlign == BASELINE_MIDDLE) {
+        } else if (verticalAlign == VerticalAlignBaselineMiddle) {
             verticalPosition += -boxModel.lineHeight(firstLine, lineDirection) / 2 + boxModel.baselinePosition(baselineType(), firstLine, lineDirection);
-        } else if (verticalAlign == LENGTH) {
+        } else if (verticalAlign == VerticalAlignLength) {
             LayoutUnit lineHeight;
             // Per http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align: 'Percentages: refer to the 'line-height' of the element itself'.
-            if (boxModel.style()->verticalAlignLength().hasPercent())
+            if (boxModel.style()->getVerticalAlignLength().hasPercent())
                 lineHeight = LayoutUnit(boxModel.style()->computedLineHeight());
             else
                 lineHeight = boxModel.lineHeight(firstLine, lineDirection);
-            verticalPosition -= valueForLength(boxModel.style()->verticalAlignLength(), lineHeight);
+            verticalPosition -= valueForLength(boxModel.style()->getVerticalAlignLength(), lineHeight);
         }
     }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp
index 27bd7ce..8d62fde 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp
@@ -68,7 +68,7 @@
 {
     if (diff.needsFullLayout()) {
         setNeedsBoundariesUpdate();
-        if (style()->hasTransform())
+        if (diff.transformChanged())
             setNeedsTransformUpdate();
     }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
index 1a6ea6ab..6867fe7 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
@@ -88,8 +88,10 @@
         return;
 
     // The text metrics may be influenced by style changes.
-    if (LayoutSVGText* textLayoutObject = LayoutSVGText::locateLayoutSVGTextAncestor(this))
+    if (LayoutSVGText* textLayoutObject = LayoutSVGText::locateLayoutSVGTextAncestor(this)) {
+        textLayoutObject->setNeedsTextMetricsUpdate();
         textLayoutObject->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::StyleChange);
+    }
 }
 
 InlineTextBox* LayoutSVGInlineText::createTextBox(int start, unsigned short length)
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
index 6d5eef1..243a47a 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
@@ -103,7 +103,7 @@
 {
     if (diff.needsFullLayout()) {
         setNeedsBoundariesUpdate();
-        if (style()->hasTransform())
+        if (diff.transformChanged())
             setNeedsTransformUpdate();
     }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
index 1ce2aa4..675c646 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
@@ -179,9 +179,9 @@
     // the outermost svg is clipped if auto, and svg document roots are always clipped
     // When the svg is stand-alone (isDocumentElement() == true) the viewport clipping should always
     // be applied, noting that the window scrollbars should be hidden if overflow=hidden.
-    return style()->overflowX() == OHIDDEN
-        || style()->overflowX() == OAUTO
-        || style()->overflowX() == OSCROLL
+    return style()->overflowX() == OverflowHidden
+        || style()->overflowX() == OverflowAuto
+        || style()->overflowX() == OverflowScroll
         || this->isDocumentElement();
 }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
index 6458eb56..1a0da09 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
@@ -263,22 +263,6 @@
         m_layoutAttributesBuilder.buildLayoutAttributesForText(affectedAttributes[i]->context());
 }
 
-void LayoutSVGText::subtreeStyleDidChange()
-{
-    if (!shouldHandleSubtreeMutations() || documentBeingDestroyed())
-        return;
-
-    checkLayoutAttributesConsistency(this, m_layoutAttributes);
-
-    // Only update the metrics cache, but not the text positioning element cache
-    // nor the layout attributes cached in the leaf #text layoutObjects.
-    FontCachePurgePreventer fontCachePurgePreventer;
-    for (LayoutObject* descendant = firstChild(); descendant; descendant = descendant->nextInPreOrder(this)) {
-        if (descendant->isSVGInlineText())
-            m_layoutAttributesBuilder.rebuildMetricsForTextLayoutObject(toLayoutSVGInlineText(descendant));
-    }
-}
-
 void LayoutSVGText::subtreeTextDidChange(LayoutSVGInlineText* text)
 {
     ASSERT(text);
@@ -319,8 +303,6 @@
     ASSERT(needsLayout());
     LayoutAnalyzer::Scope analyzer(*this);
 
-    subtreeStyleDidChange();
-
     bool updateCachedBoundariesInParents = false;
     if (m_needsTransformUpdate) {
         m_localTransform = toSVGTextElement(node())->calculateAnimatedLocalTransform();
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.h
index c17f12c..f302c41 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.h
@@ -55,7 +55,6 @@
     void subtreeChildWasAdded(LayoutObject*);
     void subtreeChildWillBeRemoved(LayoutObject*, Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes);
     void subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes);
-    void subtreeStyleDidChange();
     void subtreeTextDidChange(LayoutSVGInlineText*);
 
     const AffineTransform& localToParentTransform() const override { return m_localTransform; }
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
index c7b37f5..b52591b 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
@@ -354,7 +354,7 @@
     // LayoutSVGRoot should never query for overflow state - it should always clip itself to the initial viewport size.
     ASSERT(!object->isDocumentElement());
 
-    return object->style()->overflowX() == OHIDDEN || object->style()->overflowX() == OSCROLL;
+    return object->style()->overflowX() == OverflowHidden || object->style()->overflowX() == OverflowScroll;
 }
 
 void SVGLayoutSupport::intersectPaintInvalidationRectWithResources(const LayoutObject* layoutObject, FloatRect& paintInvalidationRect)
diff --git a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.cpp b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.cpp
new file mode 100644
index 0000000..f43bceb
--- /dev/null
+++ b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.cpp
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/origin_trials/DocumentOriginTrialContext.h"
+
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLHeadElement.h"
+#include "core/html/HTMLMetaElement.h"
+
+namespace blink {
+
+class Document;
+
+DocumentOriginTrialContext::DocumentOriginTrialContext(Document* document)
+    : m_parent(document)
+{
+}
+
+Vector<String> DocumentOriginTrialContext::getTokens()
+{
+    // When in a document, the tokens are provided in a meta tag
+    Vector<String> tokens;
+    HTMLHeadElement* head = m_parent->head();
+    if (head) {
+        for (HTMLMetaElement& metaElement : Traversal<HTMLMetaElement>::childrenOf(*head)) {
+            if (equalIgnoringCase(metaElement.httpEquiv(), kTrialHeaderName)) {
+                tokens.append(metaElement.content());
+            }
+        }
+    }
+    return tokens;
+}
+
+DEFINE_TRACE(DocumentOriginTrialContext)
+{
+    visitor->trace(m_parent);
+    OriginTrialContext::trace(visitor);
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.h b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.h
new file mode 100644
index 0000000..01231c9
--- /dev/null
+++ b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.h
@@ -0,0 +1,41 @@
+// 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 DocumentOriginTrialContext_h
+#define DocumentOriginTrialContext_h
+
+#include "core/CoreExport.h"
+#include "core/dom/Document.h"
+#include "core/origin_trials/OriginTrialContext.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include <utility>
+
+namespace blink {
+
+class WebApiKeyValidator;
+
+// DocumentOriginTrialContext is a specialization of OriginTrialContext for
+// the Document execution context. It enables and disables feature trials based
+// on the tokens found in <meta> tags in the document header.
+class CORE_EXPORT DocumentOriginTrialContext : public OriginTrialContext {
+public:
+    explicit DocumentOriginTrialContext(Document*);
+    ~DocumentOriginTrialContext() override = default;
+
+    ExecutionContext* executionContext() override { return m_parent; }
+    Vector<String> getTokens() override;
+
+    DECLARE_VIRTUAL_TRACE();
+
+protected:
+    friend class DocumentOriginTrialContextTest;
+
+private:
+    RawPtrWillBeMember<Document> m_parent;
+};
+
+} // namespace blink
+
+#endif // DocumentOriginTrialContext_h
diff --git a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContextTest.cpp b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContextTest.cpp
new file mode 100644
index 0000000..1c6b231d
--- /dev/null
+++ b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContextTest.cpp
@@ -0,0 +1,117 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/origin_trials/DocumentOriginTrialContext.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/DOMException.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/frame/FrameView.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLHeadElement.h"
+#include "core/html/HTMLMetaElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/WebTrialTokenValidator.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+using ::testing::UnorderedElementsAre;
+
+namespace {
+
+// API Key which will appear valid
+const char* kGoodTrialToken = "1|AnySignatureWillDo|https://www.example.com|Frobulate|2000000000";
+const char* kAnotherTrialToken = "1|AnySignatureWillDo|https://www.example.com|FrobulateV2|2000000000";
+
+} // namespace
+
+class DocumentOriginTrialContextTest : public ::testing::Test {
+protected:
+    DocumentOriginTrialContextTest()
+        : m_pageHolder(DummyPageHolder::create())
+        , m_frameworkWasEnabled(RuntimeEnabledFeatures::experimentalFrameworkEnabled())
+    {
+        RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(true);
+    }
+
+    ~DocumentOriginTrialContextTest()
+    {
+        RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(m_frameworkWasEnabled);
+        m_pageHolder.clear();
+    }
+
+    void SetUp() override
+    {
+        setInnerHTML(
+            "<html>"
+            "<head>"
+            "</head>"
+            "<body>"
+            "</body>"
+            "</html>");
+    }
+
+    Document& document() { return m_pageHolder->document(); }
+
+    void setPageOrigin(const String& origin)
+    {
+        KURL pageURL(ParsedURLString, origin);
+        RefPtr<SecurityOrigin> pageOrigin = SecurityOrigin::create(pageURL);
+        document().updateSecurityOrigin(pageOrigin);
+    }
+
+    void setInnerHTML(const char* htmlContent)
+    {
+        document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent), ASSERT_NO_EXCEPTION);
+        document().view()->updateAllLifecyclePhases();
+    }
+
+    void addTrialToken(const AtomicString& token)
+    {
+        HTMLElement* head = document().head();
+        ASSERT_TRUE(head);
+
+        RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(document());
+        meta->setAttribute(HTMLNames::http_equivAttr, OriginTrialContext::kTrialHeaderName);
+        meta->setAttribute(HTMLNames::contentAttr, token);
+        head->appendChild(meta.release());
+    }
+
+    Vector<String> getTokens()
+    {
+        return document().createOriginTrialContext()->getTokens();
+    }
+
+private:
+    OwnPtr<DummyPageHolder> m_pageHolder;
+    const bool m_frameworkWasEnabled;
+};
+
+TEST_F(DocumentOriginTrialContextTest, DetectsZeroTokens)
+{
+    String errorMessage;
+    Vector<String> tokens = getTokens();
+    EXPECT_EQ(0UL, tokens.size());
+}
+
+TEST_F(DocumentOriginTrialContextTest, ExtractsSingleToken)
+{
+    addTrialToken(kGoodTrialToken);
+    Vector<String> tokens = getTokens();
+    EXPECT_EQ(1UL, tokens.size());
+    EXPECT_EQ(kGoodTrialToken, tokens[0]);
+}
+
+TEST_F(DocumentOriginTrialContextTest, ExtractsAllTokens)
+{
+    addTrialToken(kGoodTrialToken);
+    addTrialToken(kAnotherTrialToken);
+    EXPECT_THAT(getTokens(), UnorderedElementsAre(kGoodTrialToken, kAnotherTrialToken));
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
index 636d43a..6d9cc0f2 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
@@ -17,8 +17,6 @@
 
 namespace {
 
-const char kTrialHeaderName[] = "origin-trial";
-
 String getCurrentOrigin(ExecutionContext* executionContext)
 {
     return executionContext->securityOrigin()->toString();
@@ -30,40 +28,18 @@
     return "The '" + featureName + "' feature is currently enabled in limited trials. Please see [Phosphor console URL] for information on enabling a trial for your site.";
 }
 
-bool hasValidToken(ExecutionContext* executionContext, const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
+String getInvalidTokenMessage(const String& featureName)
 {
-    bool foundAnyToken = false;
-    String origin = getCurrentOrigin(executionContext);
-
-    // When in a document, the token is provided in a meta tag
-    if (executionContext->isDocument()) {
-        HTMLHeadElement* head = toDocument(executionContext)->head();
-        for (HTMLMetaElement* metaElement = head ? Traversal<HTMLMetaElement>::firstChild(*head) : 0; metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
-            if (equalIgnoringCase(metaElement->httpEquiv(), kTrialHeaderName)) {
-                foundAnyToken = true;
-                String tokenString = metaElement->content();
-                // Check with the validator service to verify the signature.
-                if (validator->validateToken(tokenString, origin, featureName)) {
-                    return true;
-                }
-            }
-        }
-    }
-
-    if (errorMessage) {
-        if (foundAnyToken) {
-            *errorMessage = "The provided token(s) are not valid for the '" + featureName + "' feature.";
-        } else {
-            *errorMessage = getDisabledMessage(featureName);
-        }
-    }
-    return false;
+    return "The provided token(s) are not valid for the '" + featureName + "' feature.";
 }
 
 } // namespace
 
-// static
-bool OriginTrialContext::isFeatureEnabled(ExecutionContext* executionContext, const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
+const char OriginTrialContext::kTrialHeaderName[] = "origin-trial";
+
+OriginTrialContext::OriginTrialContext() {}
+
+bool OriginTrialContext::isFeatureEnabled(const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
 {
     if (!RuntimeEnabledFeatures::experimentalFrameworkEnabled()) {
         // TODO(iclelland): Set an error message here, the first time the
@@ -71,16 +47,16 @@
         return false;
     }
 
-    if (!executionContext) {
-        ASSERT_NOT_REACHED();
-        return false;
-    }
-
     // Feature trials are only enabled for secure origins
     bool isSecure = errorMessage
-        ? executionContext->isSecureContext(*errorMessage)
-        : executionContext->isSecureContext();
+        ? executionContext()->isSecureContext(*errorMessage)
+        : executionContext()->isSecureContext();
     if (!isSecure) {
+        // The execution context should always set a message here, if a valid
+        // pointer was passed in. If it does not, then we should find out why
+        // not, and decide whether the OriginTrialContext should be using its
+        // own error messages for this case.
+        DCHECK(!errorMessage || !errorMessage->isEmpty());
         return false;
     }
 
@@ -93,7 +69,42 @@
         }
     }
 
-    return hasValidToken(executionContext, featureName, errorMessage, validator);
+    return hasValidToken(getTokens(), featureName, errorMessage, validator);
+}
+
+bool OriginTrialContext::hasValidToken(Vector<String> tokens, const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
+{
+    String origin = getCurrentOrigin(executionContext());
+
+    for (const String& token : tokens) {
+        // Check with the validator service to verify the signature.
+        if (validator->validateToken(token, origin, featureName)) {
+            return true;
+        }
+    }
+
+    if (!errorMessage)
+        return false;
+
+    // If an error message has already been generated in this context, for this
+    // feature, do not generate another one. (This avoids cluttering the console
+    // with error messages on every attempt to access the feature.)
+    if (m_errorMessageGeneratedForFeature.contains(featureName)) {
+        *errorMessage = "";
+        return false;
+    }
+
+    if (tokens.size()) {
+        *errorMessage = getInvalidTokenMessage(featureName);
+    } else {
+        *errorMessage = getDisabledMessage(featureName);
+    }
+    m_errorMessageGeneratedForFeature.add(featureName);
+    return false;
+}
+
+DEFINE_TRACE(OriginTrialContext)
+{
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
index 579307d..044a7d88 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
@@ -6,12 +6,15 @@
 #define OriginTrialContext_h
 
 #include "core/CoreExport.h"
-#include "core/dom/DOMException.h"
-#include "core/dom/ExecutionContext.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/HashSet.h"
+#include "wtf/Vector.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
 
+class ExecutionContext;
 class WebTrialTokenValidator;
 
 // The Experimental Framework (EF) provides limited access to experimental
@@ -27,24 +30,39 @@
 // feature names. Instead, the EF validates the name provided by the feature
 // implementation against any provided tokens.
 //
-// This class is not intended to be instantiated. Any required state is kept
-// with a WebApiKeyValidator object held in the Platform object.
-// The static methods in this class may be called either from the main thread
-// or from a worker thread.
+// This class is abstract, and should be subclassed for each execution context
+// which supports origin trials.
 //
 // TODO(chasej): Link to documentation, or provide more detail on keys, .etc
-class CORE_EXPORT OriginTrialContext {
+class CORE_EXPORT OriginTrialContext : public NoBaseWillBeGarbageCollectedFinalized<OriginTrialContext> {
+public:
+    static const char kTrialHeaderName[];
+    virtual ~OriginTrialContext() = default;
+
+    virtual ExecutionContext* executionContext() = 0;
+    virtual Vector<String> getTokens() = 0;
+
+    DECLARE_VIRTUAL_TRACE();
+
+protected:
+    OriginTrialContext();
+
 private:
     friend class OriginTrialContextTest;
     friend class OriginTrials;
 
-    OriginTrialContext();
-
     // Returns true if the feature should be considered enabled for the current
     // execution context. This method usually makes use of the token validator
     // object in the platform, but this may be overridden if a custom validator
     // is required (for testing, for instance).
-    static bool isFeatureEnabled(ExecutionContext*, const String& featureName, String* errorMessage, WebTrialTokenValidator* = nullptr);
+    bool isFeatureEnabled(const String& featureName, String* errorMessage, WebTrialTokenValidator* = nullptr);
+
+    bool hasValidToken(Vector<String> tokens, const String& featureName, String* errorMessage, WebTrialTokenValidator*);
+
+    // Records whether an error message has been generated, for each feature
+    // name. Since these messages are generally written to the console, this is
+    // used to avoid cluttering the console with messages on every access.
+    HashSet<String> m_errorMessageGeneratedForFeature;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
index 64643512..a033346 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
@@ -12,10 +12,12 @@
 #include "core/html/HTMLHeadElement.h"
 #include "core/html/HTMLMetaElement.h"
 #include "core/testing/DummyPageHolder.h"
+#include "core/testing/NullExecutionContext.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/WebTrialTokenValidator.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "wtf/Vector.h"
 
 namespace blink {
 namespace {
@@ -66,75 +68,76 @@
     DISALLOW_COPY_AND_ASSIGN(MockTokenValidator);
 };
 
+// Concrete subclass of OriginTrialContext which simply maintains a vector of
+// token strings to use for tests.
+class TestOriginTrialContext : public OriginTrialContext {
+public:
+    explicit TestOriginTrialContext()
+        : m_parent(adoptRefWillBeNoop(new NullExecutionContext()))
+    {
+    }
+
+    ~TestOriginTrialContext() override = default;
+
+    ExecutionContext* executionContext() override { return m_parent.get(); }
+
+    void addToken(const String& token)
+    {
+        m_tokens.append(token);
+    }
+
+    void updateSecurityOrigin(const String& origin)
+    {
+        KURL pageURL(ParsedURLString, origin);
+        RefPtr<SecurityOrigin> pageOrigin = SecurityOrigin::create(pageURL);
+        m_parent->setSecurityOrigin(pageOrigin);
+        m_parent->setIsSecureContext(SecurityOrigin::isSecure(pageURL));
+    }
+
+    Vector<String> getTokens() override
+    {
+        Vector<String> tokens;
+        for (String token : m_tokens) {
+            tokens.append(token);
+        }
+        return tokens;
+    }
+
+    DEFINE_INLINE_VIRTUAL_TRACE()
+    {
+        visitor->trace(m_parent);
+        OriginTrialContext::trace(visitor);
+    }
+
+private:
+    RefPtrWillBeMember<NullExecutionContext> m_parent;
+    Vector<String> m_tokens;
+};
+
 } // namespace
 
 class OriginTrialContextTest : public ::testing::Test {
 protected:
     OriginTrialContextTest()
-        : m_page(DummyPageHolder::create())
-        , m_frameworkWasEnabled(RuntimeEnabledFeatures::experimentalFrameworkEnabled())
+        : m_frameworkWasEnabled(RuntimeEnabledFeatures::experimentalFrameworkEnabled())
         , m_tokenValidator(adoptPtr(new MockTokenValidator()))
+        , m_originTrialContext(adoptPtrWillBeNoop(new TestOriginTrialContext))
     {
-        if (!RuntimeEnabledFeatures::experimentalFrameworkEnabled()) {
-            RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(true);
-        }
+        RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(true);
     }
 
     ~OriginTrialContextTest()
     {
-        if (!m_frameworkWasEnabled) {
-            RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(false);
-        }
-
-        m_page.clear();
+        RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(m_frameworkWasEnabled);
     }
 
-    void SetUp() override
-    {
-        m_document = toHTMLDocument(&m_page->document());
-        setInnerHTML(
-            "<html>"
-            "<head>"
-            "</head>"
-            "<body>"
-            "</body>"
-            "</html>");
-    }
-
-    ExecutionContext* executionContext() { return &(m_page->document()); }
     MockTokenValidator* tokenValidator() { return m_tokenValidator.get(); }
-    HTMLDocument& document() const { return *m_document; }
-
-    void setPageOrigin(const String& origin)
-    {
-        KURL pageURL(ParsedURLString, origin);
-        RefPtr<SecurityOrigin> pageOrigin = SecurityOrigin::create(pageURL);
-        m_page->document().updateSecurityOrigin(pageOrigin);
-    }
-
-    void setInnerHTML(const char* htmlContent)
-    {
-        document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent), ASSERT_NO_EXCEPTION);
-        document().view()->updateAllLifecyclePhases();
-    }
-
-    void addTrialToken(const String& token)
-    {
-        HTMLElement* head = document().head();
-        ASSERT_TRUE(head);
-
-        RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(document());
-        meta->setAttribute(HTMLNames::http_equivAttr, "origin-trial");
-        AtomicString value(token);
-        meta->setAttribute(HTMLNames::contentAttr, value);
-        head->appendChild(meta.release());
-    }
 
     bool isFeatureEnabled(const String& origin, const String& featureName, const String& token, String* errorMessage)
     {
-        setPageOrigin(origin);
-        addTrialToken(token);
-        return OriginTrialContext::isFeatureEnabled(executionContext(), featureName, errorMessage, tokenValidator());
+        m_originTrialContext->updateSecurityOrigin(origin);
+        m_originTrialContext->addToken(token);
+        return m_originTrialContext->isFeatureEnabled(featureName, errorMessage, tokenValidator());
     }
 
     bool isFeatureEnabledWithoutErrorMessage(const String& origin, const String& featureName, const char* token)
@@ -143,10 +146,9 @@
     }
 
 private:
-    OwnPtr<DummyPageHolder> m_page;
-    RefPtrWillBePersistent<HTMLDocument> m_document;
     const bool m_frameworkWasEnabled;
     OwnPtr<MockTokenValidator> m_tokenValidator;
+    OwnPtrWillBePersistent<TestOriginTrialContext> m_originTrialContext;
 };
 
 TEST_F(OriginTrialContextTest, EnabledNonExistingFeature)
@@ -198,6 +200,38 @@
     EXPECT_EQ(1, tokenValidator()->callCount());
 }
 
+TEST_F(OriginTrialContextTest, OnlyOneErrorMessageGenerated)
+{
+    String errorMessage1;
+    String errorMessage2;
+    tokenValidator()->setResponse(false);
+    isFeatureEnabled(kFrobulateEnabledOrigin, kFrobulateFeatureName, kGoodToken, &errorMessage1);
+    isFeatureEnabled(kFrobulateEnabledOrigin, kFrobulateFeatureName, kGoodToken, &errorMessage2);
+    EXPECT_FALSE(errorMessage1.isEmpty());
+    EXPECT_TRUE(errorMessage2.isEmpty());
+}
+
+TEST_F(OriginTrialContextTest, ErrorMessageClearedIfStringReused)
+{
+    String errorMessage;
+    tokenValidator()->setResponse(false);
+    isFeatureEnabled(kFrobulateEnabledOrigin, kFrobulateFeatureName, kGoodToken, &errorMessage);
+    EXPECT_FALSE(errorMessage.isEmpty());
+    isFeatureEnabled(kFrobulateEnabledOrigin, kFrobulateFeatureName, kGoodToken, &errorMessage);
+    EXPECT_TRUE(errorMessage.isEmpty());
+}
+
+TEST_F(OriginTrialContextTest, ErrorMessageGeneratedPerFeature)
+{
+    String errorMessage1;
+    String errorMessage2;
+    tokenValidator()->setResponse(false);
+    isFeatureEnabled(kFrobulateEnabledOrigin, kFrobulateFeatureName, kGoodToken, &errorMessage1);
+    isFeatureEnabled(kFrobulateEnabledOrigin, kNonExistingFeatureName, kGoodToken, &errorMessage2);
+    EXPECT_FALSE(errorMessage1.isEmpty());
+    EXPECT_FALSE(errorMessage2.isEmpty());
+}
+
 TEST_F(OriginTrialContextTest, EnabledSecureRegisteredOriginWithoutErrorMessage)
 {
     tokenValidator()->setResponse(true);
@@ -219,7 +253,17 @@
         kGoodToken,
         &errorMessage);
     EXPECT_FALSE(isOriginEnabled);
-    EXPECT_TRUE(errorMessage.contains("secure origin")) << "Message should indicate only secure origins are allowed, was: " << errorMessage;
+    EXPECT_EQ(0, tokenValidator()->callCount());
+    EXPECT_FALSE(errorMessage.isEmpty());
+}
+
+TEST_F(OriginTrialContextTest, EnabledNonSecureRegisteredOriginWithoutErrorMessage)
+{
+    bool isOriginEnabled = isFeatureEnabledWithoutErrorMessage(
+        kFrobulateEnabledOriginUnsecure,
+        kFrobulateFeatureName,
+        kGoodToken);
+    EXPECT_FALSE(isOriginEnabled);
     EXPECT_EQ(0, tokenValidator()->callCount());
 }
 
diff --git a/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp b/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp
index dfdfd65..143dbd0 100644
--- a/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp
+++ b/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp
@@ -80,13 +80,13 @@
         return m_callbackCount;
     }
 
-    void setNotificationCallback(PassOwnPtr<Closure> closure)
+    void setNotificationCallback(PassOwnPtr<SameThreadClosure> closure)
     {
         m_closure = closure;
     }
 
 private:
-    OwnPtr<Closure> m_closure;
+    OwnPtr<SameThreadClosure> m_closure;
     WebConnectionType m_observedType;
     double m_observedMaxBandwidthMbps;
     int m_callbackCount;
diff --git a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
index f5a7792..78be6ff 100644
--- a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
+++ b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -320,13 +320,13 @@
 
     switch (type) {
     case WebFocusTypeLeft:
-        return (container->layoutObject()->style()->overflowX() != OHIDDEN && container->layoutBox()->scrollLeft() > 0);
+        return (container->layoutObject()->style()->overflowX() != OverflowHidden && container->layoutBox()->scrollLeft() > 0);
     case WebFocusTypeUp:
-        return (container->layoutObject()->style()->overflowY() != OHIDDEN && container->layoutBox()->scrollTop() > 0);
+        return (container->layoutObject()->style()->overflowY() != OverflowHidden && container->layoutBox()->scrollTop() > 0);
     case WebFocusTypeRight:
-        return (container->layoutObject()->style()->overflowX() != OHIDDEN && container->layoutBox()->scrollLeft() + container->layoutBox()->clientWidth() < container->layoutBox()->scrollWidth());
+        return (container->layoutObject()->style()->overflowX() != OverflowHidden && container->layoutBox()->scrollLeft() + container->layoutBox()->clientWidth() < container->layoutBox()->scrollWidth());
     case WebFocusTypeDown:
-        return (container->layoutObject()->style()->overflowY() != OHIDDEN && container->layoutBox()->scrollTop() + container->layoutBox()->clientHeight() < container->layoutBox()->scrollHeight());
+        return (container->layoutObject()->style()->overflowY() != OverflowHidden && container->layoutBox()->scrollTop() + container->layoutBox()->clientHeight() < container->layoutBox()->scrollHeight());
     default:
         ASSERT_NOT_REACHED();
         return false;
@@ -584,8 +584,8 @@
     for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; parentNode = parentNode->parentNode()) {
         LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode);
         if (!candidateRect.intersects(parentRect)) {
-            if (((type == WebFocusTypeLeft || type == WebFocusTypeRight) && parentNode->layoutObject()->style()->overflowX() == OHIDDEN)
-                || ((type == WebFocusTypeUp || type == WebFocusTypeDown) && parentNode->layoutObject()->style()->overflowY() == OHIDDEN))
+            if (((type == WebFocusTypeLeft || type == WebFocusTypeRight) && parentNode->layoutObject()->style()->overflowX() == OverflowHidden)
+                || ((type == WebFocusTypeUp || type == WebFocusTypeDown) && parentNode->layoutObject()->style()->overflowY() == OverflowHidden))
                 return false;
         }
         if (parentNode == candidate.enclosingScrollableBox)
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index ef6eca3..cc2687a 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -540,7 +540,7 @@
 
     EOverflow overflowStyle = (orientation == HorizontalScrollbar) ?
         box().style()->overflowX() : box().style()->overflowY();
-    return (overflowStyle == OSCROLL || overflowStyle == OAUTO || overflowStyle == OOVERLAY);
+    return (overflowStyle == OverflowScroll || overflowStyle == OverflowAuto || overflowStyle == OverflowOverlay);
 }
 
 bool PaintLayerScrollableArea::shouldPlaceVerticalScrollbarOnLeft() const
@@ -645,26 +645,26 @@
         DisableCompositingQueryAsserts disabler;
 
         // overflow:scroll should just enable/disable.
-        if (box().style()->overflowX() == OSCROLL && horizontalScrollbar())
+        if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar())
             horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
-        if (box().style()->overflowY() == OSCROLL && verticalScrollbar())
+        if (box().style()->overflowY() == OverflowScroll && verticalScrollbar())
             verticalScrollbar()->setEnabled(hasVerticalOverflow);
     }
 
     // We need to layout again if scrollbars are added or removed by overflow:auto,
     // or by changing between native and custom.
     bool horizontalScrollBarChanged = (box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow))
-        || (box().style()->overflowX() == OSCROLL && !horizontalScrollbar());
+        || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar());
     bool verticalScrollBarChanged = (box().hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow))
-        || (box().style()->overflowY() == OSCROLL && !verticalScrollbar());
+        || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar());
     if (!visualViewportSuppliesScrollbars() && (horizontalScrollBarChanged || verticalScrollBarChanged)) {
         if (box().hasAutoHorizontalScrollbar())
             setHasHorizontalScrollbar(hasHorizontalOverflow);
-        else if (box().style()->overflowX() == OSCROLL)
+        else if (box().style()->overflowX() == OverflowScroll)
             setHasHorizontalScrollbar(true);
         if (box().hasAutoVerticalScrollbar())
             setHasVerticalScrollbar(hasVerticalOverflow);
-        else if (box().style()->overflowY() == OSCROLL)
+        else if (box().style()->overflowY() == OverflowScroll)
             setHasVerticalScrollbar(true);
 
         if (hasVerticalOverflow || hasHorizontalOverflow)
@@ -677,7 +677,7 @@
             box().document().setAnnotatedRegionsDirty(true);
 
         // Our proprietary overflow: overlay value doesn't trigger a layout.
-        if ((horizontalScrollBarChanged && box().style()->overflowX() != OOVERLAY) || (verticalScrollBarChanged && box().style()->overflowY() != OOVERLAY)) {
+        if ((horizontalScrollBarChanged && box().style()->overflowX() != OverflowOverlay) || (verticalScrollBarChanged && box().style()->overflowY() != OverflowOverlay)) {
             if (!m_inOverflowRelayout) {
                 m_inOverflowRelayout = true;
                 if (delayedLayoutScope) {
@@ -760,12 +760,12 @@
 
 static bool overflowRequiresScrollbar(EOverflow overflow)
 {
-    return overflow == OSCROLL;
+    return overflow == OverflowScroll;
 }
 
 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
 {
-    return overflow == OAUTO || overflow == OOVERLAY;
+    return overflow == OverflowAuto || overflow == OverflowOverlay;
 }
 
 // This function returns true if the given box requires overflow scrollbars (as
@@ -824,12 +824,12 @@
 
     // With overflow: scroll, scrollbars are always visible but may be disabled.
     // When switching to another value, we need to re-enable them (see bug 11985).
-    if (needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == OSCROLL && overflowX != OSCROLL) {
+    if (needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == OverflowScroll && overflowX != OverflowScroll) {
         ASSERT(hasHorizontalScrollbar());
         horizontalScrollbar()->setEnabled(true);
     }
 
-    if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL && overflowY != OSCROLL) {
+    if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OverflowScroll && overflowY != OverflowScroll) {
         ASSERT(hasVerticalScrollbar());
         verticalScrollbar()->setEnabled(true);
     }
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainter.cpp b/third_party/WebKit/Source/core/paint/TableCellPainter.cpp
index 92225d9..d30a773 100644
--- a/third_party/WebKit/Source/core/paint/TableCellPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TableCellPainter.cpp
@@ -149,7 +149,7 @@
         return;
 
     LayoutTable* tableElt = m_layoutTableCell.table();
-    if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == HIDE && !m_layoutTableCell.firstChild())
+    if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild())
         return;
 
     LayoutRect paintRect = paintBounds(paintOffset, backgroundObject != &m_layoutTableCell ? AddOffsetFromParent : DoNotAddOffsetFromParent);
@@ -183,7 +183,7 @@
 void TableCellPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
     LayoutTable* table = m_layoutTableCell.table();
-    if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() == HIDE && !m_layoutTableCell.firstChild())
+    if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild())
         return;
 
     bool needsToPaintBorder = m_layoutTableCell.styleRef().hasBorderDecoration() && !table->collapseBorders();
@@ -219,7 +219,7 @@
         return;
 
     LayoutTable* tableElt = m_layoutTableCell.table();
-    if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == HIDE && !m_layoutTableCell.firstChild())
+    if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild())
         return;
 
     if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutTableCell, paintInfo.phase))
diff --git a/third_party/WebKit/Source/core/plugins/PluginView.h b/third_party/WebKit/Source/core/plugins/PluginView.h
index 41328fb..4a3e13a 100644
--- a/third_party/WebKit/Source/core/plugins/PluginView.h
+++ b/third_party/WebKit/Source/core/plugins/PluginView.h
@@ -55,7 +55,7 @@
     virtual void didReceiveResponse(const ResourceResponse&) { }
     virtual void didReceiveData(const char*, int) { }
 
-    virtual void layoutIfNeeded() { }
+    virtual void updateAllLifecyclePhases() { }
     virtual void invalidatePaintIfNeeded() { }
 
 protected:
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
index f7e12f89..352a30f 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
@@ -179,7 +179,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("AbortError: the reader is already released", onRejected);
 
@@ -208,7 +208,7 @@
 
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(result.isSet);
     EXPECT_EQ("TypeError: the reader is already released", onRejected);
@@ -250,7 +250,7 @@
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_FALSE(result.isDone);
@@ -264,7 +264,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result2.isSet);
     EXPECT_FALSE(result2.isDone);
@@ -290,7 +290,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
@@ -298,7 +298,7 @@
     EXPECT_TRUE(onRejected2.isNull());
 
     m_stream->enqueue("hello");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_FALSE(result.isDone);
@@ -308,7 +308,7 @@
     EXPECT_TRUE(onRejected2.isNull());
 
     m_stream->enqueue("world");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result2.isSet);
     EXPECT_FALSE(result2.isDone);
@@ -330,7 +330,7 @@
     String onClosedFulfilled, onClosedRejected;
     ReadResult result;
     String onReadRejected;
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     reader->closed(scriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected));
     reader->read(scriptState()).then(createResultCaptor(&result), createCaptor(&onReadRejected));
     EXPECT_TRUE(onClosedFulfilled.isNull());
@@ -338,7 +338,7 @@
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onReadRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onClosedFulfilled);
     EXPECT_TRUE(onClosedRejected.isNull());
     EXPECT_TRUE(result.isSet);
@@ -361,7 +361,7 @@
 
     String onClosedFulfilled, onClosedRejected;
     String onReadFulfilled, onReadRejected;
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     reader->closed(scriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected));
     reader->read(scriptState()).then(createCaptor(&onReadFulfilled), createCaptor(&onReadRejected));
     EXPECT_TRUE(onClosedFulfilled.isNull());
@@ -369,7 +369,7 @@
     EXPECT_TRUE(onReadFulfilled.isNull());
     EXPECT_TRUE(onReadRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onClosedFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onClosedRejected);
     EXPECT_TRUE(onReadFulfilled.isNull());
@@ -389,7 +389,7 @@
     reader->read(scriptState()).then(createResultCaptor(&result), createCaptor(&onRejected));
     reader->read(scriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(result2.isSet);
@@ -401,7 +401,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_TRUE(result.isDone);
@@ -427,7 +427,7 @@
     reader->read(scriptState()).then(createCaptor(&onFulfilled), createCaptor(&onRejected));
     reader->read(scriptState()).then(createCaptor(&onFulfilled2), createCaptor(&onRejected2));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_TRUE(onFulfilled2.isNull());
@@ -439,7 +439,7 @@
     EXPECT_TRUE(onFulfilled2.isNull());
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ(onRejected, "SyntaxError: some error");
@@ -460,7 +460,7 @@
     reader->read(scriptState()).then(createResultCaptor(&result), createCaptor(&onRejected));
     reader->read(scriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(result2.isSet);
@@ -473,7 +473,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_TRUE(result.isDone);
@@ -502,7 +502,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("TypeError: the reader is already released", onRejected);
@@ -528,7 +528,7 @@
     EXPECT_TRUE(onCancelFulfilled.isNull());
     EXPECT_TRUE(onCancelRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onClosedFulfilled);
     EXPECT_TRUE(onClosedRejected.isNull());
     EXPECT_EQ("undefined", onCancelFulfilled);
@@ -552,7 +552,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(exceptionState.hadException());
@@ -574,7 +574,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onRejected);
     EXPECT_FALSE(exceptionState.hadException());
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
index fb52f46..031ecdd 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
@@ -304,7 +304,7 @@
 
     stream->read(scriptState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
     EXPECT_FALSE(stream->isPulling());
@@ -335,7 +335,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
 }
@@ -358,7 +358,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("NotFoundError: error", onRejected);
 }
@@ -392,7 +392,7 @@
     EXPECT_TRUE(onCancelFulfilled.isNull());
     EXPECT_TRUE(onCancelRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onCancelFulfilled);
     EXPECT_TRUE(onCancelRejected.isNull());
 }
@@ -416,7 +416,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("TypeError: this stream is locked to a ReadableStreamReader", onRejected);
@@ -563,7 +563,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
 }
@@ -586,7 +586,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onRejected);
 }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index d426901..49ee65b 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -197,7 +197,7 @@
 
         bool operator!=(const InheritedFlags& other) const { return !(*this == other); }
 
-        unsigned _empty_cells : 1; // EEmptyCell
+        unsigned _empty_cells : 1; // EEmptyCells
         unsigned _caption_side : 2; // ECaptionSide
         unsigned _list_style_type : 7; // EListStyleType
         unsigned _list_style_position : 1; // EListStylePosition
@@ -573,12 +573,12 @@
     EOverflow overflowX() const { return static_cast<EOverflow>(noninherited_flags.overflowX); }
     EOverflow overflowY() const { return static_cast<EOverflow>(noninherited_flags.overflowY); }
     // It's sufficient to just check one direction, since it's illegal to have visible on only one overflow value.
-    bool isOverflowVisible() const { ASSERT(overflowX() != OVISIBLE || overflowX() == overflowY()); return overflowX() == OVISIBLE; }
-    bool isOverflowPaged() const { return overflowY() == OPAGEDX || overflowY() == OPAGEDY; }
+    bool isOverflowVisible() const { ASSERT(overflowX() != OverflowVisible || overflowX() == overflowY()); return overflowX() == OverflowVisible; }
+    bool isOverflowPaged() const { return overflowY() == OverflowPagedX || overflowY() == OverflowPagedY; }
 
     EVisibility visibility() const { return static_cast<EVisibility>(inherited_flags._visibility); }
     EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(noninherited_flags.verticalAlign); }
-    const Length& verticalAlignLength() const { return m_box->verticalAlign(); }
+    const Length& getVerticalAlignLength() const { return m_box->verticalAlign(); }
 
     const Length& clipLeft() const { return visual->clip.left(); }
     const Length& clipRight() const { return visual->clip.right(); }
@@ -591,7 +591,7 @@
 
     EClear clear() const { return static_cast<EClear>(noninherited_flags.clear); }
     ETableLayout tableLayout() const { return static_cast<ETableLayout>(noninherited_flags.tableLayout); }
-    bool isFixedTableLayout() const { return tableLayout() == TFIXED && !logicalWidth().isAuto(); }
+    bool isFixedTableLayout() const { return tableLayout() == TableLayoutFixed && !logicalWidth().isAuto(); }
 
     const Font& font() const;
     const FontMetrics& fontMetrics() const;
@@ -711,7 +711,7 @@
     EBorderCollapse borderCollapse() const { return static_cast<EBorderCollapse>(inherited_flags._border_collapse); }
     short horizontalBorderSpacing() const;
     short verticalBorderSpacing() const;
-    EEmptyCell emptyCells() const { return static_cast<EEmptyCell>(inherited_flags._empty_cells); }
+    EEmptyCells emptyCells() const { return static_cast<EEmptyCells>(inherited_flags._empty_cells); }
     ECaptionSide captionSide() const { return static_cast<ECaptionSide>(inherited_flags._caption_side); }
 
     EListStyleType listStyleType() const { return static_cast<EListStyleType>(inherited_flags._list_style_type); }
@@ -873,7 +873,7 @@
         // out along the inline axis, just like for regular multicol. Otherwise, we need to lay out
         // along the block axis.
         if (isOverflowPaged())
-            return (overflowY() == OPAGEDX) == isHorizontalWritingMode();
+            return (overflowY() == OverflowPagedX) == isHorizontalWritingMode();
         return false;
     }
     float columnWidth() const { return rareNonInheritedData->m_multiCol->m_width; }
@@ -1157,7 +1157,7 @@
     void setOverflowY(EOverflow v) { noninherited_flags.overflowY = v; }
     void setVisibility(EVisibility v) { inherited_flags._visibility = v; }
     void setVerticalAlign(EVerticalAlign v) { noninherited_flags.verticalAlign = v; }
-    void setVerticalAlignLength(const Length& length) { setVerticalAlign(LENGTH); SET_VAR(m_box, m_verticalAlign, length); }
+    void setVerticalAlignLength(const Length& length) { setVerticalAlign(VerticalAlignLength); SET_VAR(m_box, m_verticalAlign, length); }
 
     void setHasAutoClip() { SET_VAR(visual, hasAutoClip, true); SET_VAR(visual, clip, ComputedStyle::initialClip()); }
     void setClip(const LengthBox& box) { SET_VAR(visual, hasAutoClip, false); SET_VAR(visual, clip, box); }
@@ -1238,7 +1238,7 @@
     void setBorderCollapse(EBorderCollapse collapse) { inherited_flags._border_collapse = collapse; }
     void setHorizontalBorderSpacing(short);
     void setVerticalBorderSpacing(short);
-    void setEmptyCells(EEmptyCell v) { inherited_flags._empty_cells = v; }
+    void setEmptyCells(EEmptyCells v) { inherited_flags._empty_cells = v; }
     void setCaptionSide(ECaptionSide v) { inherited_flags._caption_side = v; }
 
     void setListStyleType(EListStyleType v) { inherited_flags._list_style_type = v; }
@@ -1652,8 +1652,8 @@
     static OutlineIsAuto initialOutlineStyleIsAuto() { return OutlineIsAutoOff; }
     static NinePieceImage initialNinePieceImage() { return NinePieceImage(); }
     static LengthSize initialBorderRadius() { return LengthSize(Length(0, Fixed), Length(0, Fixed)); }
-    static ECaptionSide initialCaptionSide() { return CAPTOP; }
-    static EClear initialClear() { return CNONE; }
+    static ECaptionSide initialCaptionSide() { return CaptionSideTop; }
+    static EClear initialClear() { return ClearNone; }
     static LengthBox initialClip() { return LengthBox(); }
     static Containment initialContain() { return ContainsNone; }
     static TextDirection initialDirection() { return LTR; }
@@ -1663,17 +1663,17 @@
     static ObjectFit initialObjectFit() { return ObjectFitFill; }
     static LengthPoint initialObjectPosition() { return LengthPoint(Length(50.0, Percent), Length(50.0, Percent)); }
     static EDisplay initialDisplay() { return INLINE; }
-    static EEmptyCell initialEmptyCells() { return SHOW; }
+    static EEmptyCells initialEmptyCells() { return EmptyCellsShow; }
     static EFloat initialFloating() { return NoFloat; }
-    static EListStylePosition initialListStylePosition() { return OUTSIDE; }
+    static EListStylePosition initialListStylePosition() { return ListStylePositionOutside; }
     static EListStyleType initialListStyleType() { return Disc; }
-    static EOverflow initialOverflowX() { return OVISIBLE; }
-    static EOverflow initialOverflowY() { return OVISIBLE; }
+    static EOverflow initialOverflowX() { return OverflowVisible; }
+    static EOverflow initialOverflowY() { return OverflowVisible; }
     static EBreak initialBreakAfter() { return BreakAuto; }
     static EBreak initialBreakBefore() { return BreakAuto; }
     static EBreak initialBreakInside() { return BreakAuto; }
     static EPosition initialPosition() { return StaticPosition; }
-    static ETableLayout initialTableLayout() { return TAUTO; }
+    static ETableLayout initialTableLayout() { return TableLayoutAuto; }
     static EUnicodeBidi initialUnicodeBidi() { return UBNormal; }
     static ETextTransform initialTextTransform() { return TTNONE; }
     static EVisibility initialVisibility() { return VISIBLE; }
@@ -1696,7 +1696,7 @@
     static Length initialTextIndent() { return Length(Fixed); }
     static TextIndentLine initialTextIndentLine() { return TextIndentFirstLine; }
     static TextIndentType initialTextIndentType() { return TextIndentNormal; }
-    static EVerticalAlign initialVerticalAlign() { return BASELINE; }
+    static EVerticalAlign initialVerticalAlign() { return VerticalAlignBaseline; }
     static short initialWidows() { return 1; }
     static short initialOrphans() { return 2; }
     static Length initialLineHeight() { return Length(-100.0, Percent); }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index df5c62b..3ab8be78 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -120,20 +120,28 @@
 // Random visual rendering model attributes. Not inherited.
 
 enum EOverflow {
-    OVISIBLE, OHIDDEN, OSCROLL, OAUTO, OOVERLAY, OPAGEDX, OPAGEDY
+    OverflowVisible, OverflowHidden, OverflowScroll, OverflowAuto, OverflowOverlay, OverflowPagedX, OverflowPagedY
 };
 
 enum EVerticalAlign {
-    BASELINE, MIDDLE, SUB, SUPER, TEXT_TOP,
-    TEXT_BOTTOM, TOP, BOTTOM, BASELINE_MIDDLE, LENGTH
+    VerticalAlignBaseline,
+    VerticalAlignMiddle,
+    VerticalAlignSub,
+    VerticalAlignSuper,
+    VerticalAlignTextTop,
+    VerticalAlignTextBottom,
+    VerticalAlignTop,
+    VerticalAlignBottom,
+    VerticalAlignBaselineMiddle,
+    VerticalAlignLength
 };
 
 enum EClear {
-    CNONE = 0, CLEFT = 1, CRIGHT = 2, CBOTH = 3
+    ClearNone = 0, ClearLeft = 1, ClearRight = 2, ClearBoth = 3
 };
 
 enum ETableLayout {
-    TAUTO, TFIXED
+    TableLayoutAuto, TableLayoutFixed
 };
 
 enum TextCombine {
@@ -350,15 +358,15 @@
     BreakAlways // Only needed by {page,-webkit-column}-break-{after,before} shorthands.
 };
 
-enum EEmptyCell {
-    SHOW, HIDE
+enum EEmptyCells {
+    EmptyCellsShow, EmptyCellsHide
 };
 
 enum ECaptionSide {
-    CAPTOP, CAPBOTTOM, CAPLEFT, CAPRIGHT
+    CaptionSideTop, CaptionSideBottom, CaptionSideLeft, CaptionSideRight
 };
 
-enum EListStylePosition { OUTSIDE, INSIDE };
+enum EListStylePosition { ListStylePositionOutside, ListStylePositionInside };
 
 enum EVisibility { VISIBLE, HIDDEN, COLLAPSE };
 
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
index f2e15b31..938f53e 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
@@ -78,7 +78,7 @@
 
 bool StyleFetchedImage::canRender() const
 {
-    return m_image->canRender();
+    return !m_image->errorOccurred() && !m_image->image()->isNull();
 }
 
 bool StyleFetchedImage::isLoaded() const
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
index 0eeb5bb..e42aefb 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
@@ -80,7 +80,7 @@
 
 bool StyleFetchedImageSet::canRender() const
 {
-    return m_bestFitImage->canRender();
+    return !m_bestFitImage->errorOccurred() && !m_bestFitImage->image()->isNull();
 }
 
 bool StyleFetchedImageSet::isLoaded() const
diff --git a/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp b/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp
index ebe19d2..062cdb53 100644
--- a/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp
@@ -21,15 +21,12 @@
 #include "core/svg/SVGTitleElement.h"
 
 #include "core/SVGNames.h"
-#include "core/dom/ChildListMutationScope.h"
 #include "core/dom/Document.h"
-#include "core/dom/Text.h"
 
 namespace blink {
 
 inline SVGTitleElement::SVGTitleElement(Document& document)
     : SVGElement(SVGNames::titleTag, document)
-    , m_ignoreTitleUpdatesWhenChildrenChange(false)
 {
 }
 
@@ -55,23 +52,8 @@
 void SVGTitleElement::childrenChanged(const ChildrenChange& change)
 {
     SVGElement::childrenChanged(change);
-    if (inDocument() && document().isSVGDocument() && !m_ignoreTitleUpdatesWhenChildrenChange)
+    if (inDocument() && document().isSVGDocument())
         document().setTitleElement(this);
 }
 
-void SVGTitleElement::setText(const String& value)
-{
-    RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
-    ChildListMutationScope mutation(*this);
-
-    {
-        // Avoid calling Document::setTitleElement() during intermediate steps.
-        TemporaryChange<bool> inhibitTitleUpdateScope(m_ignoreTitleUpdatesWhenChildrenChange, !value.isEmpty());
-        removeChildren(OmitSubtreeModifiedEvent);
-    }
-
-    if (!value.isEmpty())
-        appendChild(document().createTextNode(value.impl()), IGNORE_EXCEPTION);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGTitleElement.h b/third_party/WebKit/Source/core/svg/SVGTitleElement.h
index 1adc590..31e9753 100644
--- a/third_party/WebKit/Source/core/svg/SVGTitleElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGTitleElement.h
@@ -30,8 +30,6 @@
 public:
     DECLARE_NODE_FACTORY(SVGTitleElement);
 
-    void setText(const String&);
-
 private:
     explicit SVGTitleElement(Document&);
 
@@ -40,8 +38,6 @@
     void childrenChanged(const ChildrenChange&) override;
 
     bool layoutObjectIsNeeded(const ComputedStyle&) override { return false; }
-
-    bool m_ignoreTitleUpdatesWhenChildrenChange;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 53d7569..12f24bf 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -102,6 +102,7 @@
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutTreeAsText.h"
 #include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutMenuListItem.h"
 #include "core/layout/compositing/CompositedLayerMapping.h"
 #include "core/layout/compositing/PaintLayerCompositor.h"
 #include "core/loader/DocumentLoader.h"
@@ -2178,8 +2179,8 @@
     if (!layoutObject || !layoutObject->isMenuList())
         return String();
 
-    LayoutMenuList* menuList = toLayoutMenuList(layoutObject);
-    return menuList->text();
+    LayoutMenuListItem menuListItem = LayoutMenuListItem(toLayoutMenuList(layoutObject));
+    return menuListItem.text();
 }
 
 bool Internals::isSelectPopupVisible(Node* node)
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp b/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
index f2a649d..a52527e 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
@@ -25,6 +25,7 @@
 
 NullExecutionContext::NullExecutionContext()
     : m_tasksNeedSuspension(false)
+    , m_isSecureContext(true)
     , m_queue(adoptPtrWillBeNoop(new NullEventQueue()))
 {
 }
@@ -33,9 +34,16 @@
 {
 }
 
+void NullExecutionContext::setIsSecureContext(bool isSecureContext)
+{
+    m_isSecureContext = isSecureContext;
+}
+
 bool NullExecutionContext::isSecureContext(String& errorMessage, const SecureContextCheck privilegeContextCheck) const
 {
-    return true;
+    if (!m_isSecureContext)
+        errorMessage = "A secure context is required";
+    return m_isSecureContext;
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.h b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
index 9883edf..9f88e8c 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.h
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
@@ -40,6 +40,7 @@
     void addConsoleMessage(PassRefPtrWillBeRawPtr<ConsoleMessage>) override { }
     void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) override { }
 
+    void setIsSecureContext(bool);
     bool isSecureContext(String& errorMessage, const SecureContextCheck = StandardSecureContextCheck) const override;
 
     DEFINE_INLINE_TRACE()
@@ -63,6 +64,7 @@
 
 private:
     bool m_tasksNeedSuspension;
+    bool m_isSecureContext;
     OwnPtrWillBeMember<EventQueue> m_queue;
 
     KURL m_dummyURL;
diff --git a/third_party/WebKit/Source/core/workers/WorkerConsole.idl b/third_party/WebKit/Source/core/workers/WorkerConsole.idl
index 79d4f8b..6870a90 100644
--- a/third_party/WebKit/Source/core/workers/WorkerConsole.idl
+++ b/third_party/WebKit/Source/core/workers/WorkerConsole.idl
@@ -26,8 +26,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// Console API (non-standard but widely implemented in some form)
-// https://developer.chrome.com/devtools/docs/console-api
+// Console API
+// https://console.spec.whatwg.org/#console-interface
 
 // TODO(philipj): Both Firefox and IE use the Console interface in workers and
 // on the main thread alike, with no WorkerConsole or similar interface.
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
index 856c451..32cbca8 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
@@ -43,8 +43,8 @@
     [RaisesException] void importScripts(DOMString... urls);
     readonly attribute WorkerNavigator navigator;
 
-    // Console API (non-standard but widely implemented in some form)
-    // https://developer.chrome.com/devtools/docs/console-api
+    // Console API
+    // https://console.spec.whatwg.org/#console-interface
     [Replaceable] readonly attribute WorkerConsole console;
 
     // CORS and RFC1918
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
index 7b81cd8..2bf55411d 100644
--- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
@@ -82,7 +82,7 @@
     WorkerThreadableLoader::loadResourceSynchronously(toWorkerGlobalScope(executionContext), request, *this, options, resourceLoaderOptions);
 }
 
-void WorkerScriptLoader::loadAsynchronously(ExecutionContext& executionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy, PassOwnPtr<Closure> responseCallback, PassOwnPtr<Closure> finishedCallback)
+void WorkerScriptLoader::loadAsynchronously(ExecutionContext& executionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy, PassOwnPtr<SameThreadClosure> responseCallback, PassOwnPtr<SameThreadClosure> finishedCallback)
 {
     ASSERT(responseCallback || finishedCallback);
     m_responseCallback = responseCallback;
@@ -222,7 +222,7 @@
     if (!m_finishedCallback)
         return;
 
-    OwnPtr<Closure> callback = m_finishedCallback.release();
+    OwnPtr<SameThreadClosure> callback = m_finishedCallback.release();
     (*callback)();
 }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
index ae1b922..67c44a3 100644
--- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
+++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
@@ -61,7 +61,7 @@
     // used from worker context and the worker shuts down in the middle of an
     // operation. This will cause leaks when we support nested workers.
     // Note that callbacks could be invoked before loadAsynchronously() returns.
-    void loadAsynchronously(ExecutionContext&, const KURL&, CrossOriginRequestPolicy, PassOwnPtr<Closure> responseCallback, PassOwnPtr<Closure> finishedCallback);
+    void loadAsynchronously(ExecutionContext&, const KURL&, CrossOriginRequestPolicy, PassOwnPtr<SameThreadClosure> responseCallback, PassOwnPtr<SameThreadClosure> finishedCallback);
 
     // This will immediately invoke |finishedCallback| if loadAsynchronously()
     // is in progress.
@@ -105,8 +105,8 @@
     void processContentSecurityPolicy(const ResourceResponse&);
 
     // Callbacks for loadAsynchronously().
-    OwnPtr<Closure> m_responseCallback;
-    OwnPtr<Closure> m_finishedCallback;
+    OwnPtr<SameThreadClosure> m_responseCallback;
+    OwnPtr<SameThreadClosure> m_finishedCallback;
 
     RefPtr<ThreadableLoader> m_threadableLoader;
     String m_responseEncoding;
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index c96a79b..6e8997d 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -122,7 +122,7 @@
         InspectorInstrumentation::didPerformExecutionContextTask(globalScope);
 }
 
-PassOwnPtr<Closure> WorkerThread::createWorkerThreadTask(PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
+PassOwnPtr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
 {
     if (isInstrumented)
         isInstrumented = !task->taskNameForInstrumentation().isEmpty();
@@ -440,12 +440,12 @@
 
 void WorkerThread::runDebuggerTaskDontWait()
 {
-    OwnPtr<Closure> task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::DontWaitForTask);
+    OwnPtr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::DontWaitForTask);
     if (task)
         (*task)();
 }
 
-void WorkerThread::appendDebuggerTask(PassOwnPtr<Closure> task)
+void WorkerThread::appendDebuggerTask(PassOwnPtr<CrossThreadClosure> task)
 {
     {
         MutexLocker lock(m_threadStateMutex);
@@ -461,7 +461,7 @@
     backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::runDebuggerTaskDontWait, AllowCrossThreadAccess(this)));
 }
 
-void WorkerThread::runDebuggerTask(PassOwnPtr<Closure> task)
+void WorkerThread::runDebuggerTask(PassOwnPtr<CrossThreadClosure> task)
 {
     ASSERT(isCurrentThread());
     InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get());
@@ -486,7 +486,7 @@
 {
     m_pausedInDebugger = true;
     InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get());
-    OwnPtr<Closure> task;
+    OwnPtr<CrossThreadClosure> task;
     do {
         {
             SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.h b/third_party/WebKit/Source/core/workers/WorkerThread.h
index 340922c..f04b67c 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.h
@@ -96,7 +96,7 @@
     WorkerReportingProxy& workerReportingProxy() const { return m_workerReportingProxy; }
 
     void postTask(const WebTraceLocation&, PassOwnPtr<ExecutionContextTask>);
-    void appendDebuggerTask(PassOwnPtr<Closure>);
+    void appendDebuggerTask(PassOwnPtr<CrossThreadClosure>);
 
     // Runs only debugger tasks while paused in debugger, called on worker thread.
     void startRunningDebuggerTasksOnPause();
@@ -136,7 +136,7 @@
 private:
     friend class WorkerMicrotaskRunner;
 
-    PassOwnPtr<Closure> createWorkerThreadTask(PassOwnPtr<ExecutionContextTask>, bool isInstrumented);
+    PassOwnPtr<CrossThreadClosure> createWorkerThreadTask(PassOwnPtr<ExecutionContextTask>, bool isInstrumented);
 
     // Called on the main thread.
     void terminateInternal();
@@ -147,7 +147,7 @@
     void performTask(PassOwnPtr<ExecutionContextTask>, bool isInstrumented);
     void performShutdownTask();
     void postDelayedTask(const WebTraceLocation&, PassOwnPtr<ExecutionContextTask>, long long delayMs);
-    void runDebuggerTask(PassOwnPtr<Closure>);
+    void runDebuggerTask(PassOwnPtr<CrossThreadClosure>);
     void runDebuggerTaskDontWait();
 
     bool m_started;
diff --git a/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css b/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css
index 6d73e6b6..741ba56 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css
+++ b/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css
@@ -222,6 +222,7 @@
 
 .json-view {
     padding: 2px 6px;
+    overflow: auto;
 }
 
 .request-view.html iframe {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/emptyWidget.css b/third_party/WebKit/Source/devtools/front_end/ui/emptyWidget.css
index 76fb32bb..0e528df 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/emptyWidget.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/emptyWidget.css
@@ -12,4 +12,5 @@
     display: flex;
     align-items: center;
     justify-content: center;
+    overflow: auto;
 }
diff --git a/third_party/WebKit/Source/modules/InitModules.cpp b/third_party/WebKit/Source/modules/InitModules.cpp
index a066345..539c6b25 100644
--- a/third_party/WebKit/Source/modules/InitModules.cpp
+++ b/third_party/WebKit/Source/modules/InitModules.cpp
@@ -51,9 +51,12 @@
     ASSERT(isInitialized());
 }
 
-void ModulesInitializer::terminateThreads()
+void ModulesInitializer::shutdown()
 {
+    ASSERT(isInitialized());
     DatabaseManager::terminateDatabaseThread();
+    CoreInitializer::shutdown();
+
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/modules/InitModules.h b/third_party/WebKit/Source/modules/InitModules.h
index 116c7e18..17487c811 100644
--- a/third_party/WebKit/Source/modules/InitModules.h
+++ b/third_party/WebKit/Source/modules/InitModules.h
@@ -13,7 +13,7 @@
 class MODULES_EXPORT ModulesInitializer : public CoreInitializer {
 public:
     void init() override;
-    static void terminateThreads();
+    void shutdown() override;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/modules/accessibility/AXTable.cpp b/third_party/WebKit/Source/modules/accessibility/AXTable.cpp
index 3c32e17..ce598f4 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXTable.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXTable.cpp
@@ -241,7 +241,7 @@
                 continue;
 
             // If the empty-cells style is set, we'll call it a data table.
-            if (computedStyle->emptyCells() == HIDE)
+            if (computedStyle->emptyCells() == EmptyCellsHide)
                 return true;
 
             // If a cell has matching bordered sides, call it a (fully) bordered cell.
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
index 7834ae9..1c4030cb 100644
--- a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
+++ b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
@@ -249,7 +249,7 @@
     {
         ScriptValue onReject;
         promise.then(UnreachableFunction::create(scriptState()), TestFunction::create(scriptState(), &onReject));
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         return onReject;
     }
 
@@ -263,7 +263,7 @@
     {
         ScriptValue onResolve;
         promise.then(TestFunction::create(scriptState(), &onResolve), UnreachableFunction::create(scriptState()));
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         return onResolve;
     }
 
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
index b143bf7..fc54817 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
@@ -19,7 +19,6 @@
 #include "modules/encryptedmedia/MediaKeys.h"
 #include "platform/ContentDecryptionModuleResult.h"
 #include "platform/Logging.h"
-#include "platform/RuntimeEnabledFeatures.h"
 #include "wtf/Functional.h"
 
 namespace blink {
@@ -357,20 +356,17 @@
 {
     WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::encrypted");
 
-    if (RuntimeEnabledFeatures::encryptedMediaEnabled()) {
-        // Send event for WD EME.
-        RefPtrWillBeRawPtr<Event> event;
-        if (m_mediaElement->isMediaDataCORSSameOrigin(m_mediaElement->executionContext()->securityOrigin())) {
-            event = createEncryptedEvent(initDataType, initData, initDataLength);
-        } else {
-            // Current page is not allowed to see content from the media file,
-            // so don't return the initData. However, they still get an event.
-            event = createEncryptedEvent(WebEncryptedMediaInitDataType::Unknown, nullptr, 0);
-        }
-
-        event->setTarget(m_mediaElement);
-        m_mediaElement->scheduleEvent(event.release());
+    RefPtrWillBeRawPtr<Event> event;
+    if (m_mediaElement->isMediaDataCORSSameOrigin(m_mediaElement->executionContext()->securityOrigin())) {
+        event = createEncryptedEvent(initDataType, initData, initDataLength);
+    } else {
+        // Current page is not allowed to see content from the media file,
+        // so don't return the initData. However, they still get an event.
+        event = createEncryptedEvent(WebEncryptedMediaInitDataType::Unknown, nullptr, 0);
     }
+
+    event->setTarget(m_mediaElement);
+    m_mediaElement->scheduleEvent(event.release());
 }
 
 void HTMLMediaElementEncryptedMedia::didBlockPlaybackWaitingForKey()
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl
index f096397f..34e23ce 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 partial interface HTMLMediaElement {
-    [RuntimeEnabled=EncryptedMedia] readonly attribute MediaKeys mediaKeys;
-    [RuntimeEnabled=EncryptedMedia, CallWith=ScriptState] Promise setMediaKeys(MediaKeys? mediaKeys);
-    [RuntimeEnabled=EncryptedMedia] attribute EventHandler onencrypted;
+    readonly attribute MediaKeys mediaKeys;
+    [CallWith=ScriptState] Promise setMediaKeys(MediaKeys? mediaKeys);
+    attribute EventHandler onencrypted;
 };
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaEncryptedEvent.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaEncryptedEvent.idl
index ec07de9..ac2b965d 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaEncryptedEvent.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaEncryptedEvent.idl
@@ -27,7 +27,6 @@
 
 [
     Constructor(DOMString type, optional MediaEncryptedEventInit eventInitDict),
-    RuntimeEnabled=EncryptedMedia,
 ] interface MediaEncryptedEvent : Event {
     readonly attribute DOMString initDataType;
     readonly attribute ArrayBuffer? initData;
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl
index 1d9dbdb..f4a03dba 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl
@@ -32,8 +32,7 @@
 };
 
 [
-    Constructor(DOMString type, optional MediaKeyMessageEventInit eventInitDict),
-    RuntimeEnabled=EncryptedMedia
+    Constructor(DOMString type, optional MediaKeyMessageEventInit eventInitDict)
 ] interface MediaKeyMessageEvent : Event {
     readonly attribute MediaKeyMessageType messageType;
     readonly attribute ArrayBuffer message;
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.idl
index 5c3e214..6a02652 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.idl
@@ -25,7 +25,6 @@
 
 [
     DependentLifetime,
-    RuntimeEnabled=EncryptedMedia,
     GarbageCollected,
 ] interface MediaKeySession : EventTarget {
     // session properties
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.idl
index 02069e7..9ea3c04 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.idl
@@ -5,7 +5,6 @@
 // http://w3c.github.io/encrypted-media/#mediakeysystemaccess-interface
 
 [
-    RuntimeEnabled=EncryptedMedia,
     GarbageCollected,
 ] interface MediaKeySystemAccess {
     readonly attribute DOMString keySystem;
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemConfiguration.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemConfiguration.idl
index 2db1454..6c361f6 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemConfiguration.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemConfiguration.idl
@@ -10,9 +10,7 @@
     "not-allowed"
 };
 
-[
-    RuntimeEnabled=EncryptedMedia
-] dictionary MediaKeySystemConfiguration {
+dictionary MediaKeySystemConfiguration {
     sequence<DOMString> initDataTypes;
     sequence<MediaKeySystemMediaCapability> audioCapabilities;
     sequence<MediaKeySystemMediaCapability> videoCapabilities;
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemMediaCapability.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemMediaCapability.idl
index 4f06468..2895169 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemMediaCapability.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemMediaCapability.idl
@@ -4,9 +4,7 @@
 
 // https://w3c.github.io/encrypted-media/#idl-def-MediaKeySystemMediaCapability
 
-[
-    RuntimeEnabled=EncryptedMedia
-] dictionary MediaKeySystemMediaCapability {
+dictionary MediaKeySystemMediaCapability {
     DOMString contentType = "";
     DOMString robustness = "";
 };
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl
index 8bf9389..f8fd221 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl
@@ -30,7 +30,6 @@
 
 [
     DependentLifetime,
-    RuntimeEnabled=EncryptedMedia,
     GarbageCollected,
 ] interface MediaKeys {
     [CallWith=ScriptState, RaisesException] MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl
index e04f29a..62c96b7 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl
@@ -4,8 +4,6 @@
 
 // https://w3c.github.io/encrypted-media/#navigator-extension-requestmediakeysystemaccess
 
-[
-    RuntimeEnabled=EncryptedMedia
-] partial interface Navigator {
+partial interface Navigator {
     [CallWith=ScriptState] Promise<MediaKeySystemAccess> requestMediaKeySystemAccess(DOMString keySystem, sequence<MediaKeySystemConfiguration> supportedConfigurations);
 };
diff --git a/third_party/WebKit/Source/modules/fetch/CrossThreadHolder.h b/third_party/WebKit/Source/modules/fetch/CrossThreadHolder.h
index 3601350..125a959 100644
--- a/third_party/WebKit/Source/modules/fetch/CrossThreadHolder.h
+++ b/third_party/WebKit/Source/modules/fetch/CrossThreadHolder.h
@@ -46,7 +46,7 @@
     // destructed (possibly on the calling thread or on the thread of
     // |executionContext|) when |executionContext| is stopped or
     // CrossThreadHolder is destructed.
-    void postTask(PassOwnPtr<WTF::Function<void(T*, ExecutionContext*)>> task)
+    void postTask(PassOwnPtr<WTF::Function<void(T*, ExecutionContext*), WTF::CrossThreadAffinity>> task)
     {
         MutexLocker locker(m_mutex->mutex());
         if (!m_bridge) {
@@ -119,7 +119,7 @@
             m_holder = nullptr;
         }
 
-        void runTask(PassOwnPtr<WTF::Function<void(T*, ExecutionContext*)>> task)
+        void runTask(PassOwnPtr<WTF::Function<void(T*, ExecutionContext*), WTF::CrossThreadAffinity>> task)
         {
             ASSERT(executionContext()->isContextThread());
             if (m_obj)
diff --git a/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h b/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h
index b027bbb..cbfaafe 100644
--- a/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h
+++ b/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h
@@ -115,13 +115,13 @@
                 ASSERT(m_holder);
                 m_holder = nullptr;
             }
-            void postTaskToReadingThread(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+            void postTaskToReadingThread(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
             {
                 MutexLocker locker(m_holderMutex);
                 ASSERT(m_holder);
                 m_holder->readingThread()->postTask(location, task);
             }
-            void postTaskToUpdatingThread(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+            void postTaskToUpdatingThread(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
             {
                 MutexLocker locker(m_holderMutex);
                 ASSERT(m_holder);
@@ -218,20 +218,20 @@
         void resetReader() { m_reader = nullptr; }
         void signalDone() { m_waitableEvent->signal(); }
         const String& result() { return m_context->result(); }
-        void postTaskToReadingThread(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+        void postTaskToReadingThread(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
         {
             m_context->postTaskToReadingThread(location,  task);
         }
-        void postTaskToUpdatingThread(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+        void postTaskToUpdatingThread(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
         {
             m_context->postTaskToUpdatingThread(location,  task);
         }
-        void postTaskToReadingThreadAndWait(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+        void postTaskToReadingThreadAndWait(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
         {
             postTaskToReadingThread(location,  task);
             m_waitableEvent->wait();
         }
-        void postTaskToUpdatingThreadAndWait(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+        void postTaskToUpdatingThreadAndWait(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
         {
             postTaskToUpdatingThread(location,  task);
             m_waitableEvent->wait();
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
index 9a9daead..fba225c 100644
--- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
+++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
@@ -8,6 +8,7 @@
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8GCController.h"
+#include "bindings/core/v8/V8RecursionScope.h"
 #include "core/dom/Document.h"
 #include "core/testing/DummyPageHolder.h"
 #include "modules/fetch/DataConsumerHandleTestUtil.h"
@@ -59,6 +60,7 @@
     {
         v8::Local<v8::String> source;
         v8::Local<v8::Script> script;
+        V8RecursionScope::MicrotaskSuppression microtasks(isolate());
         if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
             ADD_FAILURE();
             return v8::MaybeLocal<v8::Value>();
diff --git a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
index e4bcc4c..6e4cb88 100644
--- a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
@@ -121,7 +121,7 @@
     return Platform::current()->fileSystem();
 }
 
-void LocalFileSystem::requestFileSystemAccessInternal(ExecutionContext* context, PassOwnPtr<Closure> allowed, PassOwnPtr<Closure> denied)
+void LocalFileSystem::requestFileSystemAccessInternal(ExecutionContext* context, PassOwnPtr<SameThreadClosure> allowed, PassOwnPtr<SameThreadClosure> denied)
 {
     if (!client()) {
         (*denied)();
diff --git a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h
index 986eed47..a5a8e0c 100644
--- a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h
@@ -75,7 +75,7 @@
 
 private:
     WebFileSystem* fileSystem() const;
-    void requestFileSystemAccessInternal(ExecutionContext*, PassOwnPtr<Closure> allowed, PassOwnPtr<Closure> denied);
+    void requestFileSystemAccessInternal(ExecutionContext*, PassOwnPtr<SameThreadClosure> allowed, PassOwnPtr<SameThreadClosure> denied);
     void fileSystemNotAvailable(PassRefPtrWillBeRawPtr<ExecutionContext>, CallbackWrapper*);
     void fileSystemNotAllowedInternal(PassRefPtrWillBeRawPtr<ExecutionContext>, CallbackWrapper*);
     void fileSystemAllowedInternal(PassRefPtrWillBeRawPtr<ExecutionContext>, FileSystemType, CallbackWrapper*);
diff --git a/third_party/WebKit/Source/modules/mediasource/MediaSource.idl b/third_party/WebKit/Source/modules/mediasource/MediaSource.idl
index 253faa0..a5ac50b7 100644
--- a/third_party/WebKit/Source/modules/mediasource/MediaSource.idl
+++ b/third_party/WebKit/Source/modules/mediasource/MediaSource.idl
@@ -28,7 +28,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#idl-def-MediaSource
+// https://www.w3.org/TR/media-source/#idl-def-MediaSource
 
 enum EndOfStreamError {
     "network",
@@ -39,7 +39,6 @@
     DependentLifetime,
     Constructor,
     ConstructorCallWith=ExecutionContext,
-    RuntimeEnabled=MediaSource,
 ] interface MediaSource : EventTarget {
     // All the source buffers created by this object.
     readonly attribute SourceBufferList sourceBuffers;
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.idl b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.idl
index a3f206e..ff2fbba4 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.idl
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.idl
@@ -28,7 +28,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#idl-def-SourceBuffer
+// https://www.w3.org/TR/media-source/#idl-def-SourceBuffer
 
 enum AppendMode {
     "segments",
@@ -37,7 +37,6 @@
 
 [
     DependentLifetime,
-    RuntimeEnabled=MediaSource,
 ] interface SourceBuffer : EventTarget {
 
     // Gets or sets the AppendMode.
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBufferList.idl b/third_party/WebKit/Source/modules/mediasource/SourceBufferList.idl
index 2cd26cc..1fcd8ab 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBufferList.idl
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBufferList.idl
@@ -30,9 +30,7 @@
 
 [
     GarbageCollected,
-    RuntimeEnabled=MediaSource,
 ] interface SourceBufferList : EventTarget {
     readonly attribute unsigned long length;
     [ImplementedAs=item] getter SourceBuffer (unsigned long index);
 };
-
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi
index 40a2149..0cd43e1 100644
--- a/third_party/WebKit/Source/modules/modules.gypi
+++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -321,6 +321,7 @@
       'webusb/USBIsochronousOutTransferResult.idl',
       'webusb/USBOutTransferResult.idl',
       'worklet/Worklet.idl',
+      'worklet/WorkletConsole.idl',
       'worklet/WorkletGlobalScope.idl',
     ],
     # 'partial interface' or target (right side of) 'implements'
@@ -1887,6 +1888,8 @@
       'worklet/DOMWindowWorklet.h',
       'worklet/Worklet.cpp',
       'worklet/Worklet.h',
+      'worklet/WorkletConsole.cpp',
+      'worklet/WorkletConsole.h',
       'worklet/WorkletGlobalScope.cpp',
       'worklet/WorkletGlobalScope.h',
     ],
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
index 8c0af13..cb4e2da8 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
@@ -92,7 +92,7 @@
 {
     StubScriptFunction resolved, rejected;
     promise.then(resolved.function(scriptState), rejected.function(scriptState));
-    promise.isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(promise.isolate());
     EXPECT_EQ(0ul, resolved.callCount());
     EXPECT_EQ(1ul, rejected.callCount());
     if (rejected.callCount())
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp
index c89091f0..7274ba1 100644
--- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp
@@ -294,5 +294,19 @@
     return static_cast<ScriptProcessorHandler&>(handler()).bufferSize();
 }
 
+bool ScriptProcessorNode::hasPendingActivity() const
+{
+    // To prevent the node from leaking after the context is closed.
+    if (context()->isContextClosed())
+        return false;
+
+    // If |onaudioprocess| event handler is defined, the node should not be
+    // GCed even if it is out of scope.
+    if (hasEventListeners(EventTypeNames::audioprocess))
+        return true;
+
+    return false;
+}
+
 } // namespace blink
 
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h
index dbb58cf..d86dc08 100644
--- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h
@@ -106,6 +106,9 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess);
     size_t bufferSize() const;
 
+    // ScriptWrappable
+    bool hasPendingActivity() const final;
+
 private:
     ScriptProcessorNode(AbstractAudioContext&, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels);
 };
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl
index 382e384..8a0400c 100644
--- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl
+++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl
@@ -23,7 +23,9 @@
  */
 
 // For real-time audio stream synthesis/processing in JavaScript
-interface ScriptProcessorNode : AudioNode {
+[
+    DependentLifetime
+]interface ScriptProcessorNode : AudioNode {
     // Rendering callback
     attribute EventHandler onaudioprocess;
 
diff --git a/third_party/WebKit/Source/modules/worklet/DOMWindowWorklet.cpp b/third_party/WebKit/Source/modules/worklet/DOMWindowWorklet.cpp
index 34c6e5c8..07a4a32d 100644
--- a/third_party/WebKit/Source/modules/worklet/DOMWindowWorklet.cpp
+++ b/third_party/WebKit/Source/modules/worklet/DOMWindowWorklet.cpp
@@ -42,7 +42,7 @@
 Worklet* DOMWindowWorklet::renderWorklet(ExecutionContext* executionContext) const
 {
     if (!m_renderWorklet && frame())
-        m_renderWorklet = Worklet::create(executionContext);
+        m_renderWorklet = Worklet::create(frame(), executionContext);
     return m_renderWorklet.get();
 }
 
diff --git a/third_party/WebKit/Source/modules/worklet/Worklet.cpp b/third_party/WebKit/Source/modules/worklet/Worklet.cpp
index 4218b58..647ee587 100644
--- a/third_party/WebKit/Source/modules/worklet/Worklet.cpp
+++ b/third_party/WebKit/Source/modules/worklet/Worklet.cpp
@@ -10,20 +10,21 @@
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
+#include "modules/worklet/WorkletGlobalScope.h"
 
 namespace blink {
 
 // static
-Worklet* Worklet::create(ExecutionContext* executionContext)
+Worklet* Worklet::create(LocalFrame* frame, ExecutionContext* executionContext)
 {
-    Worklet* worklet = new Worklet(executionContext);
+    Worklet* worklet = new Worklet(frame, executionContext);
     worklet->suspendIfNeeded();
     return worklet;
 }
 
-Worklet::Worklet(ExecutionContext* executionContext)
+Worklet::Worklet(LocalFrame* frame, ExecutionContext* executionContext)
     : ActiveDOMObject(executionContext)
-    , m_workletGlobalScope(WorkletGlobalScope::create(executionContext->url(), executionContext->userAgent(), executionContext->securityOrigin(), toIsolate(executionContext)))
+    , m_workletGlobalScope(WorkletGlobalScope::create(frame, executionContext->url(), executionContext->userAgent(), executionContext->securityOrigin(), toIsolate(executionContext)))
 {
 }
 
diff --git a/third_party/WebKit/Source/modules/worklet/Worklet.h b/third_party/WebKit/Source/modules/worklet/Worklet.h
index 91f7f2e..5fda297 100644
--- a/third_party/WebKit/Source/modules/worklet/Worklet.h
+++ b/third_party/WebKit/Source/modules/worklet/Worklet.h
@@ -26,7 +26,7 @@
 public:
     // The ExecutionContext argument is the parent document of the Worklet. The
     // Worklet inherits the url and userAgent, from the document.
-    static Worklet* create(ExecutionContext*);
+    static Worklet* create(LocalFrame*, ExecutionContext*);
 
     ScriptPromise import(ScriptState*, const String& url);
 
@@ -36,7 +36,7 @@
     DECLARE_TRACE();
 
 private:
-    explicit Worklet(ExecutionContext*);
+    Worklet(LocalFrame*, ExecutionContext*);
 
     void onResponse();
     void onFinished(WorkerScriptLoader*, ScriptPromiseResolver*);
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletConsole.cpp b/third_party/WebKit/Source/modules/worklet/WorkletConsole.cpp
new file mode 100644
index 0000000..9d9bf7f
--- /dev/null
+++ b/third_party/WebKit/Source/modules/worklet/WorkletConsole.cpp
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/worklet/WorkletConsole.h"
+
+#include "core/inspector/ConsoleMessage.h"
+#include "modules/worklet/WorkletGlobalScope.h"
+
+
+namespace blink {
+
+WorkletConsole::WorkletConsole(WorkletGlobalScope* scope)
+    : m_scope(scope)
+{
+}
+
+WorkletConsole::~WorkletConsole()
+{
+}
+
+void WorkletConsole::reportMessageToConsole(PassRefPtrWillBeRawPtr<ConsoleMessage> consoleMessage)
+{
+    m_scope->addConsoleMessage(consoleMessage);
+}
+
+ExecutionContext* WorkletConsole::context()
+{
+    if (!m_scope)
+        return nullptr;
+    return m_scope;
+}
+
+DEFINE_TRACE(WorkletConsole)
+{
+    visitor->trace(m_scope);
+    ConsoleBase::trace(visitor);
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletConsole.h b/third_party/WebKit/Source/modules/worklet/WorkletConsole.h
new file mode 100644
index 0000000..c79f0cb
--- /dev/null
+++ b/third_party/WebKit/Source/modules/worklet/WorkletConsole.h
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WorkletConsole_h
+#define WorkletConsole_h
+
+#include "core/frame/ConsoleBase.h"
+#include "core/frame/ConsoleTypes.h"
+#include "core/inspector/ConsoleAPITypes.h"
+#include "platform/heap/Handle.h"
+
+namespace blink {
+
+class ConsoleMessage;
+class WorkletGlobalScope;
+
+class WorkletConsole final : public ConsoleBase {
+    DEFINE_WRAPPERTYPEINFO();
+public:
+    static WorkletConsole* create(WorkletGlobalScope* scope)
+    {
+        return new WorkletConsole(scope);
+    }
+    ~WorkletConsole() override;
+
+    DECLARE_VIRTUAL_TRACE();
+
+protected:
+    ExecutionContext* context() final;
+    void reportMessageToConsole(PassRefPtrWillBeRawPtr<ConsoleMessage>) final;
+
+private:
+    explicit WorkletConsole(WorkletGlobalScope*);
+
+    RawPtrWillBeMember<WorkletGlobalScope> m_scope;
+};
+
+} // namespace blink
+
+#endif // WorkletConsole_h
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletConsole.idl b/third_party/WebKit/Source/modules/worklet/WorkletConsole.idl
new file mode 100644
index 0000000..04fe98c
--- /dev/null
+++ b/third_party/WebKit/Source/modules/worklet/WorkletConsole.idl
@@ -0,0 +1,14 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Console API
+// https://console.spec.whatwg.org/#console-interface
+
+// TODO(ikilpatrick): Console object shouldn't inherit from ConsoleBase.
+
+[
+    Exposed=Worklet,
+    NoInterfaceObject,
+] interface WorkletConsole : ConsoleBase {
+};
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp
index d2b4b20..833e715 100644
--- a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp
@@ -5,19 +5,23 @@
 #include "modules/worklet/WorkletGlobalScope.h"
 
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
+#include "core/frame/FrameConsole.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "modules/worklet/WorkletConsole.h"
 
 namespace blink {
 
 // static
-PassRefPtrWillBeRawPtr<WorkletGlobalScope> WorkletGlobalScope::create(const KURL& url, const String& userAgent, PassRefPtr<SecurityOrigin> securityOrigin, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<WorkletGlobalScope> WorkletGlobalScope::create(LocalFrame* frame, const KURL& url, const String& userAgent, PassRefPtr<SecurityOrigin> securityOrigin, v8::Isolate* isolate)
 {
-    RefPtrWillBeRawPtr<WorkletGlobalScope> workletGlobalScope = adoptRefWillBeNoop(new WorkletGlobalScope(url, userAgent, securityOrigin, isolate));
+    RefPtrWillBeRawPtr<WorkletGlobalScope> workletGlobalScope = adoptRefWillBeNoop(new WorkletGlobalScope(frame, url, userAgent, securityOrigin, isolate));
     workletGlobalScope->scriptController()->initializeContextIfNeeded();
     return workletGlobalScope.release();
 }
 
-WorkletGlobalScope::WorkletGlobalScope(const KURL& url, const String& userAgent, PassRefPtr<SecurityOrigin> securityOrigin, v8::Isolate* isolate)
-    : m_url(url)
+WorkletGlobalScope::WorkletGlobalScope(LocalFrame* frame, const KURL& url, const String& userAgent, PassRefPtr<SecurityOrigin> securityOrigin, v8::Isolate* isolate)
+    : LocalFrameLifecycleObserver(frame)
+    , m_url(url)
     , m_userAgent(userAgent)
     , m_scriptController(WorkerOrWorkletScriptController::create(this, isolate))
 {
@@ -28,6 +32,13 @@
 {
 }
 
+WorkletConsole* WorkletGlobalScope::console()
+{
+    if (!m_console)
+        m_console = WorkletConsole::create(this);
+    return m_console.get();
+}
+
 v8::Local<v8::Object> WorkletGlobalScope::wrap(v8::Isolate*, v8::Local<v8::Object> creationContext)
 {
     // WorkletGlobalScope must never be wrapped with wrap method. The global
@@ -58,6 +69,25 @@
     return false;
 }
 
+void WorkletGlobalScope::reportBlockedScriptExecutionToInspector(const String& directiveText)
+{
+    InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
+}
+
+void WorkletGlobalScope::addConsoleMessage(PassRefPtrWillBeRawPtr<ConsoleMessage> prpConsoleMessage)
+{
+    RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = prpConsoleMessage;
+    frame()->console().addMessage(consoleMessage.release());
+}
+
+void WorkletGlobalScope::logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+{
+    RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber);
+    consoleMessage->setScriptId(scriptId);
+    consoleMessage->setCallStack(callStack);
+    addConsoleMessage(consoleMessage.release());
+}
+
 KURL WorkletGlobalScope::virtualCompleteURL(const String& url) const
 {
     // Always return a null URL when passed a null string.
@@ -72,8 +102,10 @@
 DEFINE_TRACE(WorkletGlobalScope)
 {
     visitor->trace(m_scriptController);
+    visitor->trace(m_console);
     ExecutionContext::trace(visitor);
     SecurityContext::trace(visitor);
+    LocalFrameLifecycleObserver::trace(visitor);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h
index 007f9e1..2546c2f 100644
--- a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h
+++ b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h
@@ -10,6 +10,7 @@
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/ExecutionContextTask.h"
 #include "core/dom/SecurityContext.h"
+#include "core/frame/LocalFrameLifecycleObserver.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/workers/WorkerOrWorkletGlobalScope.h"
 #include "platform/heap/Handle.h"
@@ -17,9 +18,11 @@
 namespace blink {
 
 class EventQueue;
+class LocalFrame;
 class WorkerOrWorkletScriptController;
+class WorkletConsole;
 
-class WorkletGlobalScope : public RefCountedWillBeGarbageCollectedFinalized<WorkletGlobalScope>, public SecurityContext, public WorkerOrWorkletGlobalScope, public ScriptWrappable {
+class WorkletGlobalScope : public RefCountedWillBeGarbageCollectedFinalized<WorkletGlobalScope>, public SecurityContext, public WorkerOrWorkletGlobalScope, public ScriptWrappable, public LocalFrameLifecycleObserver {
     DEFINE_WRAPPERTYPEINFO();
     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WorkletGlobalScope);
 public:
@@ -30,11 +33,13 @@
 
     // The url, userAgent and securityOrigin arguments are inherited from the
     // parent ExecutionContext for Worklets.
-    static PassRefPtrWillBeRawPtr<WorkletGlobalScope> create(const KURL&, const String& userAgent, PassRefPtr<SecurityOrigin>, v8::Isolate*);
+    static PassRefPtrWillBeRawPtr<WorkletGlobalScope> create(LocalFrame*, const KURL&, const String& userAgent, PassRefPtr<SecurityOrigin>, v8::Isolate*);
     ~WorkletGlobalScope() override;
 
     bool isWorkletGlobalScope() const final { return true; }
 
+    // WorkletGlobalScope
+    WorkletConsole* console();
 
     // WorkerOrWorkletGlobalScope
     ScriptWrappable* scriptWrappable() const final { return const_cast<WorkletGlobalScope*>(this); }
@@ -61,10 +66,9 @@
         ASSERT_NOT_REACHED();
     }
 
-    // TODO(ikilpatrick): implement when we implement devtools support.
-    void reportBlockedScriptExecutionToInspector(const String& directiveText) final { }
-    void addConsoleMessage(PassRefPtrWillBeRawPtr<ConsoleMessage>) final { }
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) final { }
+    void reportBlockedScriptExecutionToInspector(const String& directiveText) final;
+    void addConsoleMessage(PassRefPtrWillBeRawPtr<ConsoleMessage>) final;
+    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) final;
 
     DECLARE_VIRTUAL_TRACE();
 
@@ -74,7 +78,7 @@
     void derefExecutionContext() final { deref(); }
 #endif
 
-    WorkletGlobalScope(const KURL&, const String& userAgent, PassRefPtr<SecurityOrigin>, v8::Isolate*);
+    WorkletGlobalScope(LocalFrame*, const KURL&, const String& userAgent, PassRefPtr<SecurityOrigin>, v8::Isolate*);
 
     const KURL& virtualURL() const final { return m_url; }
     KURL virtualCompleteURL(const String&) const final;
@@ -82,6 +86,8 @@
     EventTarget* errorEventTarget() final { return nullptr; }
     void didUpdateSecurityOrigin() final { }
 
+    mutable PersistentWillBeMember<WorkletConsole> m_console;
+
     KURL m_url;
     String m_userAgent;
     OwnPtrWillBeMember<WorkerOrWorkletScriptController> m_scriptController;
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.idl b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.idl
index f3ceb1e0..de3c3470 100644
--- a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.idl
+++ b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.idl
@@ -10,4 +10,5 @@
     RuntimeEnabled=Worklet,
     WillBeGarbageCollected,
 ] interface WorkletGlobalScope {
+    [Replaceable] readonly attribute WorkletConsole console;
 };
diff --git a/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp b/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp
index 4f0a8b4e..1102c6c8 100644
--- a/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp
+++ b/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp
@@ -32,12 +32,12 @@
 
 namespace blink {
 
-PassOwnPtr<ContentSettingCallbacks> ContentSettingCallbacks::create(PassOwnPtr<Closure> allowed, PassOwnPtr<Closure> denied)
+PassOwnPtr<ContentSettingCallbacks> ContentSettingCallbacks::create(PassOwnPtr<SameThreadClosure> allowed, PassOwnPtr<SameThreadClosure> denied)
 {
     return adoptPtr(new ContentSettingCallbacks(std::move(allowed), std::move(denied)));
 }
 
-ContentSettingCallbacks::ContentSettingCallbacks(PassOwnPtr<Closure> allowed, PassOwnPtr<Closure> denied)
+ContentSettingCallbacks::ContentSettingCallbacks(PassOwnPtr<SameThreadClosure> allowed, PassOwnPtr<SameThreadClosure> denied)
     : m_allowed(std::move(allowed))
     , m_denied(std::move(denied))
 {
diff --git a/third_party/WebKit/Source/platform/ContentSettingCallbacks.h b/third_party/WebKit/Source/platform/ContentSettingCallbacks.h
index 2252aa7..52dd4c5 100644
--- a/third_party/WebKit/Source/platform/ContentSettingCallbacks.h
+++ b/third_party/WebKit/Source/platform/ContentSettingCallbacks.h
@@ -18,17 +18,17 @@
     USING_FAST_MALLOC(ContentSettingCallbacks);
     WTF_MAKE_NONCOPYABLE(ContentSettingCallbacks);
 public:
-    static PassOwnPtr<ContentSettingCallbacks> create(PassOwnPtr<Closure> allowed, PassOwnPtr<Closure> denied);
+    static PassOwnPtr<ContentSettingCallbacks> create(PassOwnPtr<SameThreadClosure> allowed, PassOwnPtr<SameThreadClosure> denied);
     virtual ~ContentSettingCallbacks() { }
 
     void onAllowed() { (*m_allowed)(); }
     void onDenied() { (*m_denied)(); }
 
 private:
-    ContentSettingCallbacks(PassOwnPtr<Closure> allowed, PassOwnPtr<Closure> denied);
+    ContentSettingCallbacks(PassOwnPtr<SameThreadClosure> allowed, PassOwnPtr<SameThreadClosure> denied);
 
-    OwnPtr<Closure> m_allowed;
-    OwnPtr<Closure> m_denied;
+    OwnPtr<SameThreadClosure> m_allowed;
+    OwnPtr<SameThreadClosure> m_denied;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 55b0cb6b..bd06d46 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -67,8 +67,6 @@
 ForceDisplayList2dCanvas
 // See crbug.com/585250.
 ForceDisable2dCanvasCopyOnWrite
-// See https://crbug.com/582618.
-EncryptedMedia status=stable
 ExecCommandInJavaScript status=test
 ComputedAccessibilityInfo status=experimental
 EventListenerOptions status=stable
@@ -117,8 +115,7 @@
 MediaDevices status=stable
 MediaRecorder status=stable
 MediaSession
-MediaSource status=stable
-MediaSourceExperimental depends_on=MediaSource, status=experimental
+MediaSourceExperimental status=experimental
 MediaStreamSpeech status=experimental
 MemoryInfoInWorkers status=experimental
 MobileLayoutTheme
diff --git a/third_party/WebKit/Source/platform/Task.h b/third_party/WebKit/Source/platform/Task.h
index 64b656c..e404408 100644
--- a/third_party/WebKit/Source/platform/Task.h
+++ b/third_party/WebKit/Source/platform/Task.h
@@ -40,11 +40,16 @@
 
 namespace blink {
 
-class Task : public WebTaskRunner::Task {
-    USING_FAST_MALLOC(Task);
-    WTF_MAKE_NONCOPYABLE(Task);
+// Please use WTF::SameThreadClosure or WTF::CrossThreadClosure directly,
+// instead of wrapping them by blink::SameThreadTask/CrossThreadTask here.
+
+// TODO(hiroshige): Make these classes internal to
+// Source/platform/WebTaskRunner.cpp.
+class SameThreadTask : public WebTaskRunner::Task {
+    USING_FAST_MALLOC(SameThreadTask);
+    WTF_MAKE_NONCOPYABLE(SameThreadTask);
 public:
-    explicit Task(PassOwnPtr<Closure> closure)
+    explicit SameThreadTask(PassOwnPtr<SameThreadClosure> closure)
         : m_closure(std::move(closure))
     {
     }
@@ -55,7 +60,25 @@
     }
 
 private:
-    OwnPtr<Closure> m_closure;
+    OwnPtr<SameThreadClosure> m_closure;
+};
+
+class CrossThreadTask : public WebTaskRunner::Task {
+    USING_FAST_MALLOC(CrossThreadTask);
+    WTF_MAKE_NONCOPYABLE(CrossThreadTask);
+public:
+    explicit CrossThreadTask(PassOwnPtr<CrossThreadClosure> closure)
+        : m_closure(std::move(closure))
+    {
+    }
+
+    void run() override
+    {
+        (*m_closure)();
+    }
+
+private:
+    OwnPtr<CrossThreadClosure> m_closure;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/ThreadSafeFunctional.h b/third_party/WebKit/Source/platform/ThreadSafeFunctional.h
index b8f9c1e..855cdb5 100644
--- a/third_party/WebKit/Source/platform/ThreadSafeFunctional.h
+++ b/third_party/WebKit/Source/platform/ThreadSafeFunctional.h
@@ -27,11 +27,12 @@
 //     bind(func1, 42, str.isolatedCopy());
 
 template<typename... FreeVariableTypes, typename FunctionType, typename... Ps>
-PassOwnPtr<Function<typename WTF::FunctionWrapper<FunctionType>::ResultType(FreeVariableTypes...)>> threadSafeBind(
+PassOwnPtr<Function<typename WTF::FunctionWrapper<FunctionType>::ResultType(FreeVariableTypes...), WTF::CrossThreadAffinity>> threadSafeBind(
     FunctionType function,
     const Ps&... parameters)
 {
-    return bind<FreeVariableTypes...>(function,
+    return WTF::bindInternal<WTF::CrossThreadAffinity, FreeVariableTypes...>(
+        function,
         CrossThreadCopier<Ps>::copy(parameters)...);
 }
 
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.cpp b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
index e44dc1c..1d2f7978 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
@@ -8,19 +8,24 @@
 
 namespace blink {
 
-void WebTaskRunner::postTask(const WebTraceLocation& location, PassOwnPtr<ClosureTask> task)
+void WebTaskRunner::postTask(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
 {
-    postTask(std::move(location), new blink::Task(std::move(task)));
+    postTask(location, new CrossThreadTask(std::move(task)));
 }
 
-void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, PassOwnPtr <ClosureTask> task, long long delayMs)
+void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task, long long delayMs)
 {
-    postDelayedTask(location, new blink::Task(std::move(task)), delayMs);
+    postDelayedTask(location, new CrossThreadTask(std::move(task)), delayMs);
 }
 
-void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, PassOwnPtr <ClosureTask> task, double delayMs)
+void WebTaskRunner::postTask(const WebTraceLocation& location, PassOwnPtr<SameThreadClosure> task)
 {
-    postDelayedTask(location, new blink::Task(std::move(task)), delayMs);
+    postTask(location, new SameThreadTask(std::move(task)));
+}
+
+void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, PassOwnPtr <SameThreadClosure> task, long long delayMs)
+{
+    postDelayedTask(location, new SameThreadTask(std::move(task)), delayMs);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
index cc69582..32ea91a 100644
--- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
+++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -33,12 +33,22 @@
     static PassOwnPtr<WebThreadSupportingGC> createForThread(WebThread*);
     ~WebThreadSupportingGC();
 
-    void postTask(const WebTraceLocation& location, PassOwnPtr<Closure> task)
+    void postTask(const WebTraceLocation& location, PassOwnPtr<SameThreadClosure> task)
     {
         m_thread->getWebTaskRunner()->postTask(location, task);
     }
 
-    void postDelayedTask(const WebTraceLocation& location, PassOwnPtr<Closure> task, long long delayMs)
+    void postDelayedTask(const WebTraceLocation& location, PassOwnPtr<SameThreadClosure> task, long long delayMs)
+    {
+        m_thread->getWebTaskRunner()->postDelayedTask(location, task, delayMs);
+    }
+
+    void postTask(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task)
+    {
+        m_thread->getWebTaskRunner()->postTask(location, task);
+    }
+
+    void postDelayedTask(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> task, long long delayMs)
     {
         m_thread->getWebTaskRunner()->postDelayedTask(location, task, delayMs);
     }
diff --git a/third_party/WebKit/Source/platform/fonts/FontCache.cpp b/third_party/WebKit/Source/platform/fonts/FontCache.cpp
index cb658d8e..593d819 100644
--- a/third_party/WebKit/Source/platform/fonts/FontCache.cpp
+++ b/third_party/WebKit/Source/platform/fonts/FontCache.cpp
@@ -59,12 +59,13 @@
 
 namespace blink {
 
-#if !OS(WIN)
+#if !OS(WIN) && !OS(LINUX)
 FontCache::FontCache()
     : m_purgePreventCount(0)
+    , m_fontManager(nullptr)
 {
 }
-#endif // !OS(WIN)
+#endif // !OS(WIN) && !OS(LINUX)
 
 typedef HashMap<FontCacheKey, OwnPtr<FontPlatformData>, FontCacheKeyHash, FontCacheKeyTraits> FontPlatformDataCache;
 typedef HashMap<FallbackListCompositeKey, OwnPtr<ShapeCache>, FallbackListCompositeKeyHash, FallbackListCompositeKeyTraits> FallbackListShaperCache;
@@ -72,9 +73,12 @@
 static FontPlatformDataCache* gFontPlatformDataCache = nullptr;
 static FallbackListShaperCache* gFallbackListShaperCache = nullptr;
 
+SkFontMgr* FontCache::s_fontManager = nullptr;
+
 #if OS(WIN)
 bool FontCache::s_useDirectWrite = false;
-SkFontMgr* FontCache::s_fontManager = nullptr;
+bool FontCache::s_antialiasedTextEnabled = false;
+bool FontCache::s_lcdTextEnabled = false;
 bool FontCache::s_useSubpixelPositioning = false;
 float FontCache::s_deviceScaleFactor = 1.0;
 #endif // OS(WIN)
@@ -148,7 +152,6 @@
     return fontVerticalDataCache;
 }
 
-#if OS(WIN)
 void FontCache::setFontManager(const RefPtr<SkFontMgr>& fontManager)
 {
     ASSERT(!s_fontManager);
@@ -156,7 +159,6 @@
     // Explicitly AddRef since we're going to hold on to the object for the life of the program.
     s_fontManager->ref();
 }
-#endif
 
 PassRefPtr<OpenTypeVerticalData> FontCache::getVerticalData(const FontFileKey& key, const FontPlatformData& platformData)
 {
diff --git a/third_party/WebKit/Source/platform/fonts/FontCache.h b/third_party/WebKit/Source/platform/fonts/FontCache.h
index 6d72b401..0c20a056 100644
--- a/third_party/WebKit/Source/platform/fonts/FontCache.h
+++ b/third_party/WebKit/Source/platform/fonts/FontCache.h
@@ -45,9 +45,7 @@
 #include "wtf/text/WTFString.h"
 #include <limits.h>
 
-#if OS(WIN)
 #include "SkFontMgr.h"
-#endif
 
 class SkTypeface;
 
@@ -104,13 +102,18 @@
     unsigned short generation();
     void invalidate();
 
+    SkFontMgr* fontManager() { return m_fontManager.get(); }
+    static void setFontManager(const RefPtr<SkFontMgr>&);
+
 #if OS(WIN)
     bool useSubpixelPositioning() const { return s_useSubpixelPositioning; }
-    SkFontMgr* fontManager() { return m_fontManager.get(); }
     static bool useDirectWrite() { return s_useDirectWrite; }
+    static bool antialiasedTextEnabled() { return s_antialiasedTextEnabled; }
+    static bool lcdTextEnabled() { return s_lcdTextEnabled; }
     static float deviceScaleFactor() { return s_deviceScaleFactor; }
     static void setUseDirectWrite(bool useDirectWrite) { s_useDirectWrite = useDirectWrite; }
-    static void setFontManager(const RefPtr<SkFontMgr>&);
+    static void setAntialiasedTextEnabled(bool enabled) { s_antialiasedTextEnabled = enabled; }
+    static void setLCDTextEnabled(bool enabled) { s_lcdTextEnabled = enabled; }
     static void setDeviceScaleFactor(float deviceScaleFactor) { s_deviceScaleFactor = deviceScaleFactor; }
     static void addSideloadedFontForTesting(SkTypeface*);
     // Functions to cache and retrieve the system font metrics.
@@ -174,15 +177,23 @@
     // Implemented on skia platforms.
     PassRefPtr<SkTypeface> createTypeface(const FontDescription&, const FontFaceCreationParams&, CString& name);
 
+#if OS(ANDROID) || OS(LINUX)
+    static AtomicString getFamilyNameForCharacter(SkFontMgr*, UChar32, const FontDescription&, FontFallbackPriority);
+#endif
+
     PassRefPtr<SimpleFontData> fallbackOnStandardFontStyle(const FontDescription&, UChar32);
 
     // Don't purge if this count is > 0;
     int m_purgePreventCount;
 
-#if OS(WIN)
     RefPtr<SkFontMgr> m_fontManager;
-    static bool s_useDirectWrite;
+
     static SkFontMgr* s_fontManager;
+
+#if OS(WIN)
+    static bool s_useDirectWrite;
+    static bool s_antialiasedTextEnabled;
+    static bool s_lcdTextEnabled;
     static float s_deviceScaleFactor;
     static bool s_useSubpixelPositioning;
     static HashMap<String, RefPtr<SkTypeface>>* s_sideloadedFonts;
diff --git a/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp b/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp
index 325fe2c..83c8b7d3 100644
--- a/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp
+++ b/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp
@@ -31,7 +31,6 @@
 #include "platform/fonts/FontCache.h"
 
 #include "platform/Language.h"
-#include "platform/fonts/AcceptLanguagesResolver.h"
 #include "platform/fonts/SimpleFontData.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/FontFaceCreationParams.h"
@@ -41,61 +40,10 @@
 
 namespace blink {
 
-// Android special locale for retrieving the color emoji font
-// based on the proposed changes in UTR #51 for introducing
-// an Emoji script code:
-// http://www.unicode.org/reports/tr51/proposed.html#Emoji_Script
-static const char* kAndroidColorEmojiLocale = "und-Zsye";
-
-// SkFontMgr requires script-based locale names, like "zh-Hant" and "zh-Hans",
-// instead of "zh-CN" and "zh-TW".
-static CString toSkFontMgrLocale(const String& locale)
-{
-    if (!locale.startsWith("zh", TextCaseInsensitive))
-        return locale.ascii();
-
-    switch (localeToScriptCodeForFontSelection(locale)) {
-    case USCRIPT_SIMPLIFIED_HAN:
-        return "zh-Hans";
-    case USCRIPT_TRADITIONAL_HAN:
-        return "zh-Hant";
-    default:
-        return locale.ascii();
-    }
-}
-
-static AtomicString getFamilyNameForCharacter(UChar32 c, const FontDescription& fontDescription, FontFallbackPriority fallbackPriority)
-{
-    const size_t kMaxLocales = 4;
-    RefPtr<SkFontMgr> fm = adoptRef(SkFontMgr::RefDefault());
-    const char* bcp47Locales[kMaxLocales];
-    size_t localeCount = 0;
-
-    if (fallbackPriority == FontFallbackPriority::EmojiEmoji) {
-        bcp47Locales[localeCount++] = kAndroidColorEmojiLocale;
-    }
-    if (const char* hanLocale = AcceptLanguagesResolver::preferredHanSkFontMgrLocale())
-        bcp47Locales[localeCount++] = hanLocale;
-    CString defaultLocale = toSkFontMgrLocale(defaultLanguage());
-    bcp47Locales[localeCount++] = defaultLocale.data();
-    CString fontLocale;
-    if (!fontDescription.locale().isEmpty()) {
-        fontLocale = toSkFontMgrLocale(fontDescription.locale());
-        bcp47Locales[localeCount++] = fontLocale.data();
-    }
-    ASSERT_WITH_SECURITY_IMPLICATION(localeCount < kMaxLocales);
-    RefPtr<SkTypeface> typeface = adoptRef(fm->matchFamilyStyleCharacter(0, SkFontStyle(), bcp47Locales, localeCount, c));
-    if (!typeface)
-        return emptyAtom;
-
-    SkString skiaFamilyName;
-    typeface->getFamilyName(&skiaFamilyName);
-    return skiaFamilyName.c_str();
-}
-
 PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*, FontFallbackPriority fallbackPriority)
 {
-    AtomicString familyName = getFamilyNameForCharacter(c, fontDescription, fallbackPriority);
+    RefPtr<SkFontMgr> fm = adoptRef(SkFontMgr::RefDefault());
+    AtomicString familyName = getFamilyNameForCharacter(fm.get(), c, fontDescription, fallbackPriority);
     if (familyName.isEmpty())
         return getLastResortFallbackFont(fontDescription, DoNotRetain);
     return fontDataFromFontPlatformData(getFontPlatformData(fontDescription, FontFaceCreationParams(familyName)), DoNotRetain);
@@ -121,7 +69,8 @@
         return familyName;
     }
 
-    return getFamilyNameForCharacter(examplerChar, fontDescription, FontFallbackPriority::Text);
+    RefPtr<SkFontMgr> fm = adoptRef(SkFontMgr::RefDefault());
+    return getFamilyNameForCharacter(fm.get(), examplerChar, fontDescription, FontFallbackPriority::Text);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp b/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
index 9dad8c8..d881c69 100644
--- a/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
+++ b/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
@@ -34,6 +34,17 @@
 
 namespace blink {
 
+FontCache::FontCache()
+    : m_purgePreventCount(0)
+{
+    if (s_fontManager) {
+        adopted(s_fontManager);
+        m_fontManager = s_fontManager;
+    } else {
+        m_fontManager = nullptr;
+    }
+}
+
 void FontCache::getFontForCharacter(UChar32 c, const char* preferredLocale, FontCache::PlatformFallbackFont* fallbackFont)
 {
     WebFallbackFont webFallbackFont;
@@ -56,6 +67,17 @@
     const SimpleFontData*,
     FontFallbackPriority fallbackPriority)
 {
+    // The m_fontManager is set only if it was provided by the embedder with WebFontRendering::setSkiaFontManager. This is
+    // used to emulate android fonts on linux so we always request the family from the font manager and if none is found, we return
+    // the LastResort fallback font and avoid using FontCache::getFontForCharacter which would use sandbox support to
+    // query the underlying system for the font family.
+    if (m_fontManager) {
+        AtomicString familyName = getFamilyNameForCharacter(m_fontManager.get(), c, fontDescription, fallbackPriority);
+        if (familyName.isEmpty())
+            return getLastResortFallbackFont(fontDescription, DoNotRetain);
+        return fontDataFromFontPlatformData(getFontPlatformData(fontDescription, FontFaceCreationParams(familyName)), DoNotRetain);
+    }
+
     if (fallbackPriority == FontFallbackPriority::EmojiEmoji) {
         // FIXME crbug.com/591346: We're overriding the fallback character here
         // with the FAMILY emoji in the hope to find a suitable emoji font.
diff --git a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp
index b0acb93..503e8e49 100644
--- a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp
+++ b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp
@@ -31,6 +31,8 @@
 #include "SkFontMgr.h"
 #include "SkStream.h"
 #include "SkTypeface.h"
+#include "platform/Language.h"
+#include "platform/fonts/AcceptLanguagesResolver.h"
 #include "platform/fonts/AlternateFontFamily.h"
 #include "platform/fonts/FontCache.h"
 #include "platform/fonts/FontDescription.h"
@@ -58,6 +60,64 @@
 
 namespace blink {
 
+#if OS(ANDROID) || OS(LINUX)
+// Android special locale for retrieving the color emoji font
+// based on the proposed changes in UTR #51 for introducing
+// an Emoji script code:
+// http://www.unicode.org/reports/tr51/proposed.html#Emoji_Script
+static const char* kAndroidColorEmojiLocale = "und-Zsye";
+
+// SkFontMgr requires script-based locale names, like "zh-Hant" and "zh-Hans",
+// instead of "zh-CN" and "zh-TW".
+static CString toSkFontMgrLocale(const String& locale)
+{
+    if (!locale.startsWith("zh", TextCaseInsensitive))
+        return locale.ascii();
+
+    switch (localeToScriptCodeForFontSelection(locale)) {
+    case USCRIPT_SIMPLIFIED_HAN:
+        return "zh-Hans";
+    case USCRIPT_TRADITIONAL_HAN:
+        return "zh-Hant";
+    default:
+        return locale.ascii();
+    }
+}
+
+// This function is called on android or when we are emulating android fonts on linux and the
+// embedder has overriden the default fontManager with WebFontRendering::setSkiaFontMgr.
+// static
+AtomicString FontCache::getFamilyNameForCharacter(SkFontMgr* fm, UChar32 c, const FontDescription& fontDescription, FontFallbackPriority fallbackPriority)
+{
+    ASSERT(fm);
+
+    const size_t kMaxLocales = 4;
+    const char* bcp47Locales[kMaxLocales];
+    size_t localeCount = 0;
+
+    if (fallbackPriority == FontFallbackPriority::EmojiEmoji) {
+        bcp47Locales[localeCount++] = kAndroidColorEmojiLocale;
+    }
+    if (const char* hanLocale = AcceptLanguagesResolver::preferredHanSkFontMgrLocale())
+        bcp47Locales[localeCount++] = hanLocale;
+    CString defaultLocale = toSkFontMgrLocale(defaultLanguage());
+    bcp47Locales[localeCount++] = defaultLocale.data();
+    CString fontLocale;
+    if (!fontDescription.locale().isEmpty()) {
+        fontLocale = toSkFontMgrLocale(fontDescription.locale());
+        bcp47Locales[localeCount++] = fontLocale.data();
+    }
+    ASSERT_WITH_SECURITY_IMPLICATION(localeCount < kMaxLocales);
+    RefPtr<SkTypeface> typeface = adoptRef(fm->matchFamilyStyleCharacter(0, SkFontStyle(), bcp47Locales, localeCount, c));
+    if (!typeface)
+        return emptyAtom;
+
+    SkString skiaFamilyName;
+    typeface->getFamilyName(&skiaFamilyName);
+    return skiaFamilyName.c_str();
+}
+#endif
+
 void FontCache::platformInit()
 {
 }
@@ -111,7 +171,7 @@
     return fontDataFromFontPlatformData(fontPlatformData, shouldRetain);
 }
 
-#if OS(WIN)
+#if OS(WIN) || OS(LINUX)
 static inline SkFontStyle fontStyle(const FontDescription& fontDescription)
 {
     int width = static_cast<int>(fontDescription.stretch());
@@ -172,6 +232,14 @@
     }
 #endif
 
+#if OS(LINUX)
+    // On linux if the fontManager has been overridden then we should be calling the embedder
+    // provided font Manager rather than calling SkTypeface::CreateFromName which may redirect the
+    // call to the default font Manager.
+    if (m_fontManager)
+        return adoptRef(m_fontManager->matchFamilyStyle(name.data(), fontStyle(fontDescription)));
+#endif
+
     // FIXME: Use m_fontManager, SkFontStyle and matchFamilyStyle instead of
     // CreateFromName on all platforms.
     return adoptRef(SkTypeface::CreateFromName(name.data(), static_cast<SkTypeface::Style>(style)));
diff --git a/third_party/WebKit/Source/platform/fonts/win/FontPlatformDataWin.cpp b/third_party/WebKit/Source/platform/fonts/win/FontPlatformDataWin.cpp
index 96dcd17..9e7e6c04 100644
--- a/third_party/WebKit/Source/platform/fonts/win/FontPlatformDataWin.cpp
+++ b/third_party/WebKit/Source/platform/fonts/win/FontPlatformDataWin.cpp
@@ -85,38 +85,6 @@
     paint->setFlags(flags);
 }
 
-// Lookup the current system settings for font smoothing.
-// We cache these values for performance, but if the browser has a way to be
-// notified when these change, we could re-query them at that time.
-static uint32_t getSystemTextFlags()
-{
-    static bool gInited;
-    static uint32_t gFlags;
-    if (!gInited) {
-        BOOL enabled;
-        gFlags = 0;
-        if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &enabled, 0)) {
-            if (enabled) {
-                gFlags |= SkPaint::kAntiAlias_Flag;
-
-                UINT smoothType;
-                if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smoothType, 0)) {
-                    if (FE_FONTSMOOTHINGCLEARTYPE == smoothType)
-                        gFlags |= SkPaint::kLCDRenderText_Flag;
-                }
-            }
-        } else {
-            // SystemParametersInfo will fail only under full sandbox lockdown on Win8+.
-            // So, we default to settings we know are supported and look good.
-            // FIXME(eae): We should be querying the DirectWrite settings directly
-            // so we can respect the settings for users who turn off smoothing.
-            gFlags = SkPaint::kAntiAlias_Flag | SkPaint::kLCDRenderText_Flag;
-        }
-        gInited = true;
-    }
-    return gFlags;
-}
-
 static bool isWebFont(const String& familyName)
 {
     // Web-fonts have artifical names constructed to always be:
@@ -131,7 +99,13 @@
     if (LayoutTestSupport::isRunningLayoutTest())
         return LayoutTestSupport::isFontAntialiasingEnabledForTest() ? SkPaint::kAntiAlias_Flag : 0;
 
-    int textFlags = getSystemTextFlags();
+    int textFlags = 0;
+    if (FontCache::fontCache()->antialiasedTextEnabled()) {
+        int lcdFlag = FontCache::fontCache()->lcdTextEnabled()
+            ? SkPaint::kLCDRenderText_Flag
+            : 0;
+        textFlags = SkPaint::kAntiAlias_Flag | lcdFlag;
+    }
 
     // Many web-fonts are so poorly hinted that they are terrible to read when drawn in BW.
     // In these cases, we have decided to FORCE these fonts to be drawn with at least grayscale AA,
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
index 327b27e..5ea2af0 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
@@ -170,7 +170,7 @@
     // Otherwise, bind to the default FBO.
     void restoreFramebufferBindings();
 
-    void addNewMailboxCallback(PassOwnPtr<Closure> closure) { m_newMailboxCallback = std::move(closure); }
+    void addNewMailboxCallback(PassOwnPtr<SameThreadClosure> closure) { m_newMailboxCallback = std::move(closure); }
 
 protected: // For unittests
     DrawingBuffer(
@@ -313,7 +313,7 @@
     };
     FrontBufferInfo m_frontColorBuffer;
 
-    OwnPtr<Closure> m_newMailboxCallback;
+    OwnPtr<SameThreadClosure> m_newMailboxCallback;
 
     // This is used when the user requests either a depth or stencil buffer.
     Platform3DObject m_depthStencilBuffer;
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index c676566..1dcd122 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -4995,21 +4995,21 @@
 
 TEST(HeapTest, Bind)
 {
-    OwnPtr<Closure> closure = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::trace), Bar::create(), static_cast<Visitor*>(0));
+    OwnPtr<SameThreadClosure> closure = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::trace), Bar::create(), static_cast<Visitor*>(0));
     preciselyCollectGarbage();
     // The closure should have a persistent handle to the Bar.
     EXPECT_EQ(1u, Bar::s_live);
 
-    OwnPtr<Closure> closure2 = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::trace), RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0));
+    OwnPtr<SameThreadClosure> closure2 = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::trace), RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0));
     preciselyCollectGarbage();
     // The closure should have a persistent handle to the Bar.
     EXPECT_EQ(2u, Bar::s_live);
     // RawPtr<OffHeapInt> should not make Persistent.
-    OwnPtr<Closure> closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt>(OffHeapInt::create(1).get()));
+    OwnPtr<SameThreadClosure> closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt>(OffHeapInt::create(1).get()));
 
     UseMixin::s_traceCount = 0;
     Mixin* mixin = UseMixin::create();
-    OwnPtr<Closure> mixinClosure = bind(static_cast<void (Mixin::*)(Visitor*)>(&Mixin::trace), mixin, static_cast<Visitor*>(0));
+    OwnPtr<SameThreadClosure> mixinClosure = bind(static_cast<void (Mixin::*)(Visitor*)>(&Mixin::trace), mixin, static_cast<Visitor*>(0));
     preciselyCollectGarbage();
     // The closure should have a persistent handle to the mixin.
     EXPECT_EQ(1, UseMixin::s_traceCount);
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 7567dff..01ed8598 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -205,7 +205,7 @@
 {
     RELEASE_ASSERT(!Heap::s_shutdownCalled);
     MutexLocker locker(threadAttachMutex());
-    ThreadState* state = new(s_mainThreadStateStorage) ThreadState();
+    ThreadState* state = new (s_mainThreadStateStorage) ThreadState();
     attachedThreads().add(state);
 }
 
@@ -216,6 +216,11 @@
     // threadAttachMutex and waiting for other threads to pause or reach a
     // safepoint.
     ThreadState* state = mainThreadState();
+    ASSERT(state == ThreadState::current());
+    ASSERT(state->checkThread());
+    // You must call unregisterTraceDOMWrappers before detaching
+    // the main thread.
+    ASSERT(!state->m_isolate);
 
     // 1. Finish sweeping.
     state->completeSweep();
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h
index 8fc7b9c..3337384 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.h
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -432,6 +432,11 @@
         m_isolate = isolate;
         m_traceDOMWrappers = traceDOMWrappers;
     }
+    void unregisterTraceDOMWrappers()
+    {
+        m_isolate = nullptr;
+        m_traceDOMWrappers = nullptr;
+    }
 
     // By entering a gc-forbidden scope, conservative GCs will not
     // be allowed while handling an out-of-line allocation request.
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/OWNERS b/third_party/WebKit/Source/platform/inspector_protocol/OWNERS
new file mode 100644
index 0000000..c34ad77
--- /dev/null
+++ b/third_party/WebKit/Source/platform/inspector_protocol/OWNERS
@@ -0,0 +1,5 @@
+alph@chromium.org
+caseq@chromium.org
+dgozman@chromium.org
+kozyatinskiy@chromium.org
+pfeldman@chromium.org
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
index 4eb2b8c..010c54e 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
@@ -102,9 +102,7 @@
     void mouseMovedInContentArea() const override;
     void mouseEnteredScrollbar(Scrollbar&) const override;
     void mouseExitedScrollbar(Scrollbar&) const override;
-    void willStartLiveResize() override;
     void contentsResized() const override;
-    void willEndLiveResize() override;
     void contentAreaDidShow() const override;
     void contentAreaDidHide() const override;
     void didBeginScrollGesture() const;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
index a711f32..97c0ec56 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -216,10 +216,7 @@
 
 - (BOOL)inLiveResizeForScrollerImpPair:(id)scrollerImpPair
 {
-    if (!_scrollableArea)
-        return NO;
-
-    return _scrollableArea->inLiveResize();
+    return NO;
 }
 
 - (NSPoint)mouseLocationInContentAreaForScrollerImpPair:(id)scrollerImpPair
@@ -848,13 +845,6 @@
         [painter mouseExitedScroller];
 }
 
-void ScrollAnimatorMac::willStartLiveResize()
-{
-    if (!scrollableArea()->scrollbarsCanBeActive())
-        return;
-    [m_scrollbarPainterController.get() startLiveResize];
-}
-
 void ScrollAnimatorMac::contentsResized() const
 {
     if (!scrollableArea()->scrollbarsCanBeActive())
@@ -862,13 +852,6 @@
     [m_scrollbarPainterController.get() contentAreaDidResize];
 }
 
-void ScrollAnimatorMac::willEndLiveResize()
-{
-    if (!scrollableArea()->scrollbarsCanBeActive())
-        return;
-    [m_scrollbarPainterController.get() endLiveResize];
-}
-
 void ScrollAnimatorMac::contentAreaDidShow() const
 {
     if (!scrollableArea()->scrollbarsCanBeActive())
@@ -921,8 +904,6 @@
 
     [painter setDelegate:m_verticalScrollbarPainterDelegate.get()];
     [m_scrollbarPainterController.get() setVerticalScrollerImp:painter];
-    if (scrollableArea()->inLiveResize())
-        [painter setKnobAlpha:1];
 }
 
 void ScrollAnimatorMac::willRemoveVerticalScrollbar(Scrollbar& scrollbar)
@@ -950,8 +931,6 @@
 
     [painter setDelegate:m_horizontalScrollbarPainterDelegate.get()];
     [m_scrollbarPainterController.get() setHorizontalScrollerImp:painter];
-    if (scrollableArea()->inLiveResize())
-        [painter setKnobAlpha:1];
 }
 
 void ScrollAnimatorMac::willRemoveHorizontalScrollbar(Scrollbar& scrollbar)
diff --git a/third_party/WebKit/Source/platform/platform_generated.gyp b/third_party/WebKit/Source/platform/platform_generated.gyp
index f809392..9b6f6558 100644
--- a/third_party/WebKit/Source/platform/platform_generated.gyp
+++ b/third_party/WebKit/Source/platform/platform_generated.gyp
@@ -142,6 +142,7 @@
           'action_name': 'CharacterData',
           'inputs': [
             'fonts/CharacterDataGenerator.cpp',
+            'fonts/CharacterData.h'
           ],
           'outputs': [
             '<(blink_platform_output_dir)/CharacterData.cpp',
diff --git a/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.cpp b/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.cpp
index ea46265..64b5b84 100644
--- a/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.cpp
+++ b/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.cpp
@@ -22,7 +22,7 @@
 void CancellableTaskFactory::CancellableTask::run()
 {
     if (CancellableTaskFactory* taskFactory = m_weakPtr.get()) {
-        Closure* closure = taskFactory->m_closure.get();
+        SameThreadClosure* closure = taskFactory->m_closure.get();
         taskFactory->m_weakPtrFactory.revokeAll();
         (*closure)();
     }
diff --git a/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.h b/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.h
index 46c26bd..8b54a781 100644
--- a/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.h
+++ b/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactory.h
@@ -29,7 +29,7 @@
     // CancellableTaskFactory, and one when that owning object isn't controlled
     // by Oilpan.
     //
-    // In the Oilpan case, as WTF::Closure objects are off-heap, we have to construct the
+    // In the Oilpan case, as WTF::SameThreadClosure objects are off-heap, we have to construct the
     // closure in such a manner that it doesn't end up referring back to the owning heap
     // object with a strong Persistent<> GC root reference. If we do, this will create
     // a heap <-> off-heap cycle and leak, the owning object can never be GCed.
@@ -62,7 +62,7 @@
 protected:
     // Only intended used by unit tests wanting to stack allocate and/or pass in a closure value.
     // Please use the create() factory method elsewhere.
-    explicit CancellableTaskFactory(PassOwnPtr<Closure> closure)
+    explicit CancellableTaskFactory(PassOwnPtr<SameThreadClosure> closure)
         : m_closure(std::move(closure))
         , m_weakPtrFactory(this)
     {
@@ -85,7 +85,7 @@
         WeakPtr<CancellableTaskFactory> m_weakPtr;
     };
 
-    OwnPtr<Closure> m_closure;
+    OwnPtr<SameThreadClosure> m_closure;
     WeakPtrFactory<CancellableTaskFactory> m_weakPtrFactory;
 };
 
diff --git a/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactoryTest.cpp b/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactoryTest.cpp
index 40ff9c4..694d61e 100644
--- a/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactoryTest.cpp
+++ b/third_party/WebKit/Source/platform/scheduler/CancellableTaskFactoryTest.cpp
@@ -12,7 +12,7 @@
 
 class TestCancellableTaskFactory final : public CancellableTaskFactory {
 public:
-    explicit TestCancellableTaskFactory(PassOwnPtr<Closure> closure)
+    explicit TestCancellableTaskFactory(PassOwnPtr<SameThreadClosure> closure)
         : CancellableTaskFactory(closure)
     {
     }
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
index 68d78057..d92ffac 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
@@ -92,10 +92,8 @@
     virtual void mouseMovedInContentArea() const { }
     virtual void mouseEnteredScrollbar(Scrollbar&) const { }
     virtual void mouseExitedScrollbar(Scrollbar&) const { }
-    virtual void willStartLiveResize() { }
     virtual void updateAfterLayout() { }
     virtual void contentsResized() const { }
-    virtual void willEndLiveResize() { }
     virtual void contentAreaDidShow() const { }
     virtual void contentAreaDidHide() const { }
 
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
index d4474d1..7c8e82d 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -80,8 +80,7 @@
 }
 
 ScrollableArea::ScrollableArea()
-    : m_inLiveResize(false)
-    , m_scrollbarOverlayStyle(ScrollbarOverlayStyleDefault)
+    : m_scrollbarOverlayStyle(ScrollbarOverlayStyleDefault)
     , m_scrollOriginChanged(false)
     , m_horizontalScrollbarNeedsPaintInvalidation(false)
     , m_verticalScrollbarNeedsPaintInvalidation(false)
@@ -309,24 +308,6 @@
     scrollPositionChanged(DoublePoint(offset), ProgrammaticScroll);
 }
 
-void ScrollableArea::willStartLiveResize()
-{
-    if (m_inLiveResize)
-        return;
-    m_inLiveResize = true;
-    if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
-        scrollAnimator->willStartLiveResize();
-}
-
-void ScrollableArea::willEndLiveResize()
-{
-    if (!m_inLiveResize)
-        return;
-    m_inLiveResize = false;
-    if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
-        scrollAnimator->willEndLiveResize();
-}
-
 void ScrollableArea::contentAreaWillPaint() const
 {
     if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index d11b6eb..527cb60c 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -101,10 +101,6 @@
 
     static bool scrollBehaviorFromString(const String&, ScrollBehavior&);
 
-    bool inLiveResize() const { return m_inLiveResize; }
-    void willStartLiveResize();
-    void willEndLiveResize();
-
     void contentAreaWillPaint() const;
     void mouseEnteredContentArea() const;
     void mouseExitedContentArea() const;
@@ -327,8 +323,6 @@
     mutable OwnPtrWillBeMember<ScrollAnimatorBase> m_scrollAnimator;
     mutable OwnPtrWillBeMember<ProgrammaticScrollAnimator> m_programmaticScrollAnimator;
 
-    unsigned m_inLiveResize : 1;
-
     unsigned m_scrollbarOverlayStyle : 2; // ScrollbarOverlayStyle
 
     unsigned m_scrollOriginChanged : 1;
diff --git a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp
index 8a757d4..c75e7e8 100644
--- a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp
+++ b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp
@@ -11,12 +11,12 @@
 
 namespace blink {
 
-static void RunBackgroundTask(PassOwnPtr<Closure> closure)
+static void RunBackgroundTask(PassOwnPtr<CrossThreadClosure> closure)
 {
     (*closure)();
 }
 
-void BackgroundTaskRunner::postOnBackgroundThread(const WebTraceLocation& location, PassOwnPtr<Closure> closure, TaskSize taskSize)
+void BackgroundTaskRunner::postOnBackgroundThread(const WebTraceLocation& location, PassOwnPtr<CrossThreadClosure> closure, TaskSize taskSize)
 {
     tracked_objects::Location baseLocation(location.functionName(), location.fileName(), 0, nullptr);
     base::WorkerPool::PostTask(baseLocation, base::Bind(&RunBackgroundTask, closure), taskSize == TaskSizeLongRunningTask);
diff --git a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h
index ed7b786f..95cdf79 100644
--- a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h
+++ b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h
@@ -20,7 +20,7 @@
     TaskSizeLongRunningTask,
 };
 
-PLATFORM_EXPORT void postOnBackgroundThread(const WebTraceLocation&, PassOwnPtr<Closure>, TaskSize);
+PLATFORM_EXPORT void postOnBackgroundThread(const WebTraceLocation&, PassOwnPtr<CrossThreadClosure>, TaskSize);
 
 } // BackgroundTaskRunner
 
diff --git a/third_party/WebKit/Source/platform/v8_inspector/OWNERS b/third_party/WebKit/Source/platform/v8_inspector/OWNERS
new file mode 100644
index 0000000..c34ad77
--- /dev/null
+++ b/third_party/WebKit/Source/platform/v8_inspector/OWNERS
@@ -0,0 +1,5 @@
+alph@chromium.org
+caseq@chromium.org
+dgozman@chromium.org
+kozyatinskiy@chromium.org
+pfeldman@chromium.org
diff --git a/third_party/WebKit/Source/web/WebFormElement.cpp b/third_party/WebKit/Source/web/WebFormElement.cpp
index fecc33b9..18a3511 100644
--- a/third_party/WebKit/Source/web/WebFormElement.cpp
+++ b/third_party/WebKit/Source/web/WebFormElement.cpp
@@ -62,11 +62,6 @@
     return constUnwrap<HTMLFormElement>()->method();
 }
 
-bool WebFormElement::wasUserSubmitted() const
-{
-    return constUnwrap<HTMLFormElement>()->wasUserSubmitted();
-}
-
 void WebFormElement::getNamedElements(const WebString& name,
                                       WebVector<WebNode>& result)
 {
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index b34b41e6..4f24ed0 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -152,12 +152,6 @@
     return m_size;
 }
 
-void WebFrameWidgetImpl::willStartLiveResize()
-{
-    if (m_localRoot->frameView())
-        m_localRoot->frameView()->willStartLiveResize();
-}
-
 void WebFrameWidgetImpl::resize(const WebSize& newSize)
 {
     if (m_size == newSize)
@@ -228,12 +222,6 @@
     m_ignoreInputEvents = newValue;
 }
 
-void WebFrameWidgetImpl::willEndLiveResize()
-{
-    if (m_localRoot->frameView())
-        m_localRoot->frameView()->willEndLiveResize();
-}
-
 void WebFrameWidgetImpl::didEnterFullScreen()
 {
     // FIXME: Implement full screen for out-of-process iframes.
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
index a9629b3..371f353f 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
@@ -71,10 +71,8 @@
     // WebWidget functions:
     void close() override;
     WebSize size() override;
-    void willStartLiveResize() override;
     void resize(const WebSize&) override;
     void resizeVisualViewport(const WebSize&) override;
-    void willEndLiveResize() override;
     void didEnterFullScreen() override;
     void didExitFullScreen() override;
     void beginFrame(double lastFrameTimeMonotonic) override;
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp
index 4a4e0ac..0b34d329 100644
--- a/third_party/WebKit/Source/web/WebKit.cpp
+++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -141,6 +141,12 @@
     v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size);
 }
 
+static ModulesInitializer& modulesInitializer()
+{
+    DEFINE_STATIC_LOCAL(OwnPtr<ModulesInitializer>, initializer, (adoptPtr(new ModulesInitializer)));
+    return *initializer;
+}
+
 void initializeWithoutV8(Platform* platform)
 {
     ASSERT(!s_webKitInitialized);
@@ -161,8 +167,7 @@
         s_gcTaskRunner = new GCTaskRunner(currentThread);
     }
 
-    DEFINE_STATIC_LOCAL(ModulesInitializer, initializer, ());
-    initializer.init();
+    modulesInitializer().init();
 
     setIndexedDBClientCreateFunction(IndexedDBClientImpl::create);
 }
@@ -194,27 +199,17 @@
         // the shutdown() is called.
         delete s_endOfTaskRunner;
         s_endOfTaskRunner = nullptr;
-
-        ASSERT(s_gcTaskRunner);
-        delete s_gcTaskRunner;
-        s_gcTaskRunner = nullptr;
     }
 
     // Shutdown V8-related background threads before V8 is ramped down. Note
     // that this will wait the thread to stop its operations.
     ScriptStreamerThread::shutdown();
 
+    ThreadState::current()->unregisterTraceDOMWrappers();
+
     v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
     V8PerIsolateData::willBeDestroyed(isolate);
 
-    CoreInitializer::terminateThreads();
-
-    ModulesInitializer::terminateThreads();
-
-    // Detach the main thread before starting the shutdown sequence
-    // so that the main thread won't get involved in a GC during the shutdown.
-    ThreadState::detachMainThread();
-
     V8PerIsolateData::destroy(isolate);
 
     shutdownWithoutV8();
@@ -222,8 +217,21 @@
 
 void shutdownWithoutV8()
 {
+    ASSERT(isMainThread());
+    modulesInitializer().shutdown();
+
+    // currentThread() is null if we are running on a thread without a message loop.
+    if (Platform::current()->currentThread()) {
+        ASSERT(s_gcTaskRunner);
+        delete s_gcTaskRunner;
+        s_gcTaskRunner = nullptr;
+    }
+
+    // Detach the main thread before starting the shutdown sequence
+    // so that the main thread won't get involved in a GC during the shutdown.
+    ThreadState::detachMainThread();
+
     ASSERT(!s_endOfTaskRunner);
-    CoreInitializer::shutdown();
     Heap::shutdown();
     WTF::shutdown();
     Platform::shutdown();
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index d271fda..d5933128 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -109,12 +109,12 @@
     Widget::setFrameRect(frameRect);
 }
 
-void WebPluginContainerImpl::layoutIfNeeded()
+void WebPluginContainerImpl::updateAllLifecyclePhases()
 {
     if (!m_webPlugin)
         return;
 
-    m_webPlugin->layoutIfNeeded();
+    m_webPlugin->updateAllLifecyclePhases();
 }
 
 void WebPluginContainerImpl::paint(GraphicsContext& context, const CullRect& cullRect) const
@@ -426,10 +426,10 @@
     invalidateRect(rect);
 }
 
-void WebPluginContainerImpl::setNeedsLayout()
+void WebPluginContainerImpl::scheduleAnimation()
 {
-    if (m_element->layoutObject())
-        m_element->layoutObject()->setNeedsLayoutAndFullPaintInvalidation("Plugin needs layout");
+    if (auto* frameView = m_element->document().view())
+        frameView->scheduleAnimation();
 }
 
 void WebPluginContainerImpl::reportGeometry()
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
index 72f25f0..38867769 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -78,7 +78,7 @@
     bool supportsInputMethod() const override;
     bool canProcessDrag() const override;
     bool wantsWheelEvents() override;
-    void layoutIfNeeded() override;
+    void updateAllLifecyclePhases() override;
     void invalidatePaintIfNeeded() override { issuePaintInvalidations(); }
 
     // Widget methods
@@ -102,7 +102,7 @@
     void invalidate() override;
     void invalidateRect(const WebRect&) override;
     void scrollRect(const WebRect&) override;
-    void setNeedsLayout() override;
+    void scheduleAnimation() override;
     void reportGeometry() override;
     void allowScriptObjects() override;
     void clearScriptObjects() override;
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index d1f3d0a..46747cb 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -100,16 +100,6 @@
     RuntimeEnabledFeatures::setDisplayList2dCanvasEnabled(enable);
 }
 
-void WebRuntimeFeatures::enableEncryptedMedia(bool enable)
-{
-    RuntimeEnabledFeatures::setEncryptedMediaEnabled(enable);
-}
-
-bool WebRuntimeFeatures::isEncryptedMediaEnabled()
-{
-    return RuntimeEnabledFeatures::encryptedMediaEnabled();
-}
-
 void WebRuntimeFeatures::enableExperimentalCanvasFeatures(bool enable)
 {
     RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(enable);
@@ -150,11 +140,6 @@
     RuntimeEnabledFeatures::setMediaRecorderEnabled(enable);
 }
 
-void WebRuntimeFeatures::enableMediaSource(bool enable)
-{
-    RuntimeEnabledFeatures::setMediaSourceEnabled(enable);
-}
-
 void WebRuntimeFeatures::enableNotificationActionIcons(bool enable)
 {
     RuntimeEnabledFeatures::setNotificationActionIconsEnabled(enable);
diff --git a/third_party/WebKit/Source/web/WebViewFrameWidget.cpp b/third_party/WebKit/Source/web/WebViewFrameWidget.cpp
index 86f9d4b3..6e2e03c 100644
--- a/third_party/WebKit/Source/web/WebViewFrameWidget.cpp
+++ b/third_party/WebKit/Source/web/WebViewFrameWidget.cpp
@@ -41,11 +41,6 @@
     return m_webView->size();
 }
 
-void WebViewFrameWidget::willStartLiveResize()
-{
-    return m_webView->willStartLiveResize();
-}
-
 void WebViewFrameWidget::resize(const WebSize& size)
 {
     return m_webView->resize(size);
@@ -56,11 +51,6 @@
     return m_webView->resizeVisualViewport(size);
 }
 
-void WebViewFrameWidget::willEndLiveResize()
-{
-    return m_webView->willEndLiveResize();
-}
-
 void WebViewFrameWidget::didEnterFullScreen()
 {
     return m_webView->didEnterFullScreen();
diff --git a/third_party/WebKit/Source/web/WebViewFrameWidget.h b/third_party/WebKit/Source/web/WebViewFrameWidget.h
index 870f2d2..3c739ab6 100644
--- a/third_party/WebKit/Source/web/WebViewFrameWidget.h
+++ b/third_party/WebKit/Source/web/WebViewFrameWidget.h
@@ -40,10 +40,8 @@
     // WebFrameWidget overrides:
     void close() override;
     WebSize size() override;
-    void willStartLiveResize() override;
     void resize(const WebSize&) override;
     void resizeVisualViewport(const WebSize&) override;
-    void willEndLiveResize() override;
     void didEnterFullScreen() override;
     void didExitFullScreen() override;
     void beginFrame(double lastFrameTimeMonotonic) override;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 325d6088..99081bb 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -1770,12 +1770,6 @@
     deref();  // Balances ref() acquired in WebView::create
 }
 
-void WebViewImpl::willStartLiveResize()
-{
-    if (mainFrameImpl() && mainFrameImpl()->frameView())
-        mainFrameImpl()->frameView()->willStartLiveResize();
-}
-
 WebSize WebViewImpl::size()
 {
     return m_size;
@@ -1907,12 +1901,6 @@
     sendResizeEventAndRepaint();
 }
 
-void WebViewImpl::willEndLiveResize()
-{
-    if (mainFrameImpl() && mainFrameImpl()->frameView())
-        mainFrameImpl()->frameView()->willEndLiveResize();
-}
-
 void WebViewImpl::didEnterFullScreen()
 {
     m_fullscreenController->didEnterFullScreen();
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h
index 508dff86..e6d5b2cf 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.h
+++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -106,10 +106,8 @@
     // WebWidget methods:
     void close() override;
     WebSize size() override;
-    void willStartLiveResize() override;
     void resize(const WebSize&) override;
     void resizeVisualViewport(const WebSize&) override;
-    void willEndLiveResize() override;
     void didEnterFullScreen() override;
     void didExitFullScreen() override;
 
diff --git a/third_party/WebKit/Source/web/linux/WebFontRendering.cpp b/third_party/WebKit/Source/web/linux/WebFontRendering.cpp
index 621ff44..63b21a3a 100644
--- a/third_party/WebKit/Source/web/linux/WebFontRendering.cpp
+++ b/third_party/WebKit/Source/web/linux/WebFontRendering.cpp
@@ -31,6 +31,7 @@
 #include "public/web/linux/WebFontRendering.h"
 
 #include "core/layout/LayoutThemeFontProvider.h"
+#include "platform/fonts/FontCache.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/FontPlatformData.h"
 
@@ -40,6 +41,13 @@
 namespace blink {
 
 // static
+void WebFontRendering::setSkiaFontManager(SkFontMgr* fontMgr)
+{
+    WTF::adopted(fontMgr);
+    FontCache::setFontManager(RefPtr<SkFontMgr>(fontMgr));
+}
+
+// static
 void WebFontRendering::setHinting(SkPaint::Hinting hinting)
 {
     FontPlatformData::setHinting(hinting);
diff --git a/third_party/WebKit/Source/web/tests/FakeWebPlugin.h b/third_party/WebKit/Source/web/tests/FakeWebPlugin.h
index 5b3f1c3..310cb29d6 100644
--- a/third_party/WebKit/Source/web/tests/FakeWebPlugin.h
+++ b/third_party/WebKit/Source/web/tests/FakeWebPlugin.h
@@ -52,7 +52,7 @@
     void destroy() override;
     NPObject* scriptableObject() override { return 0; }
     bool canProcessDrag() const override { return false; }
-    void layoutIfNeeded() override { }
+    void updateAllLifecyclePhases() override { }
     void paint(WebCanvas*, const WebRect&) override { }
     void updateGeometry(const WebRect& clientRect, const WebRect& clipRect, const WebRect& windowClipRect, const WebVector<WebRect>& cutOutsRects, bool isVisible) override { }
     void updateFocus(bool, WebFocusType) override { }
diff --git a/third_party/WebKit/Source/web/win/WebFontRendering.cpp b/third_party/WebKit/Source/web/win/WebFontRendering.cpp
index fe597f3e..c02d59d 100644
--- a/third_party/WebKit/Source/web/win/WebFontRendering.cpp
+++ b/third_party/WebKit/Source/web/win/WebFontRendering.cpp
@@ -63,4 +63,16 @@
     SkFontHost::SetSubpixelOrientation(orientation);
 }
 
+// static
+void WebFontRendering::setAntialiasedTextEnabled(bool enabled)
+{
+    FontCache::setAntialiasedTextEnabled(enabled);
+}
+
+// static
+void WebFontRendering::setLCDTextEnabled(bool enabled)
+{
+    FontCache::setLCDTextEnabled(enabled);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/wtf/Forward.h b/third_party/WebKit/Source/wtf/Forward.h
index b505393..7d770d5 100644
--- a/third_party/WebKit/Source/wtf/Forward.h
+++ b/third_party/WebKit/Source/wtf/Forward.h
@@ -25,7 +25,6 @@
 
 namespace WTF {
 
-template <typename T> class Function;
 template <typename T> class OwnPtr;
 template <typename T> class PassOwnPtr;
 template <typename T> class PassRefPtr;
@@ -55,7 +54,6 @@
 
 } // namespace WTF
 
-using WTF::Function;
 using WTF::OwnPtr;
 using WTF::PassOwnPtr;
 using WTF::PassRefPtr;
diff --git a/third_party/WebKit/Source/wtf/Functional.h b/third_party/WebKit/Source/wtf/Functional.h
index d274422..b56188d 100644
--- a/third_party/WebKit/Source/wtf/Functional.h
+++ b/third_party/WebKit/Source/wtf/Functional.h
@@ -41,9 +41,14 @@
 
 // Functional.h provides a very simple way to bind a function pointer and arguments together into a function object
 // that can be stored, copied and invoked, similar to how boost::bind and std::bind in C++11.
+
+// Thread Safety:
 //
-// Use threadSafeBind() or createCrossThreadTask() if the function/task is
-// called on a (potentially) different thread from the current thread.
+// WTF::bind() and SameThreadClosure should be used for same-thread closures
+// only, i.e. the closures must be created, executed and destructed on
+// the same thread.
+// Use threadSafeBind() and CrossThreadClosure if the function/task is called
+// or destructed on a (potentially) different thread from the current thread.
 
 // WTF::bind() and move semantics
 // ==============================
@@ -191,11 +196,16 @@
     static void* unwrap(const StorageType& value) { return value; }
 };
 
-template<typename>
+enum FunctionThreadAffinity {
+    CrossThreadAffinity,
+    SameThreadAffinity
+};
+
+template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity>
 class Function;
 
-template<typename R, typename... Args>
-class Function<R(Args...)> {
+template<FunctionThreadAffinity threadAffinity, typename R, typename... Args>
+class Function<R(Args...), threadAffinity> {
     USING_FAST_MALLOC(Function);
     WTF_MAKE_NONCOPYABLE(Function);
 public:
@@ -203,13 +213,46 @@
     virtual R operator()(Args... args) = 0;
 protected:
     Function() = default;
+    void checkThread() { }
 };
 
-template <typename BoundParametersTuple, typename FunctionWrapper, typename... UnboundParameters>
+#if ENABLE(ASSERT)
+template<typename R, typename... Args>
+class Function<R(Args...), SameThreadAffinity> {
+    USING_FAST_MALLOC(Function);
+    WTF_MAKE_NONCOPYABLE(Function);
+public:
+    virtual ~Function()
+    {
+        checkThread();
+    }
+    virtual R operator()(Args... args) = 0;
+protected:
+    Function()
+        : m_createdThread(currentThread())
+    {
+    }
+
+    void NEVER_INLINE checkThread()
+    {
+        // Function with SameThreadAffinity, including SameThreadClosure
+        // created by WTF::bind() or blink::createSameThreadTask(),
+        // must be called and destructed on the thread where it is created.
+        // If it is intended to be used cross-thread, use
+        // blink::threadSafeBind() or blink::createCrossThreadTask() instead.
+        RELEASE_ASSERT(m_createdThread == currentThread());
+    }
+
+private:
+    const ThreadIdentifier m_createdThread;
+};
+#endif
+
+template <FunctionThreadAffinity threadAffinity, typename BoundParametersTuple, typename FunctionWrapper, typename... UnboundParameters>
 class PartBoundFunctionImpl;
 
-template <typename... BoundParameters, typename FunctionWrapper, typename... UnboundParameters>
-class PartBoundFunctionImpl<std::tuple<BoundParameters...>, FunctionWrapper, UnboundParameters...> final : public Function<typename FunctionWrapper::ResultType(UnboundParameters...)> {
+template <FunctionThreadAffinity threadAffinity, typename... BoundParameters, typename FunctionWrapper, typename... UnboundParameters>
+class PartBoundFunctionImpl<threadAffinity, std::tuple<BoundParameters...>, FunctionWrapper, UnboundParameters...> final : public Function<typename FunctionWrapper::ResultType(UnboundParameters...), threadAffinity> {
 public:
     // We would like to use StorageTraits<UnboundParameters>... with StorageTraits defined as below in order to obtain
     // storage traits of UnboundParameters, but unfortunately MSVC can't handle template using declarations correctly.
@@ -236,6 +279,7 @@
     template <std::size_t... boundIndices, typename... IncomingUnboundParameters>
         typename FunctionWrapper::ResultType callInternal(const base::IndexSequence<boundIndices...>&, IncomingUnboundParameters&&... unbound)
     {
+        this->checkThread();
         // Get each element in m_bound, unwrap them, and call the function with the desired arguments.
         return m_functionWrapper(ParamStorageTraits<typename std::decay<BoundParameters>::type>::unwrap(std::get<boundIndices>(m_bound))..., std::forward<IncomingUnboundParameters>(unbound)...);
     }
@@ -244,23 +288,31 @@
     std::tuple<typename ParamStorageTraits<typename std::decay<BoundParameters>::type>::StorageType...> m_bound;
 };
 
-template <typename... UnboundParameters, typename FunctionType, typename... BoundParameters>
-PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundParameters...)>> bind(FunctionType function, BoundParameters&&... boundParameters)
+template <FunctionThreadAffinity threadAffinity, typename... UnboundParameters, typename FunctionType, typename... BoundParameters>
+PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundParameters...), threadAffinity>> bindInternal(FunctionType function, BoundParameters&&... boundParameters)
 {
     // Bound parameters' types are wrapped with std::tuple so we can pass two template parameter packs (bound
     // parameters and unbound) to PartBoundFunctionImpl. Note that a tuple of this type isn't actually created;
     // std::tuple<> is just for carrying the bound parameters' types. Any other class template taking a type parameter
     // pack can be used instead of std::tuple. std::tuple is used just because it's most convenient for this purpose.
-    using BoundFunctionType = PartBoundFunctionImpl<std::tuple<BoundParameters&&...>, FunctionWrapper<FunctionType>, UnboundParameters...>;
+    using BoundFunctionType = PartBoundFunctionImpl<threadAffinity, std::tuple<BoundParameters&&...>, FunctionWrapper<FunctionType>, UnboundParameters...>;
     return adoptPtr(new BoundFunctionType(FunctionWrapper<FunctionType>(function), std::forward<BoundParameters>(boundParameters)...));
 }
 
-typedef Function<void()> Closure;
+template <typename... UnboundParameters, typename FunctionType, typename... BoundParameters>
+PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundParameters...), SameThreadAffinity>> bind(FunctionType function, BoundParameters&&... boundParameters)
+{
+    return bindInternal<SameThreadAffinity, UnboundParameters...>(function, std::forward<BoundParameters>(boundParameters)...);
+}
+
+typedef Function<void(), SameThreadAffinity> SameThreadClosure;
+typedef Function<void(), CrossThreadAffinity> CrossThreadClosure;
 
 } // namespace WTF
 
 using WTF::Function;
 using WTF::bind;
-using WTF::Closure;
+using WTF::SameThreadClosure;
+using WTF::CrossThreadClosure;
 
 #endif // WTF_Functional_h
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index 7ae10de..f48574d 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -123,7 +123,7 @@
 struct WebLocalizedString;
 struct WebSize;
 
-class Platform {
+class BLINK_PLATFORM_EXPORT Platform {
 public:
     // HTML5 Database ------------------------------------------------------
 
@@ -133,9 +133,9 @@
     typedef int FileHandle;
 #endif
 
-    BLINK_PLATFORM_EXPORT static void initialize(Platform*);
-    BLINK_PLATFORM_EXPORT static void shutdown();
-    BLINK_PLATFORM_EXPORT static Platform* current();
+    static void initialize(Platform*);
+    static void shutdown();
+    static Platform* current();
 
     // May return null.
     virtual WebCookieJar* cookieJar() { return nullptr; }
@@ -387,7 +387,7 @@
     virtual WebString defaultLocale() { return WebString(); }
 
     // Returns an interface to the main thread. Can be null if blink was initialized on a thread without a message loop.
-    BLINK_PLATFORM_EXPORT WebThread* mainThread() const;
+    WebThread* mainThread() const;
 
     // Returns an interface to the compositor thread. This can be null if the
     // renderer was created with threaded rendering desabled.
@@ -424,10 +424,10 @@
     // registerMemoryDumpProvider() method. |name| is used for debugging
     // (duplicates are allowed) and must be a long-lived C string.
     // See crbug.com/458295 for design docs.
-    BLINK_PLATFORM_EXPORT virtual void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*, const char* name);
+    virtual void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*, const char* name);
 
     // Must be called on the thread that called registerMemoryDumpProvider().
-    BLINK_PLATFORM_EXPORT virtual void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*);
+    virtual void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*);
 
     class TraceLogEnabledStateObserver {
     public:
@@ -609,7 +609,7 @@
     virtual WebTrialTokenValidator* trialTokenValidator() { return nullptr; }
 
 protected:
-    BLINK_PLATFORM_EXPORT Platform();
+    Platform();
     virtual ~Platform() { }
 
     WebThread* m_mainThread;
diff --git a/third_party/WebKit/public/platform/WebTaskRunner.h b/third_party/WebKit/public/platform/WebTaskRunner.h
index 57638175..10b1583 100644
--- a/third_party/WebKit/public/platform/WebTaskRunner.h
+++ b/third_party/WebKit/public/platform/WebTaskRunner.h
@@ -57,12 +57,14 @@
 
 #ifdef INSIDE_BLINK
     // Helpers for posting bound functions as tasks.
-    typedef Function<void()> ClosureTask;
 
-    void postTask(const WebTraceLocation&, PassOwnPtr<ClosureTask>);
-    // TODO(alexclarke): Remove this when possible.
-    void postDelayedTask(const WebTraceLocation&, PassOwnPtr<ClosureTask>, long long delayMs);
-    void postDelayedTask(const WebTraceLocation&, PassOwnPtr<ClosureTask>, double delayMs);
+    // For cross-thread posting. Can be called from any thread.
+    void postTask(const WebTraceLocation&, PassOwnPtr<CrossThreadClosure>);
+    void postDelayedTask(const WebTraceLocation&, PassOwnPtr<CrossThreadClosure>, long long delayMs);
+
+    // For same-thread posting. Must be called from the associated WebThread.
+    void postTask(const WebTraceLocation&, PassOwnPtr<SameThreadClosure>);
+    void postDelayedTask(const WebTraceLocation&, PassOwnPtr<SameThreadClosure>, long long delayMs);
 
     PassOwnPtr<WebTaskRunner> adoptClone()
     {
diff --git a/third_party/WebKit/public/web/WebFormElement.h b/third_party/WebKit/public/web/WebFormElement.h
index 35fac53..53308c7 100644
--- a/third_party/WebKit/public/web/WebFormElement.h
+++ b/third_party/WebKit/public/web/WebFormElement.h
@@ -59,7 +59,6 @@
     BLINK_EXPORT WebString action() const;
     BLINK_EXPORT WebString name() const;
     BLINK_EXPORT WebString method() const;
-    BLINK_EXPORT bool wasUserSubmitted() const;
     // FIXME: Deprecate and replace with WebVector<WebElement>.
     BLINK_EXPORT void getNamedElements(const WebString&, WebVector<WebNode>&);
     BLINK_EXPORT void getFormControlElements(WebVector<WebFormControlElement>&) const;
diff --git a/third_party/WebKit/public/web/WebPlugin.h b/third_party/WebKit/public/web/WebPlugin.h
index c25bc6c0..8e6703aa 100644
--- a/third_party/WebKit/public/web/WebPlugin.h
+++ b/third_party/WebKit/public/web/WebPlugin.h
@@ -103,8 +103,7 @@
 
     virtual bool canProcessDrag() const { return false; }
 
-    // TODO(schenney): Make these pure virtual when chromium changes land
-    virtual void layoutIfNeeded() { }
+    virtual void updateAllLifecyclePhases() = 0;
     virtual void paint(WebCanvas*, const WebRect&) = 0;
 
     // Coordinates are relative to the containing window.
diff --git a/third_party/WebKit/public/web/WebPluginContainer.h b/third_party/WebKit/public/web/WebPluginContainer.h
index 569d190..47a0d37 100644
--- a/third_party/WebKit/public/web/WebPluginContainer.h
+++ b/third_party/WebKit/public/web/WebPluginContainer.h
@@ -65,11 +65,8 @@
     virtual void invalidateRect(const WebRect&) = 0;
     virtual void scrollRect(const WebRect&) = 0;
 
-    // Causes the container to be marked as needing layout, which in turn will cause
-    // layoutIfNeeded() to be called on any contained WebPlugin during the container's
-    // web view's lifecycle update, and in particular before calling paint() on the
-    // WebPlugin.
-    virtual void setNeedsLayout() = 0;
+    // Schedules an animation of the WebView that contains the plugin, as well as the plugin.
+    virtual void scheduleAnimation() = 0;
 
     // Causes the container to report its current geometry via
     // WebPlugin::updateGeometry.
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index 7e8d055..b371968c 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -70,8 +70,7 @@
     BLINK_EXPORT static void forceDisplayList2dCanvas(bool);
     BLINK_EXPORT static void forceDisable2dCanvasCopyOnWrite(bool);
 
-    BLINK_EXPORT static void enableEncryptedMedia(bool);
-    BLINK_EXPORT static bool isEncryptedMediaEnabled();
+    BLINK_EXPORT static void enableCompositorAnimationTimelines(bool);
 
     BLINK_EXPORT static void enableExperimentalCanvasFeatures(bool);
 
@@ -90,8 +89,6 @@
 
     BLINK_EXPORT static void enableMediaRecorder(bool);
 
-    BLINK_EXPORT static void enableMediaSource(bool);
-
     BLINK_EXPORT static void enableNotificationActionIcons(bool);
 
     BLINK_EXPORT static void enableNotificationConstructor(bool);
diff --git a/third_party/WebKit/public/web/WebWidget.h b/third_party/WebKit/public/web/WebWidget.h
index ceb006f..04ba9c0d 100644
--- a/third_party/WebKit/public/web/WebWidget.h
+++ b/third_party/WebKit/public/web/WebWidget.h
@@ -63,12 +63,6 @@
     // Returns the current size of the WebWidget.
     virtual WebSize size() { return WebSize(); }
 
-    // Used to group a series of resize events. For example, if the user
-    // drags a resizer then willStartLiveResize will be called, followed by a
-    // sequence of resize events, ending with willEndLiveResize when the user
-    // lets go of the resizer.
-    virtual void willStartLiveResize() { }
-
     // Called to resize the WebWidget.
     virtual void resize(const WebSize&) { }
 
@@ -79,10 +73,6 @@
     // keyboard to overlay over content but allow scrolling it into view.
     virtual void resizeVisualViewport(const WebSize&) { }
 
-    // Ends a group of resize events that was started with a call to
-    // willStartLiveResize.
-    virtual void willEndLiveResize() { }
-
     // Called to notify the WebWidget of entering/exiting fullscreen mode.
     virtual void didEnterFullScreen() { }
     virtual void didExitFullScreen() { }
diff --git a/third_party/WebKit/public/web/linux/WebFontRendering.h b/third_party/WebKit/public/web/linux/WebFontRendering.h
index 7aa6d25..54c1ad3 100644
--- a/third_party/WebKit/public/web/linux/WebFontRendering.h
+++ b/third_party/WebKit/public/web/linux/WebFontRendering.h
@@ -33,6 +33,7 @@
 
 #include "../../platform/WebCommon.h"
 #include <SkFontHost.h>
+#include <SkFontMgr.h>
 #include <SkPaint.h>
 
 namespace blink {
@@ -41,6 +42,7 @@
 public:
     // Set global font renderering preferences.
 
+    BLINK_EXPORT static void setSkiaFontManager(SkFontMgr*);
     BLINK_EXPORT static void setHinting(SkPaint::Hinting);
     BLINK_EXPORT static void setAutoHint(bool);
     BLINK_EXPORT static void setUseBitmaps(bool);
diff --git a/third_party/WebKit/public/web/win/WebFontRendering.h b/third_party/WebKit/public/web/win/WebFontRendering.h
index f1877f80..af4b1d4 100644
--- a/third_party/WebKit/public/web/win/WebFontRendering.h
+++ b/third_party/WebKit/public/web/win/WebFontRendering.h
@@ -24,6 +24,8 @@
     BLINK_EXPORT static void setStatusFontMetrics(const wchar_t* familyName, int32_t fontHeight);
     BLINK_EXPORT static void setLCDOrder(SkFontHost::LCDOrder);
     BLINK_EXPORT static void setLCDOrientation(SkFontHost::LCDOrientation);
+    BLINK_EXPORT static void setAntialiasedTextEnabled(bool);
+    BLINK_EXPORT static void setLCDTextEnabled(bool);
 };
 
 } // namespace blink
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath
index 62d3c39..d9a45166 100644
--- a/tools/android/eclipse/.classpath
+++ b/tools/android/eclipse/.classpath
@@ -98,8 +98,8 @@
     <classpathentry kind="src" path="out/Debug/gen/enums/accessibility_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/activity_type_ids_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/android_resource_type_java"/>
-    <classpathentry kind="src" path="out/Debug/gen/enums/autocomplete_match_java/"/>
-    <classpathentry kind="src" path="out/Debug/gen/enums/autocomplete_match_type_java/"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/autocomplete_match_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/autocomplete_match_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/ax_enumerations_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/base_java_application_state"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/base_java_library_load_from_apk_status_codes"/>
@@ -107,46 +107,63 @@
     <classpathentry kind="src" path="out/Debug/gen/enums/base_java_memory_pressure_level"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/bitmap_format_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/bookmark_type_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/browsing_data_time_period_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/browsing_data_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/certificate_mime_types_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/cert_verify_status_android_java"/>
-    <classpathentry kind="src" path="out/Debug/gen/enums/connection_security_levels_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/chromium_url_request_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/connectivity_check_result_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/console_message_level_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/content_gamepad_mapping"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/content_setting_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/content_settings_type_java"/>
-    <classpathentry kind="src" path="out/Debug/gen/enums/cronet_url_request_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/data_use_ui_message_enum_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/device_sensors_consts_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/gesture_event_type_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/http_cache_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/infobar_action_type_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/infobar_delegate_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/invalidate_types_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/investigated_scenario_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/media_android_captureapitype"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/media_android_imageformat"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/model_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/most_visited_tile_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/navigation_controller_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/net_request_priority_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/network_change_notifier_android_types_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/network_change_notifier_types_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/network_quality_observations_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/offline_page_feature_enums_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/offline_page_model_enums_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/page_info_connection_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/page_transition_types_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/popup_item_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/private_key_types_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/profile_account_management_metrics_java"/>
-    <classpathentry kind="src" path="out/Debug/gen/enums/profile_sync_service_model_type_selection_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/readback_response_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/result_codes_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/screen_orientation_values_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/security_state_enums_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/selection_event_type_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/sensor_manager_android_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/shortcut_source_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/signin_metrics_enum_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/speech_recognition_error_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/stop_source_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/system_ui_resource_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/tab_load_status_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/text_input_type_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/top_controls_state_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/touch_device_types_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/touch_handle_orientation_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/traffic_stats_error_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/url_request_error_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/url_request_failed_job_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/usb_descriptors_javagen"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/web_display_mode"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/web_input_event_java"/>
+    <classpathentry kind="src" path="out/Debug/gen/enums/website_settings_action_java"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/web_text_input_type"/>
     <classpathentry kind="src" path="out/Debug/gen/enums/window_open_disposition_java"/>
     <classpathentry kind="src" path="out/Debug/gen/templates/base_build_config_gen"/>
diff --git a/tools/android/forwarder2/socket.cc b/tools/android/forwarder2/socket.cc
index c6073c19..669764f 100644
--- a/tools/android/forwarder2/socket.cc
+++ b/tools/android/forwarder2/socket.cc
@@ -136,7 +136,7 @@
   }
   family_ = PF_UNIX;
   addr_.addr_un.sun_family = family_;
-  // Copied from net/socket/unix_domain_socket_posix.cc
+  // Copied from net/socket/unix_domain_client_socket_posix.cc.
   // Convert the path given into abstract socket name. It must start with
   // the '\0' character, so we are adding it. |addr_len| must specify the
   // length of the structure exactly, as potentially the socket name may
diff --git a/tools/android/loading/activity_lens.py b/tools/android/loading/activity_lens.py
index c99d47a9..f6165d9 100644
--- a/tools/android/loading/activity_lens.py
+++ b/tools/android/loading/activity_lens.py
@@ -76,7 +76,7 @@
                      - max(start_msec, event.start_msec)))
 
   @classmethod
-  def _ThreadBusiness(cls, events, start_msec, end_msec):
+  def _ThreadBusyness(cls, events, start_msec, end_msec):
     """Amount of time a thread spent executing from the message loop."""
     busy_duration = 0
     message_loop_events = [
@@ -179,7 +179,7 @@
     assert end_msec - start_msec >= 0.
     events = self._OverlappingMainRendererThreadEvents(start_msec, end_msec)
     result = {'edge_cost': end_msec - start_msec,
-              'busy': self._ThreadBusiness(events, start_msec, end_msec),
+              'busy': self._ThreadBusyness(events, start_msec, end_msec),
               'parsing': self._Parsing(events, start_msec, end_msec),
               'script': self._ScriptsExecuting(events, start_msec, end_msec)}
     return result
@@ -219,6 +219,16 @@
         breakdown[x] for x in ('script', 'parsing', 'other_url', 'unknown_url'))
     return breakdown
 
+  def MainRendererThreadBusyness(self, start_msec, end_msec):
+    """Returns the amount of time the main renderer thread was busy.
+
+    Args:
+      start_msec: (float) Start of the interval.
+      end_msec: (float) End of the interval.
+    """
+    events = self._OverlappingMainRendererThreadEvents(start_msec, end_msec)
+    return self._ThreadBusyness(events, start_msec, end_msec)
+
 
 class _EventsTree(object):
   """Builds the hierarchy of events from a list of fully nested events."""
diff --git a/tools/android/loading/activity_lens_unittest.py b/tools/android/loading/activity_lens_unittest.py
index 5abc172..f0c1275 100644
--- a/tools/android/loading/activity_lens_unittest.py
+++ b/tools/android/loading/activity_lens_unittest.py
@@ -11,7 +11,7 @@
 import tracing
 
 
-class ActivityLensTestCast(unittest.TestCase):
+class ActivityLensTestCase(unittest.TestCase):
   @classmethod
   def _EventsFromRawEvents(cls, raw_events):
     tracing_track = tracing.TracingTrack(None)
@@ -83,7 +83,7 @@
     self.assertEquals((1, second_renderer_tid),
                       ActivityLens._GetRendererMainThreadId(events))
 
-  def testThreadBusiness(self):
+  def testThreadBusyness(self):
     raw_events =  [
         {u'args': {},
          u'cat': u'toplevel',
@@ -104,10 +104,10 @@
          u'ts': 0,
          u'tts': 0}]
     events = self._EventsFromRawEvents(raw_events)
-    self.assertEquals(200, ActivityLens._ThreadBusiness(events, 0, 1000))
+    self.assertEquals(200, ActivityLens._ThreadBusyness(events, 0, 1000))
     # Clamping duration.
-    self.assertEquals(100, ActivityLens._ThreadBusiness(events, 0, 100))
-    self.assertEquals(50, ActivityLens._ThreadBusiness(events, 25, 75))
+    self.assertEquals(100, ActivityLens._ThreadBusyness(events, 0, 100))
+    self.assertEquals(50, ActivityLens._ThreadBusyness(events, 25, 75))
 
   def testScriptExecuting(self):
     url = u'http://example.com/script.js'
@@ -249,6 +249,53 @@
          'other_url': 6., 'unknown_url': 7.},
         activity.BreakdownEdgeActivityByInitiator(dep))
 
+  def testMainRendererThreadBusyness(self):
+    raw_events =  [
+        {u'args': {u'name': u'CrRendererMain'},
+         u'cat': u'__metadata',
+         u'name': u'thread_name',
+         u'ph': u'M',
+         u'pid': 1,
+         u'tid': 12,
+         u'ts': 0},
+        {u'args': {},
+         u'cat': u'toplevel',
+         u'dur': 200 * 1000,
+         u'name': u'MessageLoop::RunTask',
+         u'ph': u'X',
+         u'pid': 1,
+         u'tid': 12,
+         u'ts': 0,
+         u'tts': 56485},
+        {u'args': {},
+         u'cat': u'toplevel',
+         u'dur': 8 * 200,
+         u'name': u'MessageLoop::NestedSomething',
+         u'ph': u'X',
+         u'pid': 1,
+         u'tid': 12,
+         u'ts': 0,
+         u'tts': 0},
+        {u'args': {},
+         u'cat': u'toplevel',
+         u'dur': 500 * 1000,
+         u'name': u'MessageLoop::RunTask',
+         u'ph': u'X',
+         u'pid': 12,
+         u'tid': 12,
+         u'ts': 0,
+         u'tts': 56485}]
+    lens = self._ActivityLens([], raw_events)
+    # Ignore events from another PID.
+    self.assertEquals(200, lens.MainRendererThreadBusyness(0, 1000))
+    # Clamping duration.
+    self.assertEquals(100, lens.MainRendererThreadBusyness(0, 100))
+    self.assertEquals(50, lens.MainRendererThreadBusyness(25, 75))
+    # Other PID.
+    raw_events[0]['pid'] = 12
+    lens = self._ActivityLens([], raw_events)
+    self.assertEquals(500, lens.MainRendererThreadBusyness(0, 1000))
+
   def _ActivityLens(self, requests, raw_events):
     loading_trace = test_utils.LoadingTraceFromEvents(
         requests, None, raw_events)
diff --git a/tools/android/loading/loading_trace.py b/tools/android/loading/loading_trace.py
index d383857..344baeb2 100644
--- a/tools/android/loading/loading_trace.py
+++ b/tools/android/loading/loading_trace.py
@@ -5,6 +5,7 @@
 """Represents the trace of a page load."""
 
 import json
+
 import page_track
 import request_track
 import tracing
diff --git a/tools/android/loading/network_activity_lens.py b/tools/android/loading/network_activity_lens.py
new file mode 100644
index 0000000..20400934
--- /dev/null
+++ b/tools/android/loading/network_activity_lens.py
@@ -0,0 +1,210 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Gives a picture of the network activity between timestamps."""
+
+import bisect
+import collections
+import itertools
+import operator
+
+
+class NetworkActivityLens(object):
+  """Reconstructs the network activity during a trace.
+
+  The {uploaded,downloaded}_bytes_timeline timelines are:
+  ([timestamp_msec], [value_at_timestamp]). Bytes are counted when a
+  network event completes.
+
+  The rate timelines are:
+  ([timestamp_msec], [rate]), where the rate is computed over the time
+  period ending at timestamp_msec.
+
+  For all the timelines, the list of timestamps are identical.
+  """
+  def __init__(self, trace):
+    """Initializes a NetworkActivityLens instance.
+
+    Args:
+      trace: (LoadingTrace)
+    """
+    self._trace = trace
+    self._start_end_times = []
+    self._active_events_list = []
+    self._uploaded_bytes_timeline = []
+    self._downloaded_bytes_timeline = []
+    self._upload_rate_timeline = []
+    self._download_rate_timeline = []
+    requests = trace.request_track.GetEvents()
+    self._network_events = list(itertools.chain.from_iterable(
+        NetworkEvent.EventsFromRequest(request) for request in requests))
+    self._IndexEvents()
+    self._CreateTimelines()
+
+  @property
+  def uploaded_bytes_timeline(self): # (timestamps, data)
+    return (self._start_end_times, self._uploaded_bytes_timeline)
+
+  @property
+  def downloaded_bytes_timeline(self):
+    return (self._start_end_times, self._downloaded_bytes_timeline)
+
+  @property
+  def upload_rate_timeline(self):
+    return (self._start_end_times, self._upload_rate_timeline)
+
+  @property
+  def download_rate_timeline(self):
+    return (self._start_end_times, self._download_rate_timeline)
+
+  def _IndexEvents(self):
+    start_end_times_set = set()
+    for event in self._network_events:
+      start_end_times_set.add(event.start_msec)
+      start_end_times_set.add(event.end_msec)
+    self._start_end_times = sorted(list(start_end_times_set))
+    self._active_events_list = [[] for _ in self._start_end_times]
+    for event in self._network_events:
+      start_index = bisect.bisect_right(
+          self._start_end_times, event.start_msec) - 1
+      end_index = bisect.bisect_right(
+          self._start_end_times, event.end_msec)
+      for index in range(start_index, end_index):
+        self._active_events_list[index].append(event)
+
+  def _CreateTimelines(self):
+    for (index, timestamp) in enumerate(self._start_end_times):
+      upload_rate = sum(
+          e.UploadRate() for e in self._active_events_list[index]
+          if timestamp != e.end_msec)
+      download_rate = sum(
+          e.DownloadRate() for e in self._active_events_list[index]
+          if timestamp != e.end_msec)
+      uploaded_bytes = sum(
+          e.UploadedBytes() for e in self._active_events_list[index]
+          if timestamp == e.end_msec)
+      downloaded_bytes = sum(
+          e.DownloadedBytes() for e in self._active_events_list[index]
+          if timestamp == e.end_msec)
+      self._uploaded_bytes_timeline.append(uploaded_bytes)
+      self._downloaded_bytes_timeline.append(downloaded_bytes)
+      self._upload_rate_timeline.append(upload_rate)
+      self._download_rate_timeline.append(download_rate)
+
+
+class NetworkEvent(object):
+  """Represents a network event."""
+  KINDS = set(
+      ('dns', 'connect', 'send', 'receive_headers', 'receive_body'))
+  def __init__(self, request, kind, start_msec, end_msec, chunk_index=None):
+    """Creates a NetworkEvent."""
+    self._request = request
+    self._kind = kind
+    self.start_msec = start_msec
+    self.end_msec = end_msec
+    self._chunk_index = chunk_index
+
+  @classmethod
+  def _GetStartEndOffsetsMsec(cls, request, kind, index=None):
+    start_offset, end_offset = (0, 0)
+    r = request
+    if kind == 'dns':
+      start_offset = r.timing.dns_start
+      end_offset = r.timing.dns_end
+    elif kind == 'connect':
+      start_offset = r.timing.connect_start
+      end_offset = r.timing.connect_end
+    elif kind == 'send':
+      start_offset = r.timing.send_start
+      end_offset = r.timing.send_end
+    elif kind == 'receive_headers': # There is no responseReceived timing.
+      start_offset = r.timing.send_end
+      end_offset = r.timing.receive_headers_end
+    elif kind == 'receive_body':
+      if index is None:
+        start_offset = r.timing.receive_headers_end
+        end_offset = r.timing.loading_finished
+      else:
+        # Some chunks can correspond to no data.
+        i = index - 1
+        while i >= 0:
+          (offset, size) = r.data_chunks[i]
+          if size != 0:
+            previous_chunk_start = offset
+            break
+          i -= 1
+        else:
+          previous_chunk_start = r.timing.receive_headers_end
+        start_offset = previous_chunk_start
+        end_offset = r.data_chunks[index][0]
+    return (start_offset, end_offset)
+
+  @classmethod
+  def EventsFromRequest(cls, request):
+    # TODO(lizeb): This ignore forced revalidations.
+    if (request.from_disk_cache or request.served_from_cache
+        or request.IsDataRequest()):
+      return []
+    events = []
+    for kind in cls.KINDS - set(['receive_body']):
+      event = cls._EventWithKindFromRequest(request, kind)
+      if event:
+        events.append(event)
+    kind = 'receive_body'
+    if request.data_chunks:
+      for (index, chunk) in enumerate(request.data_chunks):
+        if chunk[0] != 0:
+          event = cls._EventWithKindFromRequest(request, kind, index)
+          if event:
+            events.append(event)
+    else:
+      event = cls._EventWithKindFromRequest(request, kind, None)
+      if event:
+        events.append(event)
+    return events
+
+  @classmethod
+  def _EventWithKindFromRequest(cls, request, kind, index=None):
+    (start_offset, end_offset) = cls._GetStartEndOffsetsMsec(
+        request, kind, index)
+    event = cls(request, kind, request.start_msec + start_offset,
+                request.start_msec + end_offset, index)
+    if start_offset == -1 or end_offset == -1:
+      return None
+    return event
+
+  def UploadedBytes(self):
+    """Returns the number of bytes uploaded during this event."""
+    if self._kind not in ('send'):
+      return 0
+    # Headers are not compressed (ignoring SPDY / HTTP/2)
+    if not self._request.request_headers:
+      return 0
+    return sum(len(k) + len(str(v)) for (k, v)
+               in self._request.request_headers.items())
+
+  def DownloadedBytes(self):
+    """Returns the number of bytes downloaded during this event."""
+    if self._kind not in ('receive_headers', 'receive_body'):
+      return 0
+    if self._kind == 'receive_headers':
+      return sum(len(k) + len(str(v)) for (k, v)
+                 in self._request.response_headers.items())
+    else:
+      if self._chunk_index is None:
+        return self._request.encoded_data_length
+      else:
+        return self._request.data_chunks[self._chunk_index][1]
+
+  def UploadRate(self):
+    """Returns the upload rate of this event in Bytes / s."""
+    return 1000 * self.UploadedBytes() / float(self.end_msec - self.start_msec)
+
+  def DownloadRate(self):
+    """Returns the download rate of this event in Bytes / s."""
+    downloaded_bytes = self.DownloadedBytes()
+    value = 1000 * downloaded_bytes / float(self.end_msec - self.start_msec)
+    if value > 1e6:
+      print self._kind, downloaded_bytes, self.end_msec - self.start_msec
+    return value
diff --git a/tools/android/loading/network_activity_lens_unittest.py b/tools/android/loading/network_activity_lens_unittest.py
new file mode 100644
index 0000000..e857679a
--- /dev/null
+++ b/tools/android/loading/network_activity_lens_unittest.py
@@ -0,0 +1,111 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import copy
+import unittest
+
+from network_activity_lens import NetworkActivityLens
+import test_utils
+
+
+class NetworkActivityLensTestCase(unittest.TestCase):
+  def testTimeline(self):
+    timing_dict = {
+        'requestTime': 1.2,
+        'dnsStart': 20, 'dnsEnd': 30,
+        'connectStart': 50, 'connectEnd': 60,
+        'sendStart': 70, 'sendEnd': 80,
+        'receiveHeadersEnd': 90,
+        'loadingFinished': 100}
+    request = test_utils.MakeRequestWithTiming(1, 2, timing_dict)
+    lens = self._NetworkActivityLens([request])
+    start_end_times = lens.uploaded_bytes_timeline[0]
+    expected_start_times = [
+        1220., 1230., 1250., 1260., 1270., 1280., 1290., 1300.]
+    self.assertListEqual(expected_start_times, start_end_times)
+    timing_dict = copy.copy(timing_dict)
+    timing_dict['requestTime'] += .005
+    second_request = test_utils.MakeRequestWithTiming(1, 2, timing_dict)
+    lens = self._NetworkActivityLens([request, second_request])
+    start_end_times = lens.uploaded_bytes_timeline[0]
+    expected_start_times = sorted(
+        expected_start_times + [x + 5. for x in expected_start_times])
+    for (expected, actual) in zip(expected_start_times, start_end_times):
+      self.assertAlmostEquals(expected, actual)
+
+  def testTransferredBytes(self):
+    timing_dict = {
+        'requestTime': 1.2,
+        'dnsStart': 20, 'dnsEnd': 30,
+        'connectStart': 50, 'connectEnd': 60,
+        'sendStart': 70, 'sendEnd': 80,
+        'receiveHeadersEnd': 90,
+        'loadingFinished': 100}
+    request = test_utils.MakeRequestWithTiming(1, 2, timing_dict)
+    request.request_headers = {'a': 'b'}
+    request.response_headers = {'c': 'def'}
+    lens = self._NetworkActivityLens([request])
+    # Upload
+    upload_timeline = lens.uploaded_bytes_timeline
+    self.assertEquals(1270, upload_timeline[0][4])
+    self.assertEquals(1280, upload_timeline[0][5])
+    self.assertEquals(0, upload_timeline[1][4])
+    self.assertEquals(2, upload_timeline[1][5])
+    self.assertEquals(0, upload_timeline[1][6])
+    upload_rate = lens.upload_rate_timeline
+    self.assertEquals(2 / 10e-3, upload_rate[1][4])
+    self.assertEquals(0, upload_rate[1][5])
+    # Download
+    download_timeline = lens.downloaded_bytes_timeline
+    download_rate = lens.download_rate_timeline
+    self.assertEquals(1280, download_timeline[0][5])
+    self.assertEquals(1290, download_timeline[0][6])
+    self.assertEquals(0, download_timeline[1][5])
+    self.assertEquals(4, download_timeline[1][6])
+    self.assertEquals(0, download_timeline[1][7])
+    download_rate = lens.download_rate_timeline
+    self.assertEquals(4 / 10e-3, download_rate[1][5])
+    self.assertEquals(0, download_rate[1][6])
+
+  def testLongRequest(self):
+    timing_dict = {
+        'requestTime': 1200,
+        'dnsStart': 20, 'dnsEnd': 30,
+        'connectStart': 50, 'connectEnd': 60,
+        'sendStart': 70, 'sendEnd': 80,
+        'receiveHeadersEnd': 90,
+        'loadingFinished': 100}
+    request = test_utils.MakeRequestWithTiming(1, 2, timing_dict)
+    request.response_headers = {}
+    timing_dict = {
+        'requestTime': 1200,
+        'dnsStart': 2, 'dnsEnd': 3,
+        'connectStart': 5, 'connectEnd': 6,
+        'sendStart': 7, 'sendEnd': 8,
+        'receiveHeadersEnd': 10,
+        'loadingFinished': 1000}
+    long_request = test_utils.MakeRequestWithTiming(1, 2, timing_dict)
+    long_request.response_headers = {}
+    long_request.encoded_data_length = 1000
+    lens = self._NetworkActivityLens([request, long_request])
+    (timestamps, downloaded_bytes) = lens.downloaded_bytes_timeline
+    (_, download_rate) = lens.download_rate_timeline
+    start_receive = (long_request.start_msec
+                     + long_request.timing.receive_headers_end)
+    end_receive = (long_request.start_msec
+                   + long_request.timing.loading_finished)
+    self.assertEquals(1000, downloaded_bytes[-1])
+    for (index, timestamp) in enumerate(timestamps):
+      if start_receive < timestamp < end_receive:
+        self.assertAlmostEqual(1000 / 990e-3, download_rate[index])
+        self.assertEquals(0, downloaded_bytes[index])
+    self.assertEquals(1000, downloaded_bytes[-1])
+
+  def _NetworkActivityLens(self, requests):
+    trace = test_utils.LoadingTraceFromEvents(requests)
+    return NetworkActivityLens(trace)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/android/loading/network_cpu_activity_view.py b/tools/android/loading/network_cpu_activity_view.py
new file mode 100755
index 0000000..09450e1
--- /dev/null
+++ b/tools/android/loading/network_cpu_activity_view.py
@@ -0,0 +1,69 @@
+#!/usr/bin/python
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Graphs the CPU and network activity during a load."""
+
+import numpy as np
+import matplotlib
+from matplotlib import pylab as plt
+import sys
+
+import activity_lens
+import loading_trace
+import network_activity_lens
+
+
+def _CpuActivityTimeline(cpu_lens, start_msec, end_msec, granularity):
+  cpu_timestamps = np.arange(start_msec, end_msec, granularity)
+  busy_percentage = []
+  print len(cpu_timestamps)
+  for i in range(len(cpu_timestamps) - 1):
+    (start, end) = (cpu_timestamps[i], cpu_timestamps[i + 1])
+    duration = end - start
+    busy_ms = cpu_lens.MainRendererThreadBusyness(start, end)
+    busy_percentage.append(100 * busy_ms / float(duration))
+  return (cpu_timestamps[:-1], np.array(busy_percentage))
+
+
+def GraphTimelines(trace, output_filename):
+  """Creates and saves a graph of Network and CPU activity for a trace.
+
+  Args:
+    trace: (LoadingTrace)
+    output_filename: (str) Path of the output graph.
+  """
+  cpu_lens = activity_lens.ActivityLens(trace)
+  network_lens = network_activity_lens.NetworkActivityLens(trace)
+  matplotlib.rc('font', size=14)
+  figure, (network, cpu) = plt.subplots(2, sharex = True, figsize=(14, 10))
+  figure.suptitle('Network and CPU Activity - %s' % trace.url)
+  upload_timeline = network_lens.uploaded_bytes_timeline
+  download_timeline = network_lens.downloaded_bytes_timeline
+  start_time = upload_timeline[0][0]
+  end_time = upload_timeline[0][-1]
+  times = np.array(upload_timeline[0]) - start_time
+  network.step(times, np.cumsum(download_timeline[1]) / 1e6, label='Download')
+  network.step(times, np.cumsum(upload_timeline[1]) / 1e6, label='Upload')
+  network.legend(loc='lower right')
+  network.set_xlabel('Time (ms)')
+  network.set_ylabel('Total Data Transferred (MB)')
+
+  (cpu_timestamps, cpu_busyness) = _CpuActivityTimeline(
+      cpu_lens, start_time, end_time, 100)
+  cpu.step(cpu_timestamps - start_time, cpu_busyness)
+  cpu.set_ylim(ymin=0, ymax=100)
+  cpu.set_xlabel('Time (ms)')
+  cpu.set_ylabel('Main Renderer Thread Busyness (%)')
+  figure.savefig(output_filename, dpi=300)
+
+
+def main():
+  filename = sys.argv[1]
+  trace = loading_trace.LoadingTrace.FromJsonFile(filename)
+  GraphTimelines(trace, filename + '.pdf')
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/android/loading/test_utils.py b/tools/android/loading/test_utils.py
index 2d80d1a..5d2b617 100644
--- a/tools/android/loading/test_utils.py
+++ b/tools/android/loading/test_utils.py
@@ -42,6 +42,41 @@
     return event['frame_id']
 
 
+def MakeRequestWithTiming(
+    url, source_url, timing_dict, magic_content_type=False,
+    initiator_type='other'):
+  """Make a dependent request.
+
+  Args:
+    url: a url, or number which will be used as a url.
+    source_url: a url or number which will be used as the source (initiating)
+      url. If the source url is not present, then url will be a root. The
+      convention in tests is to use a source_url of 'null' in this case.
+    timing_dict: (dict) Suitable to be passed to request_track.TimingFromDict().
+    initiator_type: the initiator type to use.
+
+  Returns:
+    A request_track.Request.
+  """
+  assert initiator_type in ('other', 'parser')
+  timing = request_track.TimingFromDict(timing_dict)
+  rq = request_track.Request.FromJsonDict({
+      'timestamp': timing.request_time,
+      'request_id': str(MakeRequestWithTiming._next_request_id),
+      'url': 'http://' + str(url),
+      'initiator': {'type': initiator_type, 'url': 'http://' + str(source_url)},
+      'response_headers': {'Content-Type':
+                           'null' if not magic_content_type
+                           else 'magic-debug-content' },
+      'timing': request_track.TimingAsList(timing)
+  })
+  MakeRequestWithTiming._next_request_id += 1
+  return rq
+
+
+MakeRequestWithTiming._next_request_id = 0
+
+
 def MakeRequest(
     url, source_url, start_time=None, headers_time=None, end_time=None,
     magic_content_type=False, initiator_type='other'):
@@ -63,7 +98,6 @@
 
   Returns:
     A request_track.Request.
-
   """
   assert ((start_time is None and
            headers_time is None and
@@ -75,29 +109,16 @@
   if start_time is None:
     # Use the request id in seconds for timestamps. This guarantees increasing
     # times which makes request dependencies behave as expected.
-    start_time = headers_time = end_time = MakeRequest._next_request_id * 1000
-  assert initiator_type in ('other', 'parser')
-  timing = request_track.TimingAsList(request_track.TimingFromDict({
+    start_time = headers_time = end_time = (
+        MakeRequestWithTiming._next_request_id * 1000)
+  timing_dict = {
       # connectEnd should be ignored.
       'connectEnd': (end_time - start_time) / 2,
       'receiveHeadersEnd': headers_time - start_time,
       'loadingFinished': end_time - start_time,
-      'requestTime': start_time / 1000.0}))
-  rq = request_track.Request.FromJsonDict({
-      'timestamp': start_time / 1000.0,
-      'request_id': str(MakeRequest._next_request_id),
-      'url': 'http://' + str(url),
-      'initiator': {'type': initiator_type, 'url': 'http://' + str(source_url)},
-      'response_headers': {'Content-Type':
-                           'null' if not magic_content_type
-                           else 'magic-debug-content' },
-      'timing': timing
-  })
-  MakeRequest._next_request_id += 1
-  return rq
-
-
-MakeRequest._next_request_id = 0
+      'requestTime': start_time / 1000.0}
+  return MakeRequestWithTiming(
+      url, source_url, timing_dict, magic_content_type, initiator_type)
 
 
 def LoadingTraceFromEvents(requests, page_events=None, trace_events=None):
diff --git a/tools/checklicenses/checklicenses.py b/tools/checklicenses/checklicenses.py
index 89af839..8067eaa 100755
--- a/tools/checklicenses/checklicenses.py
+++ b/tools/checklicenses/checklicenses.py
@@ -621,6 +621,9 @@
     # Don't check generated files
     'out/',
 
+    # Don't check downloaded goma client binaries
+    'build/goma/client',
+
     # Don't check sysroot directories
     'build/linux/debian_wheezy_amd64-sysroot',
     'build/linux/debian_wheezy_arm-sysroot',
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
index 96182d5..2806dab 100644
--- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
+++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -212,26 +212,12 @@
     }
   }
 
-  name = 'k';  // k prefix on enum values.
-  if (!is_shouty) {
-    name += original_name;
-    name[1] = clang::toUppercase(name[1]);
-    return true;
-  }
+  if (is_shouty)
+    return false;
 
-  // If it's shouty make it camel case.
-  bool start_word = true;
-  for (auto c : original_name) {
-    if (c == '_') {
-      start_word = true;
-      continue;
-    }
-    if (start_word)
-      name += clang::toUppercase(c);
-    else
-      name += clang::toLowercase(c);
-    start_word = false;
-  }
+  name = 'k';  // k prefix on enum values.
+  name += original_name;
+  name[1] = clang::toUppercase(name[1]);
   return true;
 }
 
diff --git a/tools/clang/rewrite_to_chrome_style/tests/enums-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/enums-expected.cc
index 4de9b08d..f35d628 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/enums-expected.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/enums-expected.cc
@@ -5,7 +5,7 @@
 namespace blink {
 
 enum EnumInNamespace {
-  // These should be renamed to SHOUT_CAPS.
+  // These should be renamed to kConstantCase.
   kNamedWrong,
   kNamedWrong2,
   // This shouldn't exist but if it does renaming them will help us find them.
@@ -15,7 +15,7 @@
 class T {
  public:
   enum EnumInClass {
-    // These should be renamed to SHOUT_CAPS.
+    // These should be renamed to kConstantCase.
     kClassNamedWrong,
     kClassNamedWrong22,
     // This shouldn't exist but if it does renaming them will help us find them.
@@ -23,7 +23,7 @@
   };
 
   enum class EnumClassInClass {
-    // These should be renamed to SHOUT_CAPS.
+    // These should be renamed to kConstantCase.
     kEnumClassNamedWrong,
     kEnumClassNamedWrong22,
     // This shouldn't exist but if it does renaming them will help us find them.
@@ -31,9 +31,9 @@
   };
 };
 
-// Already SHOUT_CAPS, so the naming shouldn't change.
+// Is SHOUT_CAPS, so the naming shouldn't change.
 enum AlreadyShouty {
-  kEnableDirectz3000SupportForHl3e1,
+  ENABLE_DIRECTZ3000_SUPPORT_FOR_HL3E1,
 };
 
 }  // namespace blink
@@ -46,7 +46,7 @@
 };
 
 void F() {
-  // These should be renamed to SHOUT_CAPS.
+  // These should be renamed to kConstantCase.
   blink::EnumInNamespace e1 = blink::kNamedWrong;
   blink::EnumInNamespace e2 = blink::kNamedWrong2;
   blink::T::EnumInClass e3 = blink::T::kClassNamedWrong;
diff --git a/tools/clang/rewrite_to_chrome_style/tests/enums-original.cc b/tools/clang/rewrite_to_chrome_style/tests/enums-original.cc
index 000a41e..72faf8e 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/enums-original.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/enums-original.cc
@@ -5,7 +5,7 @@
 namespace blink {
 
 enum EnumInNamespace {
-  // These should be renamed to SHOUT_CAPS.
+  // These should be renamed to kConstantCase.
   NamedWrong,
   namedWrong2,
   // This shouldn't exist but if it does renaming them will help us find them.
@@ -15,7 +15,7 @@
 class T {
  public:
   enum EnumInClass {
-    // These should be renamed to SHOUT_CAPS.
+    // These should be renamed to kConstantCase.
     ClassNamedWrong,
     classNamedWrong22,
     // This shouldn't exist but if it does renaming them will help us find them.
@@ -23,7 +23,7 @@
   };
 
   enum class EnumClassInClass {
-    // These should be renamed to SHOUT_CAPS.
+    // These should be renamed to kConstantCase.
     EnumClassNamedWrong,
     enumClassNamedWrong22,
     // This shouldn't exist but if it does renaming them will help us find them.
@@ -31,7 +31,7 @@
   };
 };
 
-// Already SHOUT_CAPS, so the naming shouldn't change.
+// Is SHOUT_CAPS, so the naming shouldn't change.
 enum AlreadyShouty {
   ENABLE_DIRECTZ3000_SUPPORT_FOR_HL3E1,
 };
@@ -46,7 +46,7 @@
 };
 
 void F() {
-  // These should be renamed to SHOUT_CAPS.
+  // These should be renamed to kConstantCase.
   blink::EnumInNamespace e1 = blink::NamedWrong;
   blink::EnumInNamespace e2 = blink::namedWrong2;
   blink::T::EnumInClass e3 = blink::T::ClassNamedWrong;
diff --git a/tools/copyright_scanner/copyright_scanner.py b/tools/copyright_scanner/copyright_scanner.py
index 04b6407..b83e891 100644
--- a/tools/copyright_scanner/copyright_scanner.py
+++ b/tools/copyright_scanner/copyright_scanner.py
@@ -68,6 +68,8 @@
     path_join('tools', 'histograms'),
     # Swarming tools, doesn't exist in the snapshot
     path_join('tools', 'swarming_client'),
+    # Don't check downloaded goma client binaries.
+    path_join('build', 'goma', 'client'),
     # Ignore sysroots.
     path_join('build', 'linux', 'debian_wheezy_amd64-sysroot'),
     path_join('build', 'linux', 'debian_wheezy_arm-sysroot'),
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 4a54f4a..3365cb0 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -12838,6 +12838,14 @@
   </summary>
 </histogram>
 
+<histogram name="Extensions.ExtensionFrameMapLookupSuccessful" units="Boolean">
+  <owner>rdevlin.cronin@chromium.org</owner>
+  <summary>
+    True if the lookup for a frame in the extension frame map succeeded after a
+    cache miss.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.ExtensionHostMonitoring.MaxActiveLoading">
   <owner>rdevlin.cronin@chromium.org</owner>
   <summary>
@@ -12894,6 +12902,13 @@
   </summary>
 </histogram>
 
+<histogram name="Extensions.ExtensionRendererStateCacheHit" units="Boolean">
+  <owner>rdevlin.cronin@chromium.org</owner>
+  <summary>
+    True if the cache for the ExtensionRendererState was hit during a lookup.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.ExtensionRootPathLength">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>
@@ -21933,6 +21948,15 @@
   </summary>
 </histogram>
 
+<histogram name="Mojo.Shell.RenderProcessInitializationTime" units="ms">
+  <owner>rockot@chromium.org</owner>
+  <summary>
+    Measures the time it takes for a new render process to receive an
+    initialization request from the Mojo shell. This is precisely the duration
+    of the MojoShellConnectionImpl::Create() call in RendererMain.
+  </summary>
+</histogram>
+
 <histogram name="Mojo.System.Node.ConnectedPeers">
   <owner>rockot@chromium.org</owner>
   <summary>
@@ -33494,6 +33518,16 @@
   </summary>
 </histogram>
 
+<histogram name="PageLoad.Internal.ProvisionalAbortChainSize.NoCommit"
+    units="length">
+  <owner>csharrison@chromium.org</owner>
+  <summary>
+    This histogram counts the number of provisional loads aborted by new
+    navigations. In this case the chain never ends with a commit. This is logged
+    on the next abort signal comes in (e.g. tab close or new navigation).
+  </summary>
+</histogram>
+
 <histogram name="PageLoad.Internal.ProvisionalAbortChainSize.Reload"
     units="length">
   <owner>csharrison@chromium.org</owner>
@@ -45278,6 +45312,9 @@
 </histogram>
 
 <histogram name="SequencedWorkerPool.TaskCount">
+  <obsolete>
+    Histogram wasn't even reported anymore when ownership was taken in 11/2015.
+  </obsolete>
   <owner>gab@chromium.org</owner>
   <summary>
     How many pending tasks there are on each request for work from a worker
@@ -45286,6 +45323,9 @@
 </histogram>
 
 <histogram name="SequencedWorkerPool.UnrunnableTaskCount">
+  <obsolete>
+    Histogram wasn't even reported anymore when ownership was taken in 11/2015.
+  </obsolete>
   <owner>gab@chromium.org</owner>
   <summary>How many tasks we skip over to find the next runnable task.</summary>
 </histogram>
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index a712349..a3d6fced 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -88,7 +88,9 @@
         '--js-flags=--expose_gc',
         '--enable-experimental-web-platform-features',
         '--disable-gesture-requirement-for-media-playback',
-        '--enable-experimental-canvas-features'
+        '--enable-experimental-canvas-features',
+        # TODO(qinmin): After fixing crbug.com/592017, remove this command line.
+        '--reduce-security-for-testing'
     ])
     if 'content-shell' in options.browser_type:
       options.AppendExtraBrowserArgs('--expose-internals-for-testing')
@@ -99,6 +101,9 @@
     log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML')
 
     for line in log.splitlines():
+      if line.startswith("FATAL: "):
+        print line
+        continue
       if not line.startswith('values '):
         continue
       parts = line.split()
@@ -166,8 +171,7 @@
     return CreateStorySetFromPath(path, SKIPPED_FILE)
 
 
-@benchmark.Disabled('android',  # http://crbug.com/496707
-                    'reference')  # http://crbug.com/576779
+@benchmark.Disabled('reference')  # http://crbug.com/576779
 class BlinkPerfCanvas(perf_benchmark.PerfBenchmark):
   tag = 'canvas'
   test = _BlinkPerfMeasurement
diff --git a/ui/app_list/views/app_list_folder_view.cc b/ui/app_list/views/app_list_folder_view.cc
index d680988..14177439 100644
--- a/ui/app_list/views/app_list_folder_view.cc
+++ b/ui/app_list/views/app_list_folder_view.cc
@@ -64,7 +64,7 @@
   view_model_->Add(items_grid_view_, kIndexChildItems);
 
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 
   model_->AddObserver(this);
 }
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index 19fdb14..20ec097 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -123,7 +123,7 @@
   search_box_view_->set_contents_view(contents_view_);
 
   contents_view_->SetPaintToLayer(true);
-  contents_view_->SetFillsBoundsOpaquely(false);
+  contents_view_->layer()->SetFillsBoundsOpaquely(false);
   contents_view_->layer()->SetMasksToBounds(true);
 
   delegate_->StartSearch();
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index 05d96c65..ef4387b 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -436,14 +436,14 @@
   app_list_main_view_ = new AppListMainView(delegate_);
   AddChildView(app_list_main_view_);
   app_list_main_view_->SetPaintToLayer(true);
-  app_list_main_view_->SetFillsBoundsOpaquely(false);
+  app_list_main_view_->layer()->SetFillsBoundsOpaquely(false);
   app_list_main_view_->layer()->SetMasksToBounds(true);
 
   // This will be added to the |search_box_widget_| after the app list widget is
   // initialized.
   search_box_view_ = new SearchBoxView(app_list_main_view_, delegate_);
   search_box_view_->SetPaintToLayer(true);
-  search_box_view_->SetFillsBoundsOpaquely(false);
+  search_box_view_->layer()->SetFillsBoundsOpaquely(false);
   search_box_view_->layer()->SetMasksToBounds(true);
 
   // TODO(vadimt): Remove ScopedTracker below once crbug.com/440224 and
@@ -465,7 +465,7 @@
     speech_view_ = new SpeechView(delegate_);
     speech_view_->SetVisible(false);
     speech_view_->SetPaintToLayer(true);
-    speech_view_->SetFillsBoundsOpaquely(false);
+    speech_view_->layer()->SetFillsBoundsOpaquely(false);
     speech_view_->layer()->SetOpacity(0.0f);
     AddChildView(speech_view_);
   }
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index 5d41b5a..43cd030a 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -382,7 +382,7 @@
   // Clip any icons that are outside the grid view's bounds. These icons would
   // otherwise be visible to the user when the grid view is off screen.
   layer()->SetMasksToBounds(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 
   pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs,
                                            kOverscrollPageTransitionDurationMs);
@@ -803,9 +803,7 @@
   AddChildView(view);
   drag_view_ = view;
   drag_view_->SetPaintToLayer(true);
-  // Note: For testing purpose, SetFillsBoundsOpaquely can be set to true to
-  // show the gray background.
-  drag_view_->SetFillsBoundsOpaquely(false);
+  drag_view_->layer()->SetFillsBoundsOpaquely(false);
   drag_view_->SetBoundsRect(drag_view_rect);
   drag_view_->SetDragUIState();  // Hide the title of the drag_view_.
 
@@ -1080,7 +1078,7 @@
   AppListItemView* view = new AppListItemView(this,
                                               item_list_->item_at(index));
   view->SetPaintToLayer(true);
-  view->SetFillsBoundsOpaquely(false);
+  view->layer()->SetFillsBoundsOpaquely(false);
   return view;
 }
 
@@ -1326,7 +1324,7 @@
     layer = view->RecreateLayer();
     layer->SuppressPaint();
 
-    view->SetFillsBoundsOpaquely(false);
+    view->layer()->SetFillsBoundsOpaquely(false);
     view->layer()->SetOpacity(0.f);
   }
 
diff --git a/ui/app_list/views/folder_background_view.cc b/ui/app_list/views/folder_background_view.cc
index 36318ef4..c4c1cc8 100644
--- a/ui/app_list/views/folder_background_view.cc
+++ b/ui/app_list/views/folder_background_view.cc
@@ -26,7 +26,7 @@
     : folder_view_(NULL),
       show_state_(NO_BUBBLE) {
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 FolderBackgroundView::~FolderBackgroundView() {
diff --git a/ui/app_list/views/pulsing_block_view.cc b/ui/app_list/views/pulsing_block_view.cc
index 7cba7cf..08ea725 100644
--- a/ui/app_list/views/pulsing_block_view.cc
+++ b/ui/app_list/views/pulsing_block_view.cc
@@ -75,7 +75,7 @@
 
 PulsingBlockView::PulsingBlockView(const gfx::Size& size, bool start_delay) {
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 
   const int max_delay = kAnimationDurationInMs * arraysize(kAnimationOpacity);
   const int delay = start_delay ? base::RandInt(0, max_delay) : 0;
diff --git a/ui/app_list/views/top_icon_animation_view.cc b/ui/app_list/views/top_icon_animation_view.cc
index 2f65f611..e323782c 100644
--- a/ui/app_list/views/top_icon_animation_view.cc
+++ b/ui/app_list/views/top_icon_animation_view.cc
@@ -27,7 +27,7 @@
   AddChildView(icon_);
 
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 TopIconAnimationView::~TopIconAnimationView() {
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index fd925a0..718de9d 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -553,6 +553,7 @@
     ]
 
     deps += [
+      "//ui/events/ozone:events_ozone_evdev",
       "//ui/events/ozone:events_ozone_layout",
       "//ui/ozone:ozone_base",
     ]
diff --git a/ui/base/material_design/material_design_controller.cc b/ui/base/material_design/material_design_controller.cc
index 877b1a3..411f553 100644
--- a/ui/base/material_design/material_design_controller.cc
+++ b/ui/base/material_design/material_design_controller.cc
@@ -10,8 +10,16 @@
 #include "ui/base/ui_base_switches.h"
 
 #if defined(OS_CHROMEOS)
-#include "base/strings/string_util.h"
-#include "base/sys_info.h"
+#include "ui/base/touch/touch_device.h"
+#include "ui/events/devices/device_data_manager.h"
+
+#if defined(USE_OZONE)
+#include <fcntl.h>
+
+#include "base/files/file_enumerator.h"
+#include "ui/events/ozone/evdev/event_device_info.h"
+#endif  // defined(USE_OZONE)
+
 #endif  // defined(OS_CHROMEOS)
 
 namespace ui {
@@ -35,14 +43,29 @@
 
 MaterialDesignController::Mode MaterialDesignController::DefaultMode() {
 #if defined(OS_CHROMEOS)
-  // TODO(tdanderson): Enable hybrid by default for touchscreen devices.
-  //                   See crbug.com/588880.
-  const std::string board = base::SysInfo::GetLsbReleaseBoard();
-  if (base::StartsWith(board, "link", base::CompareCase::SENSITIVE) ||
-      base::StartsWith(board, "veyron_minnie", base::CompareCase::SENSITIVE) ||
-      base::StartsWith(board, "samus", base::CompareCase::SENSITIVE)) {
-    return Mode::MATERIAL_HYBRID;
+  if (DeviceDataManager::HasInstance() &&
+      DeviceDataManager::GetInstance()->device_lists_complete()) {
+    return GetTouchScreensAvailability() == TouchScreensAvailability::ENABLED ?
+        Mode::MATERIAL_HYBRID : Mode::MATERIAL_NORMAL;
   }
+
+#if defined(USE_OZONE)
+  base::FileEnumerator file_enum(
+      base::FilePath(FILE_PATH_LITERAL("/dev/input")), false,
+      base::FileEnumerator::FILES, FILE_PATH_LITERAL("event*[0-9]"));
+  for (base::FilePath path = file_enum.Next(); !path.empty();
+       path = file_enum.Next()) {
+    EventDeviceInfo devinfo;
+    int fd = open(path.value().c_str(), O_RDWR | O_NONBLOCK | O_CLOEXEC);
+    if (fd >= 0) {
+      if (devinfo.Initialize(fd, path) && devinfo.HasTouchscreen()) {
+        close(fd);
+        return Mode::MATERIAL_HYBRID;
+      }
+      close(fd);
+    }
+  }
+#endif  // defined(USE_OZONE)
   return Mode::MATERIAL_NORMAL;
 #elif defined(OS_LINUX)
   return Mode::MATERIAL_NORMAL;
diff --git a/ui/base/resource/resource_bundle_mac.mm b/ui/base/resource/resource_bundle_mac.mm
index fb907400..0b8d526 100644
--- a/ui/base/resource/resource_bundle_mac.mm
+++ b/ui/base/resource/resource_bundle_mac.mm
@@ -143,27 +143,43 @@
   if (delegate_)
     image = delegate_->GetNativeImageNamed(resource_id);
 
-  bool found_in_a_material_design_pack = false;
-
   if (image.IsEmpty()) {
     base::scoped_nsobject<NSImage> ns_image;
+    // Material Design packs are meant to override the standard packs, so
+    // search for the image in those packs first.
     for (size_t i = 0; i < data_packs_.size(); ++i) {
+      if (!data_packs_[i]->HasOnlyMaterialDesignAssets())
+        continue;
       scoped_refptr<base::RefCountedStaticMemory> data(
           data_packs_[i]->GetStaticMemory(resource_id));
       if (!data.get())
         continue;
 
-      // This loop adds the image resource from each available pack, if it's
-      // present. When Material Design packs are available, however, their
-      // images are meant to override the same image in the standard packs. The
-      // Material Design packs exist at the start of the data_packs_ vector,
-      // so make a note that the image was pulled from a Material Design pack,
-      // and ignore the same image in the standard packs.
-      if (found_in_a_material_design_pack) {
-        break;
+      base::scoped_nsobject<NSData> ns_data(
+          [[NSData alloc] initWithBytes:data->front() length:data->size()]);
+      if (!ns_image.get()) {
+        ns_image.reset([[NSImage alloc] initWithData:ns_data]);
+      } else {
+        NSImageRep* image_rep = [NSBitmapImageRep imageRepWithData:ns_data];
+        if (image_rep)
+          [ns_image addRepresentation:image_rep];
       }
-      found_in_a_material_design_pack =
-          data_packs_[i]->HasOnlyMaterialDesignAssets();
+    }
+
+    if (ns_image.get()) {
+      image = gfx::Image(ns_image.release());
+    }
+  }
+
+  if (image.IsEmpty()) {
+    base::scoped_nsobject<NSImage> ns_image;
+    for (size_t i = 0; i < data_packs_.size(); ++i) {
+      if (data_packs_[i]->HasOnlyMaterialDesignAssets())
+        continue;
+      scoped_refptr<base::RefCountedStaticMemory> data(
+          data_packs_[i]->GetStaticMemory(resource_id));
+      if (!data.get())
+        continue;
 
       base::scoped_nsobject<NSData> ns_data(
           [[NSData alloc] initWithBytes:data->front() length:data->size()]);
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp
index 80f28d45..ae6f6e57 100644
--- a/ui/base/ui_base.gyp
+++ b/ui/base/ui_base.gyp
@@ -462,6 +462,7 @@
         ['use_ozone==1', {
           'dependencies': [
             '../events/devices/events_devices.gyp:events_devices',
+            '../events/ozone/events_ozone.gyp:events_ozone_evdev',
             '../events/ozone/events_ozone.gyp:events_ozone_layout',
             '../ozone/ozone.gyp:ozone_base',
           ],
diff --git a/ui/base/win/open_file_name_win.cc b/ui/base/win/open_file_name_win.cc
index 5c2df41..8b32ae2 100644
--- a/ui/base/win/open_file_name_win.cc
+++ b/ui/base/win/open_file_name_win.cc
@@ -86,15 +86,15 @@
 }
 
 void OpenFileName::SetFilters(
-    const std::vector<base::Tuple<base::string16, base::string16>>& filters) {
+    const std::vector<std::tuple<base::string16, base::string16>>& filters) {
   openfilename_.lpstrFilter = NULL;
   filter_buffer_.clear();
   if (filters.empty())
     return;
   for (const auto& filter : filters) {
-    filter_buffer_.append(base::get<0>(filter));
+    filter_buffer_.append(std::get<0>(filter));
     filter_buffer_.push_back(0);
-    filter_buffer_.append(base::get<1>(filter));
+    filter_buffer_.append(std::get<1>(filter));
     filter_buffer_.push_back(0);
   }
   filter_buffer_.push_back(0);
@@ -203,9 +203,9 @@
 }
 
 // static
-std::vector<base::Tuple<base::string16, base::string16>>
+std::vector<std::tuple<base::string16, base::string16>>
 OpenFileName::GetFilters(const OPENFILENAME* openfilename) {
-  std::vector<base::Tuple<base::string16, base::string16>> filters;
+  std::vector<std::tuple<base::string16, base::string16>> filters;
 
   const base::char16* display_string = openfilename->lpstrFilter;
   if (!display_string)
@@ -220,7 +220,7 @@
     while (*pattern_end)
       ++pattern_end;
     filters.push_back(
-        base::MakeTuple(base::string16(display_string, display_string_end),
+        std::make_tuple(base::string16(display_string, display_string_end),
                   base::string16(pattern, pattern_end)));
     display_string = pattern_end + 1;
   }
diff --git a/ui/base/win/open_file_name_win.h b/ui/base/win/open_file_name_win.h
index 596b147..5d0b028e 100644
--- a/ui/base/win/open_file_name_win.h
+++ b/ui/base/win/open_file_name_win.h
@@ -8,11 +8,11 @@
 #include <Windows.h>
 #include <Commdlg.h>
 
+#include <tuple>
 #include <vector>
 
 #include "base/macros.h"
 #include "base/strings/string16.h"
-#include "base/tuple.h"
 #include "ui/base/ui_base_export.h"
 
 namespace base {
@@ -34,7 +34,7 @@
 
   // Initializes |lpstrFilter| from the label/pattern pairs in |filters|.
   void SetFilters(
-      const std::vector<base::Tuple<base::string16, base::string16>>& filters);
+      const std::vector<std::tuple<base::string16, base::string16>>& filters);
 
   // Sets |lpstrInitialDir| and |lpstrFile|.
   void SetInitialSelection(const base::FilePath& initial_directory,
@@ -68,7 +68,7 @@
 
   // Returns a vector of label/pattern pairs built from
   // |openfilename->lpstrFilter|.
-  static std::vector<base::Tuple<base::string16, base::string16>> GetFilters(
+  static std::vector<std::tuple<base::string16, base::string16>> GetFilters(
       const OPENFILENAME* openfilename);
 
  private:
diff --git a/ui/base/win/open_file_name_win_unittest.cc b/ui/base/win/open_file_name_win_unittest.cc
index 36de27fa..bce8abc 100644
--- a/ui/base/win/open_file_name_win_unittest.cc
+++ b/ui/base/win/open_file_name_win_unittest.cc
@@ -30,8 +30,8 @@
 }
 
 void CheckFilters(
-    const std::vector<base::Tuple<base::string16, base::string16>>& expected,
-    const std::vector<base::Tuple<base::string16, base::string16>>& actual) {
+    const std::vector<std::tuple<base::string16, base::string16>>& expected,
+    const std::vector<std::tuple<base::string16, base::string16>>& actual) {
   if (expected.size() != actual.size()) {
     ADD_FAILURE() << "filter count mismatch. Got " << actual.size()
                   << " expected " << expected.size() << ".";
@@ -39,9 +39,9 @@
   }
 
   for (size_t i = 0; i < expected.size(); ++i) {
-    EXPECT_EQ(base::get<0>(expected[i]), base::get<0>(actual[i]))
+    EXPECT_EQ(std::get<0>(expected[i]), std::get<0>(actual[i]))
         << "Mismatch at index " << i;
-    EXPECT_EQ(base::get<1>(expected[i]), base::get<1>(actual[i]))
+    EXPECT_EQ(std::get<1>(expected[i]), std::get<1>(actual[i]))
         << "Mismatch at index " << i;
   }
 }
@@ -206,19 +206,21 @@
   const base::string16 kNull(L"\0", 1);
 
   ui::win::OpenFileName ofn(kHwnd, kFlags);
-  std::vector<base::Tuple<base::string16, base::string16>> filters;
+  std::vector<std::tuple<base::string16, base::string16>> filters;
   ofn.SetFilters(filters);
   EXPECT_FALSE(ofn.GetOPENFILENAME()->lpstrFilter);
   CheckFilters(filters,
                ui::win::OpenFileName::GetFilters(ofn.GetOPENFILENAME()));
 
-  filters.push_back(base::MakeTuple(base::string16(L"a"), base::string16(L"b")));
+  filters.push_back(
+      std::make_tuple(base::string16(L"a"), base::string16(L"b")));
   ofn.SetFilters(filters);
   CheckFilterString(L"a" + kNull + L"b" + kNull, ofn);
   CheckFilters(filters,
                ui::win::OpenFileName::GetFilters(ofn.GetOPENFILENAME()));
 
-  filters.push_back(base::MakeTuple(base::string16(L"X"), base::string16(L"Y")));
+  filters.push_back(
+      std::make_tuple(base::string16(L"X"), base::string16(L"Y")));
   ofn.SetFilters(filters);
   CheckFilterString(L"a" + kNull + L"b" + kNull + L"X" + kNull + L"Y" + kNull,
                     ofn);
diff --git a/ui/file_manager/gallery/js/image_editor/image_editor.js b/ui/file_manager/gallery/js/image_editor/image_editor.js
index 9040fe6..7886029 100644
--- a/ui/file_manager/gallery/js/image_editor/image_editor.js
+++ b/ui/file_manager/gallery/js/image_editor/image_editor.js
@@ -301,6 +301,7 @@
   this.leaveModeInternal_(false, false /* not to switch mode */);
   this.commandQueue_.undo();
   this.updateUndoRedo();
+  this.calculateModeApplicativity_();
 };
 
 /**
@@ -313,6 +314,7 @@
   this.leaveModeInternal_(false, false /* not to switch mode */);
   this.commandQueue_.redo();
   this.updateUndoRedo();
+  this.calculateModeApplicativity_();
 };
 
 /**
@@ -635,6 +637,7 @@
 
   this.currentMode_.setUp();
 
+  this.calculateModeApplicativity_();
   if (this.currentMode_.instant) {  // Instant tool.
     this.leaveModeInternal_(true, false /* not to switch mode */);
     return;
@@ -645,7 +648,6 @@
   this.modeToolbar_.clear();
   this.currentMode_.createTools(this.modeToolbar_);
   this.modeToolbar_.show(true);
-  this.calculateModeApplicativity_();
 };
 
 /**
@@ -810,6 +812,13 @@
 };
 
 /**
+ * Called when the user starts editing image.
+ */
+ImageEditor.prototype.onStartEditing = function() {
+  this.calculateModeApplicativity_();
+};
+
+/**
  * A helper object for panning the ImageBuffer.
  *
  * @param {!HTMLElement} rootContainer The top-level container.
diff --git a/ui/file_manager/gallery/js/slide_mode.js b/ui/file_manager/gallery/js/slide_mode.js
index 1c0ba4a..dcad955 100644
--- a/ui/file_manager/gallery/js/slide_mode.js
+++ b/ui/file_manager/gallery/js/slide_mode.js
@@ -1643,6 +1643,7 @@
     }.bind(this));
 
     this.setSubMode_(Gallery.SubMode.EDIT);
+    this.editor_.onStartEditing();
   } else {
     this.editor_.getPrompt().hide();
     this.editor_.leaveMode(false /* not to switch mode */);
diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc
index 2e3c96f8..a4618f2 100644
--- a/ui/gfx/color_utils.cc
+++ b/ui/gfx/color_utils.cc
@@ -42,35 +42,21 @@
   else if (hue * 3.0 < 2.0)
     result = temp1 + (temp2 - temp1) * (2.0 / 3.0 - hue) * 6.0;
 
-  // Scale the result from 0 - 255 and round off the value.
-  return static_cast<int>(result * 255 + .5);
+  return static_cast<int>(std::round(result * 255));
 }
 
-// Next two functions' formulas from:
-// http://www.w3.org/TR/WCAG20/#relativeluminancedef
-// http://www.w3.org/TR/WCAG20/#contrast-ratiodef
-
-double ConvertSRGB(double eight_bit_component) {
+// Assumes sRGB.
+double Linearize(double eight_bit_component) {
   const double component = eight_bit_component / 255.0;
   return (component <= 0.03928) ?
       (component / 12.92) : pow((component + 0.055) / 1.055, 2.4);
 }
 
-SkColor LumaInvertColor(SkColor color) {
+SkColor LightnessInvertColor(SkColor color) {
   HSL hsl;
   SkColorToHSL(color, &hsl);
   hsl.l = 1.0 - hsl.l;
-  return HSLToSkColor(hsl, 255);
-}
-
-double ContrastRatio(double foreground_luminance, double background_luminance) {
-  DCHECK_GE(foreground_luminance, 0.0);
-  DCHECK_GE(background_luminance, 0.0);
-  foreground_luminance += 0.05;
-  background_luminance += 0.05;
-  return (foreground_luminance > background_luminance) ?
-      (foreground_luminance / background_luminance) :
-      (background_luminance / foreground_luminance);
+  return HSLToSkColor(hsl, SkColorGetA(color));
 }
 
 }  // namespace
@@ -79,20 +65,29 @@
 // ----------------------------------------------------------------------------
 
 double GetContrastRatio(SkColor color_a, SkColor color_b) {
-  return ContrastRatio(RelativeLuminance(color_a), RelativeLuminance(color_b));
+  return GetContrastRatio(GetRelativeLuminance(color_a),
+                          GetRelativeLuminance(color_b));
 }
 
-unsigned char GetLuminanceForColor(SkColor color) {
-  return base::saturated_cast<unsigned char>(
-      (0.3 * SkColorGetR(color)) +
-      (0.59 * SkColorGetG(color)) +
-      (0.11 * SkColorGetB(color)));
+double GetContrastRatio(double luminance_a, double luminance_b) {
+  DCHECK_GE(luminance_a, 0.0);
+  DCHECK_GE(luminance_b, 0.0);
+  luminance_a += 0.05;
+  luminance_b += 0.05;
+  return (luminance_a > luminance_b) ? (luminance_a / luminance_b)
+                                     : (luminance_b / luminance_a);
 }
 
-double RelativeLuminance(SkColor color) {
-  return (0.2126 * ConvertSRGB(SkColorGetR(color))) +
-         (0.7152 * ConvertSRGB(SkColorGetG(color))) +
-         (0.0722 * ConvertSRGB(SkColorGetB(color)));
+double GetRelativeLuminance(SkColor color) {
+  return (0.2126 * Linearize(SkColorGetR(color))) +
+         (0.7152 * Linearize(SkColorGetG(color))) +
+         (0.0722 * Linearize(SkColorGetB(color)));
+}
+
+uint8_t GetLuma(SkColor color) {
+  return static_cast<uint8_t>(std::round((0.299 * SkColorGetR(color)) +
+                                         (0.587 * SkColorGetG(color)) +
+                                         (0.114 * SkColorGetB(color))));
 }
 
 void SkColorToHSL(SkColor c, HSL* hsl) {
@@ -242,7 +237,7 @@
   int pixel_height = bitmap.height();
   for (int y = 0; y < pixel_height; ++y) {
     for (int x = 0; x < pixel_width; ++x)
-      ++histogram[GetLuminanceForColor(bitmap.getColor(x, y))];
+      ++histogram[GetLuma(bitmap.getColor(x, y))];
   }
 }
 
@@ -287,20 +282,28 @@
 }
 
 bool IsDark(SkColor color) {
-  return GetLuminanceForColor(color) < 128;
+  return GetLuma(color) < 128;
 }
 
-SkColor BlendTowardOppositeLuminance(SkColor color, SkAlpha alpha) {
+SkColor BlendTowardOppositeLuma(SkColor color, SkAlpha alpha) {
   return AlphaBlend(IsDark(color) ? SK_ColorWHITE : SK_ColorBLACK, color,
                     alpha);
 }
 
 SkColor GetReadableColor(SkColor foreground, SkColor background) {
-  const SkColor foreground2 = LumaInvertColor(foreground);
-  const double background_luminance = RelativeLuminance(background);
-  return (ContrastRatio(RelativeLuminance(foreground), background_luminance) >=
-          ContrastRatio(RelativeLuminance(foreground2), background_luminance)) ?
-      foreground : foreground2;
+  return PickContrastingColor(foreground, LightnessInvertColor(foreground),
+                              background);
+}
+
+SkColor PickContrastingColor(SkColor foreground1,
+                             SkColor foreground2,
+                             SkColor background) {
+  const double background_luminance = GetRelativeLuminance(background);
+  return (GetContrastRatio(GetRelativeLuminance(foreground1),
+                           background_luminance) >=
+          GetContrastRatio(GetRelativeLuminance(foreground2),
+                           background_luminance)) ?
+      foreground1 : foreground2;
 }
 
 SkColor InvertColor(SkColor color) {
diff --git a/ui/gfx/color_utils.h b/ui/gfx/color_utils.h
index 44302c8..fc8b446 100644
--- a/ui/gfx/color_utils.h
+++ b/ui/gfx/color_utils.h
@@ -23,13 +23,21 @@
 // This value is taken from w3c accessibility guidelines.
 const double kMinimumReadableContrastRatio = 4.5f;
 
-// Determines the contrast ratio of two colors.
+// Determines the contrast ratio of two colors or two relative luminance values
+// (as computed by RelativeLuminance()), calculated according to
+// http://www.w3.org/TR/WCAG20/#contrast-ratiodef .
 GFX_EXPORT double GetContrastRatio(SkColor color_a, SkColor color_b);
+GFX_EXPORT double GetContrastRatio(double luminance_a, double luminance_b);
 
-GFX_EXPORT unsigned char GetLuminanceForColor(SkColor color);
+// The relative luminance of |color|, that is, the weighted sum of the
+// linearized RGB components, normalized to 0..1, per BT.709.  See
+// http://www.w3.org/TR/WCAG20/#relativeluminancedef .
+GFX_EXPORT double GetRelativeLuminance(SkColor color);
 
-// Calculated according to http://www.w3.org/TR/WCAG20/#relativeluminancedef
-GFX_EXPORT double RelativeLuminance(SkColor color);
+// The luma of |color|, that is, the weighted sum of the gamma-compressed R'G'B'
+// components, per BT.601, a.k.a. the Y' in Y'UV.  See
+// https://en.wikipedia.org/wiki/Luma_(video).
+GFX_EXPORT uint8_t GetLuma(SkColor color);
 
 // Note: these transformations assume sRGB as the source color space
 GFX_EXPORT void SkColorToHSL(SkColor c, HSL* hsl);
@@ -50,8 +58,8 @@
                                  const HSL& upper_bound);
 
 // Makes |hsl| valid input for HSLShift(). Sets values of hue, saturation
-// and luminosity which are outside of the valid range [0, 1] to -1.
-// -1 is a special value which indicates 'no change'.
+// and lightness which are outside of the valid range [0, 1] to -1.  -1 is a
+// special value which indicates 'no change'.
 GFX_EXPORT void MakeHSLShiftValid(HSL* hsl);
 
 // HSL-Shift an SkColor. The shift values are in the range of 0-1, with the
@@ -70,8 +78,7 @@
 //    1 = full lightness (make all pixels white).
 GFX_EXPORT SkColor HSLShift(SkColor color, const HSL& shift);
 
-// Builds a histogram based on the Y' of the Y'UV representation of
-// this image.
+// Builds a histogram based on the Y' of the Y'UV representation of this image.
 GFX_EXPORT void BuildLumaHistogram(const SkBitmap& bitmap, int histogram[256]);
 
 // Calculates how "boring" an image is. The boring score is the
@@ -87,25 +94,30 @@
 GFX_EXPORT SkColor AlphaBlend(SkColor foreground, SkColor background,
                               SkAlpha alpha);
 
-// Returns true if the luminance of |color| is closer to black than white.
+// Returns true if the luma of |color| is closer to black than white.
 GFX_EXPORT bool IsDark(SkColor color);
 
 // Makes a dark color lighter or a light color darker by blending |color| with
-// white or black depending on its current luminance.  |alpha| controls the
-// amount of white or black that will be alpha-blended into |color|.
-GFX_EXPORT SkColor BlendTowardOppositeLuminance(SkColor color, SkAlpha alpha);
+// white or black depending on its current luma.  |alpha| controls the amount of
+// white or black that will be alpha-blended into |color|.
+GFX_EXPORT SkColor BlendTowardOppositeLuma(SkColor color, SkAlpha alpha);
 
-// Given an opaque foreground and background color, try to return a foreground
-// color that is "readable" over the background color by luma-inverting the
-// foreground color and then picking whichever foreground color has higher
-// contrast against the background color.  You should not pass colors with
-// non-255 alpha to this routine, since determining the correct behavior in such
-// cases can be impossible.
+// Given a foreground and background color, try to return a foreground color
+// that is "readable" over the background color by luma-inverting the foreground
+// color and then using PickContrastingColor() to pick the one with greater
+// contrast.  During this process, alpha values will be ignored; the returned
+// color will have the same alpha as |foreground|.
 //
 // NOTE: This won't do anything but waste time if the supplied foreground color
 // has a luma value close to the midpoint (0.5 in the HSL representation).
 GFX_EXPORT SkColor GetReadableColor(SkColor foreground, SkColor background);
 
+// Returns whichever of |foreground1| or |foreground2| has higher contrast with
+// |background|.
+GFX_EXPORT SkColor PickContrastingColor(SkColor foreground1,
+                                        SkColor foreground2,
+                                        SkColor background);
+
 // Invert a color.
 GFX_EXPORT SkColor InvertColor(SkColor color);
 
diff --git a/ui/gfx/sys_color_change_listener.cc b/ui/gfx/sys_color_change_listener.cc
index a814096..fcda189 100644
--- a/ui/gfx/sys_color_change_listener.cc
+++ b/ui/gfx/sys_color_change_listener.cc
@@ -20,16 +20,16 @@
 bool g_is_inverted_color_scheme_initialized = false;
 
 void UpdateInvertedColorScheme() {
-  int foreground_luminance = color_utils::GetLuminanceForColor(
-      color_utils::GetSysSkColor(COLOR_WINDOWTEXT));
-  int background_luminance = color_utils::GetLuminanceForColor(
-      color_utils::GetSysSkColor(COLOR_WINDOW));
+  const uint8_t foreground_luma =
+      color_utils::GetLuma(color_utils::GetSysSkColor(COLOR_WINDOWTEXT));
+  const uint8_t background_luma =
+      color_utils::GetLuma(color_utils::GetSysSkColor(COLOR_WINDOW));
   HIGHCONTRAST high_contrast = {0};
   high_contrast.cbSize = sizeof(HIGHCONTRAST);
   g_is_inverted_color_scheme =
       SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &high_contrast, 0) &&
       ((high_contrast.dwFlags & HCF_HIGHCONTRASTON) != 0) &&
-      foreground_luminance > background_luminance;
+      foreground_luma > background_luma;
   g_is_inverted_color_scheme_initialized = true;
 }
 
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc
index a95de2b..c8664ed 100644
--- a/ui/message_center/views/message_center_view.cc
+++ b/ui/message_center/views/message_center_view.cc
@@ -148,7 +148,7 @@
       views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
 
   scroller_->SetPaintToLayer(true);
-  scroller_->SetFillsBoundsOpaquely(false);
+  scroller_->layer()->SetFillsBoundsOpaquely(false);
   scroller_->layer()->SetMasksToBounds(true);
 
   empty_list_view_.reset(new NoNotificationMessageView);
diff --git a/ui/ozone/platform/cast/cast.gypi b/ui/ozone/platform/cast/cast.gypi
index ae875b4..a0dbd6e1 100644
--- a/ui/ozone/platform/cast/cast.gypi
+++ b/ui/ozone/platform/cast/cast.gypi
@@ -4,6 +4,7 @@
 
 {
   'variables': {
+    'disable_display%': 0,
     'internal_ozone_platform_deps': [
       'ozone_platform_cast',
     ],
diff --git a/ui/shell_dialogs/select_file_dialog_win.cc b/ui/shell_dialogs/select_file_dialog_win.cc
index cbccd3a..dafe050 100644
--- a/ui/shell_dialogs/select_file_dialog_win.cc
+++ b/ui/shell_dialogs/select_file_dialog_win.cc
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 #include <set>
+#include <tuple>
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
@@ -17,7 +18,6 @@
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread.h"
-#include "base/tuple.h"
 #include "base/win/registry.h"
 #include "base/win/scoped_comptr.h"
 #include "base/win/shortcut.h"
@@ -457,12 +457,12 @@
   // Figure out what filter got selected. The filter index is 1-based.
   std::wstring filter_selected;
   if (*index > 0) {
-    std::vector<base::Tuple<base::string16, base::string16>> filters =
+    std::vector<std::tuple<base::string16, base::string16>> filters =
         ui::win::OpenFileName::GetFilters(save_as.GetOPENFILENAME());
     if (*index > filters.size())
       NOTREACHED() << "Invalid filter index.";
     else
-      filter_selected = base::get<1>(filters[*index - 1]);
+      filter_selected = std::get<1>(filters[*index - 1]);
   }
 
   // Get the extension that was suggested to the user (when the Save As dialog
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 7c957c32..8ef6465 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -227,6 +227,7 @@
     "//ui/gfx:test_support",
     "//ui/gfx/geometry",
     "//ui/gl:test_support",
+    "//ui/native_theme",
     "//ui/resources",
     "//ui/strings",
     "//url",
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc
index 8e5c3ce2d..bd219a0 100644
--- a/ui/views/animation/ink_drop_host_view.cc
+++ b/ui/views/animation/ink_drop_host_view.cc
@@ -22,7 +22,7 @@
 
 void InkDropHostView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
   layer()->Add(ink_drop_layer);
   layer()->StackAtBottom(ink_drop_layer);
 }
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc
index 4e891b7..ad3267f 100644
--- a/ui/views/bubble/tray_bubble_view.cc
+++ b/ui/views/bubble/tray_bubble_view.cc
@@ -333,7 +333,6 @@
   set_close_on_deactivate(init_params.close_on_deactivate);
   set_margins(gfx::Insets());
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(true);
 
   bubble_content_mask_.reset(
       new TrayBubbleContentMask(bubble_border_->GetBorderCornerRadius()));
@@ -507,7 +506,6 @@
     const ViewHierarchyChangedDetails& details) {
   if (details.is_add && details.child == this) {
     details.parent->SetPaintToLayer(true);
-    details.parent->SetFillsBoundsOpaquely(true);
     details.parent->layer()->SetMasksToBounds(true);
   }
 }
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index f192e12..6809b2d 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -97,7 +97,7 @@
 
   AddChildView(ink_drop_container_);
   ink_drop_container_->SetPaintToLayer(true);
-  ink_drop_container_->SetFillsBoundsOpaquely(false);
+  ink_drop_container_->layer()->SetFillsBoundsOpaquely(false);
   ink_drop_container_->SetVisible(false);
 
   AddChildView(image_);
@@ -407,7 +407,7 @@
 
 void LabelButton::AddInkDropLayer(ui::Layer* ink_drop_layer) {
   image()->SetPaintToLayer(true);
-  image()->SetFillsBoundsOpaquely(false);
+  image()->layer()->SetFillsBoundsOpaquely(false);
   ink_drop_container_->SetVisible(true);
   ink_drop_container_->layer()->Add(ink_drop_layer);
 }
@@ -420,8 +420,6 @@
 
 scoped_ptr<views::InkDropAnimation> LabelButton::CreateInkDropAnimation()
     const {
-  // TODO(bruthig): Make the flood fill ink drops centered on the LocatedEvent
-  // that triggered them.
   return GetText().empty()
              ? CustomButton::CreateInkDropAnimation()
              : make_scoped_ptr(new views::FloodFillInkDropAnimation(
@@ -437,6 +435,13 @@
                    size(), 0, GetInkDropCenter(), GetInkDropBaseColor()));
 }
 
+gfx::Point LabelButton::GetInkDropCenter() const {
+  // TODO(bruthig): Make the flood fill ink drops centered on the LocatedEvent
+  // that triggered them.
+  return GetText().empty() ? image()->GetMirroredBounds().CenterPoint()
+                           : CustomButton::GetInkDropCenter();
+}
+
 void LabelButton::StateChanged() {
   const gfx::Size previous_image_size(image_->GetPreferredSize());
   UpdateImage();
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h
index eee771e..9d6b9d3 100644
--- a/ui/views/controls/button/label_button.h
+++ b/ui/views/controls/button/label_button.h
@@ -105,6 +105,7 @@
   void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override;
   scoped_ptr<InkDropAnimation> CreateInkDropAnimation() const override;
   scoped_ptr<InkDropHover> CreateInkDropHover() const override;
+  gfx::Point GetInkDropCenter() const override;
 
  protected:
   ImageView* image() const { return image_; }
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index 75263173..3bbb045 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -2638,8 +2638,12 @@
 }
 
 void MenuController::SetHotTrackedButton(CustomButton* hot_button) {
-  if (hot_button == hot_button_)
+  if (hot_button == hot_button_) {
+    // Hot-tracked state may change outside of the MenuController. Correct it.
+    if (hot_button && !hot_button->IsHotTracked())
+      hot_button->SetHotTracked(true);
     return;
+  }
   if (hot_button_)
     hot_button_->SetHotTracked(false);
   hot_button_ = hot_button;
diff --git a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
index 7f8bae81..6eb38d4 100644
--- a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
+++ b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
@@ -75,7 +75,7 @@
   // This is necessary, otherwise the thumb will be rendered below the views if
   // those views paint to their own layers.
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 CocoaScrollBarThumb::~CocoaScrollBarThumb() {}
diff --git a/ui/views/controls/scrollbar/overlay_scroll_bar.cc b/ui/views/controls/scrollbar/overlay_scroll_bar.cc
index fa720668..8da5f7d4 100644
--- a/ui/views/controls/scrollbar/overlay_scroll_bar.cc
+++ b/ui/views/controls/scrollbar/overlay_scroll_bar.cc
@@ -48,7 +48,7 @@
   // This is necessary, otherwise the thumb will be rendered below the views if
   // those views paint to their own layers.
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 OverlayScrollBarThumb::~OverlayScrollBarThumb() {
diff --git a/ui/views/controls/slide_out_view.cc b/ui/views/controls/slide_out_view.cc
index adf1b119..2775c088 100644
--- a/ui/views/controls/slide_out_view.cc
+++ b/ui/views/controls/slide_out_view.cc
@@ -14,7 +14,7 @@
   // If accelerated compositing is not available, this widget tracks the
   // OnSlideOut event but does not render any visible changes.
   SetPaintToLayer(true);
-  SetFillsBoundsOpaquely(false);
+  layer()->SetFillsBoundsOpaquely(false);
 }
 
 SlideOutView::~SlideOutView() {
diff --git a/ui/views/view.cc b/ui/views/view.cc
index e2139e8..9edda26 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -178,11 +178,25 @@
   // Sets the prev/next focus views.
   InitFocusSiblings(view, index);
 
-  // Let's insert the view.
   view->parent_ = this;
   children_.insert(children_.begin() + index, view);
 
-  views::Widget* widget = GetWidget();
+  // Ensure the layer tree matches the view tree before calling to any client
+  // code. This way if client code further modifies the view tree we are in a
+  // sane state.
+  const bool did_reparent_any_layers = view->UpdateParentLayers();
+  Widget* widget = GetWidget();
+  if (did_reparent_any_layers && widget)
+    widget->UpdateRootLayers();
+
+  ReorderLayers();
+
+  // Make sure the visibility of the child layers are correct.
+  // If any of the parent View is hidden, then the layers of the subtree
+  // rooted at |this| should be hidden. Otherwise, all the child layers should
+  // inherit the visibility of the owner View.
+  view->UpdateLayerVisibility();
+
   if (widget) {
     const ui::NativeTheme* new_theme = view->GetNativeTheme();
     if (new_theme != old_theme)
@@ -195,23 +209,18 @@
     v->ViewHierarchyChangedImpl(false, details);
 
   view->PropagateAddNotifications(details);
+
   UpdateTooltip();
+
   if (widget) {
     RegisterChildrenForVisibleBoundsNotification(view);
+
     if (view->visible())
       view->SchedulePaint();
   }
 
   if (layout_manager_.get())
     layout_manager_->ViewAdded(this, view);
-
-  ReorderLayers();
-
-  // Make sure the visibility of the child layers are correct.
-  // If any of the parent View is hidden, then the layers of the subtree
-  // rooted at |this| should be hidden. Otherwise, all the child layers should
-  // inherit the visibility of the owner View.
-  UpdateLayerVisibility();
 }
 
 void View::ReorderChildView(View* view, int index) {
@@ -1437,12 +1446,6 @@
 
 // Accelerated Painting --------------------------------------------------------
 
-void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
-  // This method should not have the side-effect of creating the layer.
-  if (layer())
-    layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely);
-}
-
 gfx::Vector2d View::CalculateOffsetToAncestorWithLayer(
     ui::Layer** layer_parent) {
   if (layer()) {
@@ -1806,42 +1809,47 @@
   DCHECK(view);
 
   const Views::iterator i(std::find(children_.begin(), children_.end(), view));
+  if (i == children_.end())
+    return;
+
   scoped_ptr<View> view_to_be_deleted;
-  if (i != children_.end()) {
-    if (update_focus_cycle) {
-      // Let's remove the view from the focus traversal.
-      View* next_focusable = view->next_focusable_view_;
-      View* prev_focusable = view->previous_focusable_view_;
-      if (prev_focusable)
-        prev_focusable->next_focusable_view_ = next_focusable;
-      if (next_focusable)
-        next_focusable->previous_focusable_view_ = prev_focusable;
-    }
-
-    Widget* widget = GetWidget();
-    if (widget) {
-      UnregisterChildrenForVisibleBoundsNotification(view);
-      if (view->visible())
-        view->SchedulePaint();
-
-      if (!new_parent || new_parent->GetWidget() != widget)
-        widget->NotifyWillRemoveView(view);
-    }
-
-    view->PropagateRemoveNotifications(this, new_parent);
-    view->parent_ = NULL;
-    view->UpdateLayerVisibility();
-
-    if (delete_removed_view && !view->owned_by_client_)
-      view_to_be_deleted.reset(view);
-
-    children_.erase(i);
+  if (update_focus_cycle) {
+    View* next_focusable = view->next_focusable_view_;
+    View* prev_focusable = view->previous_focusable_view_;
+    if (prev_focusable)
+      prev_focusable->next_focusable_view_ = next_focusable;
+    if (next_focusable)
+      next_focusable->previous_focusable_view_ = prev_focusable;
   }
 
+  Widget* widget = GetWidget();
+  if (widget) {
+    UnregisterChildrenForVisibleBoundsNotification(view);
+    if (view->visible())
+      view->SchedulePaint();
+
+    if (!new_parent || new_parent->GetWidget() != widget)
+      widget->NotifyWillRemoveView(view);
+  }
+
+  // Make sure the layers belonging to the subtree rooted at |view| get
+  // removed.
+  view->OrphanLayers();
+  if (widget)
+    widget->UpdateRootLayers();
+
+  view->PropagateRemoveNotifications(this, new_parent);
+  view->parent_ = nullptr;
+
+  if (delete_removed_view && !view->owned_by_client_)
+    view_to_be_deleted.reset(view);
+
+  children_.erase(i);
+
   if (update_tool_tip)
     UpdateTooltip();
 
-  if (layout_manager_.get())
+  if (layout_manager_)
     layout_manager_->ViewRemoved(this, view);
 }
 
@@ -1882,20 +1890,6 @@
     }
   }
 
-  if (details.is_add && layer() && !layer()->parent()) {
-    UpdateParentLayer();
-    Widget* widget = GetWidget();
-    if (widget)
-      widget->UpdateRootLayers();
-  } else if (!details.is_add && details.child == this) {
-    // Make sure the layers belonging to the subtree rooted at |child| get
-    // removed from layers that do not belong in the same subtree.
-    OrphanLayers();
-    Widget* widget = GetWidget();
-    if (widget)
-      widget->UpdateRootLayers();
-  }
-
   ViewHierarchyChanged(details);
   details.parent->needs_layout_ = true;
 }
@@ -2120,14 +2114,23 @@
   SchedulePaintOnParent();
 }
 
-void View::UpdateParentLayers() {
+bool View::UpdateParentLayers() {
   // Attach all top-level un-parented layers.
-  if (layer() && !layer()->parent()) {
-    UpdateParentLayer();
-  } else {
-    for (int i = 0, count = child_count(); i < count; ++i)
-      child_at(i)->UpdateParentLayers();
+  if (layer()) {
+    if (!layer()->parent()) {
+      UpdateParentLayer();
+      return true;
+    }
+    // The layers of any child views are already in place, so we can stop
+    // iterating here.
+    return false;
   }
+  bool result = false;
+  for (int i = 0, count = child_count(); i < count; ++i) {
+    if (child_at(i)->UpdateParentLayers())
+      result = true;
+  }
+  return result;
 }
 
 void View::OrphanLayers() {
diff --git a/ui/views/view.h b/ui/views/view.h
index 86bed2a..897160ea 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -295,13 +295,6 @@
   // Returns whether the view is enabled.
   bool enabled() const { return enabled_; }
 
-  // This indicates that the view completely fills its bounds in an opaque
-  // color. This doesn't affect compositing but is a hint to the compositor to
-  // optimize painting.
-  // Note that this method does not implicitly create a layer if one does not
-  // already exist for the View, but is a no-op in that case.
-  void SetFillsBoundsOpaquely(bool fills_bounds_opaquely);
-
   // Transformations -----------------------------------------------------------
 
   // Methods for setting transformations for a view (e.g. rotation, scaling).
@@ -1348,9 +1341,11 @@
   // Creates the layer and related fields for this view.
   void CreateLayer();
 
-  // Parents all un-parented layers within this view's hierarchy to this view's
-  // layer.
-  void UpdateParentLayers();
+  // Recursively calls UpdateParentLayers() on all descendants, stopping at any
+  // Views that have layers. Calls UpdateParentLayer() for any Views that have
+  // a layer with no parent. If at least one descendant had an unparented layer
+  // true is returned.
+  bool UpdateParentLayers();
 
   // Parents this view's layer to |parent_layer|, and sets its bounds and other
   // properties in accordance to |offset|, the view's offset from the
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index 76b9950..7d7000017 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -31,6 +31,7 @@
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/path.h"
 #include "ui/gfx/transform.h"
+#include "ui/native_theme/native_theme.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/native/native_view_host.h"
@@ -4473,4 +4474,96 @@
   EXPECT_EQ(ui::ET_MOUSE_RELEASED, v->last_mouse_event_type_);
 }
 
+// See comment above test for details.
+class WidgetWithCustomTheme : public Widget {
+ public:
+  explicit WidgetWithCustomTheme(ui::NativeTheme* theme) : theme_(theme) {}
+  ~WidgetWithCustomTheme() override {}
+
+  // Widget:
+  const ui::NativeTheme* GetNativeTheme() const override { return theme_; }
+
+ private:
+  ui::NativeTheme* theme_;
+
+  DISALLOW_COPY_AND_ASSIGN(WidgetWithCustomTheme);
+};
+
+// See comment above test for details.
+class ViewThatAddsViewInOnNativeThemeChanged : public View {
+ public:
+  ViewThatAddsViewInOnNativeThemeChanged() { SetPaintToLayer(true); }
+  ~ViewThatAddsViewInOnNativeThemeChanged() override {}
+
+  bool on_native_theme_changed_called() const {
+    return on_native_theme_changed_called_;
+  }
+
+  // View:
+  void OnNativeThemeChanged(const ui::NativeTheme* theme) override {
+    on_native_theme_changed_called_ = true;
+    GetWidget()->GetRootView()->AddChildView(new View);
+  }
+
+ private:
+  bool on_native_theme_changed_called_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(ViewThatAddsViewInOnNativeThemeChanged);
+};
+
+// See comment above test for details.
+class TestNativeTheme : public ui::NativeTheme {
+ public:
+  TestNativeTheme() {}
+  ~TestNativeTheme() override {}
+
+  // ui::NativeTheme:
+  SkColor GetSystemColor(ColorId color_id) const override {
+    return SK_ColorRED;
+  }
+  gfx::Size GetPartSize(Part part,
+                        State state,
+                        const ExtraParams& extra) const override {
+    return gfx::Size();
+  }
+  void Paint(SkCanvas* canvas,
+             Part part,
+             State state,
+             const gfx::Rect& rect,
+             const ExtraParams& extra) const override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestNativeTheme);
+};
+
+// Creates and adds a new child view to |parent| that has a layer.
+void AddViewWithChildLayer(View* parent) {
+  View* child = new View;
+  child->SetPaintToLayer(true);
+  parent->AddChildView(child);
+}
+
+// This test does the following:
+// . creates a couple of views with layers added to the root.
+// . Add a view that overrides OnNativeThemeChanged(). In
+//   OnNativeThemeChanged() another view is added.
+// This sequence triggered DCHECKs or crashes previously. This tests verifies
+// that doesn't happen. Reason for crash was OnNativeThemeChanged() was called
+// before the layer hierarchy was updated. OnNativeThemeChanged() should be
+// called after the layer hierarchy matches the view hierarchy.
+TEST_F(ViewTest, CrashOnAddFromFromOnNativeThemeChanged) {
+  TestNativeTheme theme;
+  WidgetWithCustomTheme widget(&theme);
+  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.bounds = gfx::Rect(50, 50, 350, 350);
+  widget.Init(params);
+
+  AddViewWithChildLayer(widget.GetRootView());
+  ViewThatAddsViewInOnNativeThemeChanged* v =
+      new ViewThatAddsViewInOnNativeThemeChanged;
+  widget.GetRootView()->AddChildView(v);
+  EXPECT_TRUE(v->on_native_theme_changed_called());
+}
+
 }  // namespace views
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index 584513d..68298e5c 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -868,6 +868,7 @@
         '../events/events.gyp:events_test_support',
         '../gfx/gfx.gyp:gfx',
         '../gfx/gfx.gyp:gfx_geometry',
+        '../native_theme/native_theme.gyp:native_theme',
         '../resources/ui_resources.gyp:ui_resources',
         '../resources/ui_resources.gyp:ui_test_pak',
         '../strings/ui_strings.gyp:ui_strings',
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index a7ab121..3e8015af 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -3270,7 +3270,8 @@
 // 1. Posting a WM_NCMOUSEMOVE message for a different location.
 // 2. Posting a WM_NCMOUSEMOVE message with a different hittest code.
 // 3. Posting a WM_MOUSEMOVE message.
-TEST_F(WidgetTest, SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
+// Disabled because of flaky timeouts: http://crbug.com/592742
+TEST_F(WidgetTest, DISABLED_SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
   Widget widget;
   Widget::InitParams params =
       CreateParams(Widget::InitParams::TYPE_WINDOW);
@@ -3343,7 +3344,8 @@
 
 // This test validates that destroying the window in the context of the
 // WM_SYSCOMMAND message with SC_MOVE does not crash.
-TEST_F(WidgetTest, DestroyInSysCommandNCLButtonDownOnCaption) {
+// Disabled because of flaky timeouts: http://crbug.com/592742
+TEST_F(WidgetTest, DISABLED_DestroyInSysCommandNCLButtonDownOnCaption) {
   Widget widget;
   Widget::InitParams params =
       CreateParams(Widget::InitParams::TYPE_WINDOW);
diff --git a/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp
new file mode 100644
index 0000000..c401345
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp
@@ -0,0 +1,17 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+  'targets': [
+    {
+      'target_name': 'cr_shared_menu',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
+        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:position_util',
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+  ],
+}